Android开发-锁屏状态下显示自定义UI
看到这个标题,想到什么应用场景吗?
- 音乐播放
- 锁屏记单词,亮屏就能看到单词
- 运动跑步时,亮屏就看到运动数据
- 自定义幻灯片?把你老婆孩子的照片放上
- 其他的自行发挥吧!
权限的获取和检查
- 权限,实现这个功能,我们需要一些权限,比如说覆盖在其他应用之上的权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
权限的判断和获取
- 判断权限
boolean b = Settings.canDrawOverlays(this);
Log.d(TAG,"has permission ==> " + b);
如果是true,就表示有显示在其他应用之上的权限,false则没有
如果是false我们要跳转到对应的界面,打开此权限
startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName())));
这个设置不同的手机不一样,以下我截图为小米手机
打开以后,我们在onResume的时候去检查一下是否有这个权限,如果你必须要有就弹窗提示用户,如果你不必须有此权限,可以走过即可。
有了权限以后,我们就可以去实现这样的功能了。
什么时候去显示锁屏的UI
屏幕状态的监听
- 灭屏(只要灭屏,就认为锁屏了)
- 解锁状态(如果用户快速锁屏用人脸识别解锁,导致一些体验上的冲突。比如说,我们的锁屏UI还没启动完成,用户就解锁了,解锁以后,还显示锁屏的UI这就不符合我们预期的交互了)
我们通过监听广播,可以知道屏幕的状态
IntentFilter filter = new IntentFilter();
//灭屏幕
filter.addAction(Intent.ACTION_SCREEN_OFF);
// 实例化广播
this.mScreenReceiver = new ScreenBroadcastReceiver();
// 注册广播
registerReceiver(mScreenReceiver, filter);
在onDestroy的时候记得取消广播的注册,避免内存泄露
监听到锁屏的状态,我们就拉起我们的自定义UI
class ScreenBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_SCREEN_OFF.equals(action)) {
//锁屏了
ICLogger.d("已经锁屏...");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& Settings.canDrawOverlays(context)) {
Intent targetIntent = new Intent(context, LockActivity.class);
targetIntent.putExtra(Constant.Key.SPORT_TYPE, type);
targetIntent.putExtra(Constant.Key.SPORT_PROGRAM, program);
targetIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(targetIntent);
ICLogger.d("start up lock activity...");
}
}
}
}
LockActivity的启动模式为singleTop,如果已经在栈顶了就不要再启动了。
防止前面我们提到的情况:如果用户快速锁屏用人脸识别解锁,导致一些体验上的冲突。比如说,我们的锁屏UI还没启动完成,用户就解锁了,解锁以后,还显示锁屏的UI
在LockActivity的onCreate方法上加上锁屏的判断
如果当前已经解锁了,就直接finsish掉
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean lockMode = keyguardManager.inKeyguardRestrictedInputMode();
ICLogger.d("lockMode ==> " + lockMode);
if (!lockMode) {
finish();
}
另外,还要设置window的flag
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
到这里,就可以实现功能了。
看看效果吧:
黑屏就是锁屏,锁屏以后显示自定义界面,解锁以后进去显示的应用的界面。
即使应用退到后台也是可以拉起来的,因为我们监听的是广播嘛。
好了,今天水的第一篇文章就到这里吧。