APP开发实战167-开机自启动的功能设计

来源:互联网 发布:苹果电脑ai软件 编辑:程序博客网 时间:2024/06/05 08:52

30.15 开机自启动的功能设计

30.15.1 普通模式

对于Android7.0之前的系统,如果设计APP在系统启动之后自启动,只需在APP添加处理ACTION_BOOT_COMPLETED广播消息的代码即可。

30.15.2直接启动模式

从Android7.0开始,系统有了一种新的启动模式“直接启动”模式,针对这种模式需要做特别处理。

    当设备已开机但用户尚未解锁设备时,Android N 将在安全的“直接启动”模式下运行。 为支持此操作,系统为数据提供两个存储位置:

    凭据加密存储,这是默认存储位置,仅在用户解锁设备后可用。

    设备加密存储,该存储位置在“直接启动”模式下和用户解锁设备后均可使用。

    默认情况下,应用不会在“直接启动”模式下运行。如果应用需要在“直接启动”模式下进行操作,可以注册在此模式期间应运行的应用组件。 对于需要在“直接启动”模式下运行的应用,常见的一些用例包括:

    已安排通知的应用,如闹钟应用。

    提供重要用户通知的应用,如短信应用。

    提供无障碍服务的应用,如 Talkback。

    如果应用在“直接启动”模式下运行时需要访问数据,则使用设备加密存储。 设备加密存储包含使用密钥加密的数据,仅在设备已成功执行验证启动后密钥才可用。

   对于应使用与用户凭据(如 PIN 或密码)关联的密钥加密的数据,请使用凭据加密存储。凭据加密存储仅在用户已成功解锁设备后可用,直到用户再次重启设备。 如果用户在解锁设备后启用锁定屏幕,则不会锁定凭据加密存储。

30.15.3 请求在直接启动时运行

    应用必须先向系统注册其组件,然后才能在“直接启动”模式下运行或访问设备加密存储。应用通过将组件标记为“加密感知”来注册系统。 若要将组件标记为加密感知,需在清单中将 android:directBootAware 属性设为 true。

    当设备重启后,加密感知组件可以注册接收来自系统的 LOCKED_BOOT_COMPLETED 广播消息。 此时设备加密存储可用,APP组件可以在“直接启动”模式下执行需要运行的任务,例如触发已设定的闹铃。

    以下代码段展示如何将 BroadcastReceiver 注册为加密感知并在应用清单中为 LOCKED_BOOT_COMPLETED 添加 Intent 过滤器:

<receiver
  android:directBootAware="true" >
  ...
  <intent-filter>
    <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/>
  </intent-filter>
</receiver>

在用户解锁设备后,所有组件均可访问设备加密存储以及凭据加密存储。

30.15.4 访问设备加密存储

    要访问设备加密存储,需通过调用 Context.createDeviceProtectedStorageContext() 创建另一个 Context 实例。使用此上下文执行的所有存储 API 调用均访问设备加密存储。 以下示例访问设备加密存储并打开现有应用数据文件:

Context directBootContext = appContext.createDeviceProtectedStorageContext();
// Access appDataFilename that lives in device encrypted storage
FileInputStream inStream = directBootContext.openFileInput(appDataFilename);
// Use inStream to read content...

    仅针对在“直接启动”模式下必须可访问的信息使用设备加密存储。请勿将设备加密存储用作通用加密存储。对于专有用户信息,或在“直接启动”模式下不需要的加密数据,请使用凭据加密存储。

30.15.5 接收用户解锁通知

    重启后一旦用户解锁了设备,应用即可切换至访问凭据加密存储,并使用依赖用户凭据的常规系统服务。

    为了在重启后用户解锁设备时收到通知,请从一个正在运行的组件注册 BroadcastReceiver 以侦听 ACTION_USER_UNLOCKED 消息。 或者,可以接收现有 ACTION_BOOT_COMPLETED 消息,该消息现在表明设备已启动,且用户已解锁设备。

    可以通过调用 UserManager.isUserUnlocked() 直接查询用户是否已解锁设备。

30.15.6 示例代码

    在AndroidManifest.xml文件中注册广播接收器:

<receiver android:name=".BootBroadcastReceiver"
    android:directBootAware="true">
    <!-- Listening the BOOT_COMPLETEDaction for legacy pre-N devices -->
    <intent-filter>
        <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

广播接收器代码:

public class BootBroadcastReceiverextends BroadcastReceiver {

    private static final String TAG= "BootBroadcastReceiver";

    @Override
   
public void onReceive(Contextcontext, Intent intent) {
        boolean bootCompleted;
        String action =intent.getAction();
        Log.i(TAG,"Receivedaction: " + action + ", user unlocked: " + UserManagerCompat
                .isUserUnlocked(context));
        if (BuildCompat.isAtLeastN()){
            bootCompleted= Intent.ACTION_LOCKED_BOOT_COMPLETED.equals(action);
        } else {
            bootCompleted= Intent.ACTION_BOOT_COMPLETED.equals(action);
        }
    }
}

0 0
原创粉丝点击