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

注意:这不是什么一键锁屏,是类似“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. MYSQL- 创建和删除临时表

    临时表可能是非常有用的,在某些情况下,保持临时数据.最重要的是应该知道的临时表是,他们将当前的客户(www.111cn.net)端会话终止时被删除 当你创建临时表的时候,你可以使用temporary关 ...

  2. 如何关闭log4j中配置的spring或者hibernate的日志信息

    通常在建立一个web项目的时候,我们通常需要为其配置日志,以便了解启动过程中发生了什么,如果启动过程中发生了错误,则可以很方便的查看错误的信息,但是在项目部署到服务器上时,打印日志信息,需要耗费大量的 ...

  3. HTML中标签和元素的区别

    作为一个前端,相信大家最先接触应该都是HTML吧?在HTML中很多人可能都没有把什么叫标签,什么叫元素这个概念搞清楚,为了把这个大家不曾留意的易混淆的搞清楚,特作此一文彻底解决掉这个问题! 首先我们来 ...

  4. iOS Instruments内存检测使用

    Instruments 可以帮我们了解到应用程序使用内存的几个方面: 全局内存使用情况(Overall Memory Use): 从全局的角度监测应用程序的内存使用情况,捕捉非预期的或大幅度的内存增长 ...

  5. cocos2d-x 纹理深入研究

    转自:http://blog.csdn.net/qq51931373/article/details/9152227 1.纹理控制. 看此代码: CCSprite *pSprite = CCSprit ...

  6. 【转载】Android Studio 设置内存大小及原理

    http://www.cnblogs.com/justinzhang/p/4274985.html http://tsroad.lofter.com/post/376316_69363ae Andro ...

  7. Java获取时间与系统时间相差8小时终极解决方案

    一.在取日期以前设置一下时区 TimeZone tz = TimeZone.getTimeZone(“ETC/GMT-8″);TimeZone.setDefault(tz); 此种方法适用于单次快速获 ...

  8. HubbleDotNet 学习之路

    1.创建后台任务实现自动同步更新表数据.打开工具后点击“management”选项卡,选择“task scheduler management”,在弹出的窗口中点击右侧的"add" ...

  9. 【PAT Advanced Level】1006. Sign In and Sign Out (25)

    关键在于清空字符数组和使用scanf进行输入 #include <stdio.h> #include <string.h> #include <fstream> # ...

  10. Upcase 将edit1中的每个字符串改为首字母大写

    //将edit1中的每个字符串改为首字母大写 procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);begin    with ...