Android 7.0 —– Direct Boot模式(AppClock)
本文针对闹钟应用对于此次Android 7.0增加DB模式所需要的应对方式。
Direct Boot模式:设备已开机但用户尚未解锁设备时,Android 7.0 将在安全的“直接启动”模式下运行。
简单来说,如果不做处理,在手机开机锁屏的情况下(DB模式),设置的闹钟是无法使用的。
开发者网站请参考:支持“直接启动”模式 | Android 开发者 | Android Developers
应对方式:
1.请求在DB模式下运行
默认情况下,应用不会在“直接启动”模式下运行。如果应用需要在DB模式下执行操作,需要注册应在此模式下运行的应用组件。应用通过将组件标记为加密感知来向系统注册,然后才能在“直接启动”模式下运行或访问设备加密存储。
android:directBootAware="true"
当设备重启后,加密感知组件可以注册以接收来自系统的ACTION_LOCKED_BOOT_COMPLETED广播消息。此时,设备加密存储可用。
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
2.接收用户解锁通知
当用户在重启后解锁设备时,应用可以切换至访问凭据加密存储,并使用依赖用户凭据的常规系统服务。
需立即获取通知的前台进程,监听ACTION_USER_UNLOCKED消息。
<action android:name="android.intent.action.USER_UNLOCKED" />
对延迟通知执行操作的后台进程,监听ACTION_BOOT_COMPLETED消息。
<action android:name="android.intent.action.BOOT_COMPLETED" />
也可以通过调用userManager.isUserUnlocked(),直接查询用户是否已解锁设备。
AppClock遇到的问题:
1.开机的时候,闹钟到时不响被miss掉了。分析log发现是:
当用户使用手机时(flip打开,屏幕on的状态下)。一个闹铃响铃,用户在通过非代码设定的按键而离开响铃界面(像是误操作等原因),此时会把这个闹铃置位missed状态,同时关闭响铃、发送notification。
if (AlarmSubLcd.isFlipOpen(mContext) == true && mIsScreenOn == true) {
missed();
}
处理方法:将此方法所在的组件在清单中注册
android:showWhenLocked="true"
将此组件浮在锁屏界面的上方,返回即进入解锁界面。
2.在DB模式下,概率性出现闹钟到时不响(解锁后闹钟可响,过时闹钟被miss掉)
这个问题给我整emo了两天,通常概率性bug是线程的事。从log中分析出来,不知道是谁把alarmInstance的状态从fire变成了miss,导致闹钟到时不响。后来从crash log发现,在DB模式下,clock的widget crash了。DB模式下,不能调用updateWidget()方法。
处理方法:
通过调用userManager.isUserUnlocked()是否已解锁设备,解锁设备后再调用updateWidget()方法。
UserManager mUserManager = context.getSystemService(UserManager.class);
if (mUserManager.isUserUnlocked()) {
UpdateWidget();
}