想做个锁屏界面很久了,最近一周,历经千辛万苦,越过种种挫折,终于完美实现了这一要求,在此将锁屏思路分享出来。

注意:这不是什么一键锁屏,是类似“go锁屏”那样的锁屏界面。

准备:本程序共需要

两个activity:home、main。

一个service:myService

一个receiver:bootReceiver

一个layout:layout

其中home作为屏幕home键专用的activity,main则是主要的展示锁屏界面的activity。

service用于接收锁屏/解锁广播,layout则是main所需要展示的界面。

思路:

!注意:以下代码没有顺序联系,具体请参考源码!

1,给程序添加服务,当此服务接收到 锁屏/解锁广播 时,关闭系统锁屏界面,打开自己的锁屏界面。

关键代码:

/onReceive中:

keyguardManager = (KeyguardManager)context.getSystemService(context.KEYGUARD_SERVICE);
keyguardLock = keyguardManager.newKeyguardLock("");
keyguardLock.disableKeyguard();//解锁系统锁屏
startActivity(toMainIntent);//跳转到主界面

注意,上面的代码需要注册权限:

<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />

另外,为了防止主界面被重复调用,我们在设置intent时还要加上一些filter:

//设置myservice中intent的filter
toMainIntent = new Intent(myService.this, Main.class);
toMainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//这个flags表示如果已经有这个activity,则将已有的提到栈顶,否则新建一个activity。
//在manifest中讲主界面的启动模式更改为:singleTask,功能和上面的“Intent.FLAG_ACTIVITY_NEW_TASK”类似
<activity
android:name="com.example.screenlocker.Main"
android:label="@string/app_name"
android:launchMode="singleTask" >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>

当然,我们还可以在onDestroy中设置服务重启,以保证此服务一直在后台运行

@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(screenReceiver);
//重启此服务
startActivity(new Intent(myService.this,myService.class));
}

将一些其他的事项,如注册服务、在主界面中启动服务等设置完成后,我们可以run一遍了~

如果没出错,那么解锁后首先打开的将是我们的锁屏界面。

2,实现了锁屏,但是还有一个问题,当按返回键或者home键的时候,我们的界面就轻易被KO了。别担心,咱们一一屏蔽他们。

首先,拿返回键开刀:只需要在主界面中添加如下代码即可:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
  switch (keyCode) {
  case KeyEvent.KEYCODE_BACK:
    return true;
  }
  return super.onKeyDown(keyCode, event);
}

可是,home键并不能通过此方法屏蔽或者捕捉。这对程序猿来说是个很头疼的问题,在网上也有各种解决的办法,但是笔者参考总结,决定用“GO锁屏”的方式来实现:

这种办法的思路是:把自己的程序设置为系统主屏幕!这样,本来按home键是要转到主屏幕的,设置好后,按home键则直接跳转到我们的界面里来了!

好了,让我们新建一个activity,命名为“home”,用来抢夺home键。然后在manifest中设置如下:

<activity android:name="com.example.screenlocker.Home" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

这样,当按home键的时候,如果是在main界面按的,系统不做反应。如果是在其他时候按下home键,就会跳转到这个activity中来。

(首次运行时,会让你选择按home键跳转到“主屏幕”或者“test1(咱们自己写的程序的appName)”)

也就是说,我们已经实现了锁屏界面对home的屏蔽。如果是在非锁屏状态下按home,就会调用home界面。我们只需在home界面里如此设置即可:

onCreate(){
跳转到系统主屏幕;//具体代码见下文
finish();//结束这个activity
}

所以,这个activity没有必要加载界面。故此,我们要将这个activity的theme设置为“不显示”,这样,不但避免浪费,更可以避免在跳转的时候屏幕闪一下,影响用户体验

//manifest设置home的theme为noDisplay
<activity
android:name="com.example.screenlocker.Home"
android:theme="@android:style/Theme.NoDisplay" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

我们可以在home的oncreate里打这样一行代码:

Log.e("", "home is called");finish();//调用finish以防止程序卡在一个不展示的activity

然后运行一遍试试效果,就可以清楚的发现,当我们何时按home键时,会调用这一activity。

3,home键已经抢过来了。那么接下来,我们要做的是让home界面跳转到主界面:

首先,我们要获取一个列表:列出所以可以作为主屏幕的程序:

List<String> pkgNamesT = new ArrayList<String>();
List<String> actNamesT = new ArrayList<String>();
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
  for (int i = 0; i < resolveInfos.size(); i++) {
    String string = resolveInfos.get(i).activityInfo.packageName;
    if (!string.equals(context.getPackageName())) {//排除自己的包名
      pkgNamesT.add(string);
      string = resolveInfos.get(i).activityInfo.name;
      actNamesT.add(string);
    }
  }

然后,可以用alertDialog的方式让用户选择要跳到哪个主屏幕,并用sharedPreferences记录用户的选择。

new AlertDialog.Builder(context).setTitle("请选择解锁后的屏幕").setCancelable(false).setSingleChoiceItems(names, 0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
editor.putString(packageName, pkgNames.get(which));
editor.putString(activityName, actNames.get(which));
editor.commit();
originalHome();
dialog.dismiss();
}
}).show();

这样,下次的时候就可以根据包名和类名,直接跳转到用户所设置的主屏幕了:

String pkgName = sharedPreferences.getString(packageName, null);
String actName = sharedPreferences.getString(activityName, null);
ComponentName componentName = new ComponentName(pkgName, actName);
Intent intent = new Intent();
intent.setComponent(componentName);
context.startActivity(intent);
((Activity) context).finish();

4,当然,最后,我们也希望可以将其设置为开机启动:

public class BootReceiver extends BroadcastReceiver{
String myPkgName = "com.example.screenlocker";//#包名
String myActName = "com.example.acts.myService";//#类名 @Override
public void onReceive(Context context, Intent intent) {
//启动监听服务
Intent myIntent=new Intent();
myIntent.setAction(myPkgName+"."+myActName);
context.startService(myIntent);
}
}

注意:别忘了在manifest中添加开机启动的权限哦:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

不过我更推荐在home中加这么一行代码:

startService(new Intent(Home.this, ScreenReceiver.class));

这样,每次打开主屏幕都能打开这个后台服务,哈哈哈……

下载源码

附言

笔者在查资料时,发现极难找到此类资料。要么晦涩难懂,要么资料不全。深深的体会到了四处碰壁的绝望,故此才有了此文。

本文将锁屏实现思路及源码分享出来,稍加修改即可使用,希望能帮到有同样需求的人。希望有收获的人能花半秒钟推荐一下,方便其余coder查阅。

android开发 锁屏 真正的锁屏,是go锁屏那种。的更多相关文章

  1. 【转】Android开发笔记(序)写在前面的目录

    原文:http://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经 ...

  2. android开发技巧——仿新版QQ锁屏下弹窗

    新版的qq,可以在锁屏下弹窗显示qq消息,正好目前在做的项目也需要这一功能.经过各种试验和资料查找,终于实现,过程不难,但是却有一些地方需要注意. 下面是实现过程. 1.使用Activity,而不是V ...

  3. Android开发中如何强制横屏和强制竖屏设置

    Android开发中如何强制横屏和强制竖屏设置 强制横屏设置: 按照下面代码示例修改Activity的onResume方法 @Override protected void onResume() { ...

  4. android开发:全屏和退出全屏

    android开发:全屏和退出全屏 from://http://blog.csdn.net/dyllove98/article/details/8831933 2013-04-21 20:31 413 ...

  5. Android开发 - 解决DialogFragment在全屏时View被状态栏遮住的问题

    我的上一篇文章:设置DialogFragment全屏显示 可以设置对话框的内容全屏显示,但是存在在某些机型上顶部的View被状态栏遮住的问题.经过测试,发现了一种解决办法,在DialogFragmen ...

  6. Android中使用Handler以及CountDownTimer实现包含倒计时的闪屏页面

    上一篇博文<Android中Handler使用浅析>通过实现倒计时闪屏页面的制作引出了Handler的使用方法以及实现原理,博文末尾也提到了实现过程中的Bug,有兴趣的朋友可以点击链接回去 ...

  7. Android中使用Handler以及CountDownTimer实现包括倒计时的闪屏页面

    上一篇博文<Android中Handler使用浅析>通过实现倒计时闪屏页面的制作引出了Handler的用法以及实现原理,博文末尾也提到了实现过程中的Bug,有兴趣的朋友能够点击链接回去看看 ...

  8. Android版本的"Wannacry"文件加密病毒样本分析(附带锁机)

    一.前言 之前一个Wannacry病毒样本在PC端肆意了很久,就是RSA加密文件,勒索钱财.不给钱就删除.但是现在移动设备如此之多,就有一些不法分子想把这个病毒扩散到移动设备了,这几天一个哥们给了一个 ...

  9. android指纹识别、拼图游戏、仿MIUI长截屏、bilibili最美创意等源码

    Android精选源码 一个动画效果的播放控件,播放,暂停,停止之间的动画 用 RxJava 实现 Android 指纹识别代码 Android仿滴滴打车(滴滴UI)源码 Android高仿哔哩哔哩动 ...

随机推荐

  1. [iOS基础控件 - 5.4] 广告分页代码(UIScrollView制作)

    A.概念 例子就是桌面的APP列表,当APP数量超过一个屏幕,自动进行分页   B.实现思路 1.创建一个UIScrollView,这里设置为宽度跟屏幕相同,高度1/4屏幕高度左右 2.使用代码在UI ...

  2. ALM11测试计划页面图解1

    在 ALM 侧栏上的测试下方,选择测试计划. 在查看菜单中,选择测试网格或测试计划树. 在 ALM 侧栏上的测试下方,选择测试计划. 右键单击测试,并选择测试详细信息. 在测试计划树中选择主题文件夹, ...

  3. PTA 5-15 PAT Judge (25分)

    /* * 1.主要就用了个sort对结构体的三级排序 */ #include "iostream" #include "algorithm" using nam ...

  4. CMD-NET命令详解(转载)

    本文转自http://www.cnblogs.com/chenjq0717/archive/2010/05/09/1730934.html net命令大全,net命令用法,net网络命令,net命令使 ...

  5. uploadPreview 兼容多浏览器图片上传及预览插件使用

    uploadPreview兼容多浏览器图片上传及预览插件 http://www.jq22.com/jquery-info2757 Html 代码 <div class="form-gr ...

  6. Web- 一些标签样式

    网上找来的.有点用 1.只有下划线的文本框:<input style="border:0;border-bottom:1 solid black;background:;"& ...

  7. JavaScript 要点(十四)HTML DOM 元素(节点)

    A.创建新的 HTML 元素 如需向 HTML DOM 添加新元素,必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素. <div id="div1"> ...

  8. android studio简易了解第一部分

    1.如果还没下载 jdk,先把jdk下载,然后下载android studio 安装 百度 android studio ,百度软件中心可以下载. Android官网可以下载:     网址: htt ...

  9. 对PostgreSQL xmax的理解

    xmax The identity (transaction ID) of the deleting transaction, or zero for an undeleted row version ...

  10. PostgreSQL的 create index concurrently

    对于PostgreSQL的 "create index concurrently". 我个人认为其中存在一个bug. 我的验证过程如下: 我有两个表,tab01和 tab02,这两 ...