添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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

  • 已安排通知的应用,如闹钟应用。
  • 提供重要用户通知的应用,如短信应用。
  • 提供无障碍服务的应用,如 Talkback。
  • 如果应用在“直接启动”模式下运行时需要访问数据,请使用设备加密存储空间。设备加密存储空间包含使用密钥加密的数据,该密钥只有在设备成功执行启动时验证后才可用。

    对于必须使用与用户凭据(如 PIN 码或密码)关联的密钥加密的数据,请使用凭据加密存储空间。凭据加密存储空间在用户成功解锁设备后才可用,直到用户再次重启设备。如果用户在解锁设备后启用锁定屏幕,凭据加密存储空间依然可用。

    请求在“直接启动”模式下运行

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

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

    以下代码段示例说明了如何在应用清单中将 BroadcastReceiver 注册为加密感知并为 ACTION_LOCKED_BOOT_COMPLETED 添加 intent 过滤器:

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

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

    访问设备加密存储空间

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

    Kotlin

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

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

    接收用户解锁通知

    当用户在重启后解锁设备时,应用可以切换至访问凭据加密存储空间,并使用依赖用户凭据的常规系统服务。

    为了在重启后用户解锁设备时收到通知,请从正在运行的组件注册 BroadcastReceiver 以监听解锁通知消息。在用户重启后解锁设备时:

  • 如果应用具有需要立即获得通知的前台进程,请监听 ACTION_USER_UNLOCKED 消息。
  • 如果应用仅使用可以对延迟通知执行操作的后台进程,请监听 ACTION_BOOT_COMPLETED 消息。
  • 您可以通过调用 UserManager.isUserUnlocked() 直接查询用户是否已解锁设备。

    迁移现有数据

    如果用户将其设备更新为使用“直接启动”模式,您可能需要将现有数据迁移到设备加密存储空间。使用 Context.moveSharedPreferencesFrom() Context.moveDatabaseFrom() (将目标上下文作为方法调用方,将来源上下文作为参数),可以在凭据加密存储空间与设备加密存储空间之间迁移偏好设置和数据库数据。

    请勿将私密用户信息(如密码或授权令牌)从凭据加密存储空间迁移到设备加密存储空间。请自行判断要从凭据加密存储空间向设备加密存储空间迁移哪些数据。在某些情况下,您可能需要在这两种加密存储空间中管理单独的数据集。

    测试加密感知应用

    在启用“直接启动”模式的情况下测试您的加密感知应用。

    如果设置了锁屏凭据(PIN 码、图案或密码),大多数搭载最新版 Android 的设备都会启用“直接启动”模式。具体而言,所有使用文件级加密的设备都会如此。如需检查设备是否使用了文件级加密,请运行以下 shell 命令:

    adb shell getprop ro.crypto.type

    如果输出为 file ,则表示设备启用了文件级加密。

    对于默认不使用文件级加密的设备,可能有其他用于测试“直接启动”模式的选项:

    某些使用完整磁盘加密 ( ro.crypto.type=block ) 且搭载 Android 7.0 到 Android 12 的设备可以转换为文件级加密。您可以采用下列两种方法:

    警告: 无论采用哪种方法转换为文件级加密,都会擦除设备上的所有用户数据。

  • 在设备上,如果您尚未启用 开发者选项 ,请依次选择 设置 > 关于手机 ,然后点按 build 号 七次,将其启用。然后,依次前往 设置 > 开发者选项 ,并选择 转换为文件级加密
  • 或者,运行以下 shell 命令: adb reboot-bootloader fastboot --wipe-and-use-fbe

    搭载 Android 13 或更低版本的设备支持“直接启动”模拟模式,该模式使用文件权限来模拟加密文件被锁定和解锁时的加密效果。仅在开发期间使用模拟模式,因为可能会导致数据丢失。如需启用“直接启动”模拟模式,请在设备上设置锁定模式,如果在设置锁定模式时系统提示使用安全启动屏幕,请选择“不用了”,然后运行以下 shell 命令:

    adb shell sm set-emulate-fbe true

    如需关闭“直接启动”模拟模式,请运行以下 shell 命令:

    adb shell sm set-emulate-fbe false

    运行其中任一命令都会导致设备重启。

    检查设备政策加密状态

    设备管理应用可以使用 DevicePolicyManager.getStorageEncryptionStatus() 检查设备目前的加密状态。

    如果您的应用以低于 Android 7.0 (API 24) 的 API 级别为目标平台,则当设备使用完整磁盘加密或带“直接启动”的文件级加密时, getStorageEncryptionStatus() 会返回 ENCRYPTION_STATUS_ACTIVE 。在这两种情况下,数据始终以闲时加密形式存储。

    如果您的应用以 Android 7.0 (API 24) 或更高版本为目标平台,则当设备使用完整磁盘加密时, getStorageEncryptionStatus() 会返回 ENCRYPTION_STATUS_ACTIVE 。如果设备使用带“直接启动”的文件级加密,则其返回 ENCRYPTION_STATUS_ACTIVE_PER_USER

    如果面向 Android 7.0 构建设备管理应用,请务必同时检查 ENCRYPTION_STATUS_ACTIVE ENCRYPTION_STATUS_ACTIVE_PER_USER 以确定设备是否已加密。

    更多代码示例

    DirectBoot 示例进一步演示了如何使用本页介绍的 API。

    [[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2023-12-14。"],[],[],null,["# Support Direct Boot mode\n\nAndroid 7.0 runs in a secure, *Direct Boot* mode\nwhen the device has been powered on but the user hasn't unlocked the\ndevice. To support this, the system provides two storage locations for data:\n\n- **Credential encrypted storage**, which is the default storage location and only available after the user has unlocked the device.\n- **Device encrypted storage**, which is a storage location available both during Direct Boot mode and after the user has unlocked the device.\n\nBy default, apps don't run during Direct Boot mode.\nIf your app needs to take action during Direct Boot mode, you can register\napp components to be run during this mode. Some common use cases\nfor apps needing to run during Direct Boot mode include:\n\n- Apps that have scheduled notifications, such as alarm clock apps.\n- Apps that provide important user notifications, like SMS apps.\n- Apps that provide accessibility services, like Talkback.\n\nIf your app needs to access data while running in Direct Boot mode, use\ndevice encrypted storage. Device encrypted storage contains data\nencrypted with a key that is only available after a device has performed a\nsuccessful verified boot.\n\nFor data that must be encrypted with a key associated with user\ncredentials, such as a PIN or password, use credential encrypted storage.\nCredential encrypted storage is available after the user has successfully\nunlocked the device and until the user restarts the device. If the\nuser enables the lock screen after unlocking the device,\ncredential encrypted storage remains available.\n\nRequest access to run during Direct Boot\n----------------------------------------\n\nApps must register their components with the system before they\ncan run during Direct Boot mode or access device encrypted\nstorage. Apps register with the system by marking components as\n*encryption aware* . To mark your component as encryption aware, set the\n`android:directBootAware` attribute to true in your manifest.\n\nEncryption aware components can register to receive an\n[ACTION_LOCKED_BOOT_COMPLETED](/reference/android/content/Intent#ACTION_LOCKED_BOOT_COMPLETED) broadcast message from the\nsystem when the device has been restarted. At this point device encrypted\nstorage is available, and your component can execute tasks that need to be\nrun during Direct Boot mode, such as triggering a scheduled alarm.\n\nThe following code snippet is an example of how to register a\n[BroadcastReceiver](/reference/android/content/BroadcastReceiver) as encryption aware, and add an\nintent filter for `ACTION_LOCKED_BOOT_COMPLETED`, in the app manifest: \n\n```xml\n\u003creceiver\n android:directBootAware=\"true\" \u003e\n ...\n \u003cintent-filter\u003e\n \u003caction android:name=\"android.intent.action.LOCKED_BOOT_COMPLETED\" /\u003e\n \u003c/intent-filter\u003e\n\u003c/receiver\u003e\n```\n\nOnce the user has unlocked the device, all components can access both the\ndevice encrypted storage as well as credential encrypted storage.\n\nAccess device encrypted storage\n-------------------------------\n\nTo access device encrypted storage, create a second\n[Context](/reference/android/content/Context) instance by calling\n[Context.createDeviceProtectedStorageContext()](/reference/android/content/Context#createDeviceProtectedStorageContext()). All storage API\ncalls made using this context access the device encrypted storage. The\nfollowing example accesses the device encrypted storage and opens an existing\napp data file: \n\n### Kotlin\n\n```kotlin\nval directBootContext: Context = appContext.createDeviceProtectedStorageContext()\n// Access appDataFilename that lives in device encrypted storage\nval inStream: InputStream = directBootContext.openFileInput(appDataFilename)\n// Use inStream to read content...\n```\n\n### Java\n\n```java\nContext directBootContext = appContext.createDeviceProtectedStorageContext();\n// Access appDataFilename that lives in device encrypted storage\nFileInputStream inStream = directBootContext.openFileInput(appDataFilename);\n// Use inStream to read content...\n```\n\nUse device encrypted storage only for\ninformation that must be accessible during Direct Boot mode.\nDon't use device encrypted storage as a general-purpose encrypted store.\nFor private user information, or encrypted data that isn't needed during\nDirect Boot mode, use credential encrypted storage.\n\nGet notified of user unlock\n---------------------------\n\nWhen the user unlocks the device after restart, your app can switch to\naccessing credential encrypted storage and use regular system services that\ndepend on user credentials.\n\nTo get notified when the user unlocks the device after a reboot,\nregister a `BroadcastReceiver` from a running component\nto listen for unlock notification messages. When the user unlocks the device\nafter boot:\n\n- If your app has foreground processes that need immediate notification, listen for the [ACTION_USER_UNLOCKED](/reference/android/content/Intent#ACTION_USER_UNLOCKED) message.\n- If your app only uses background processes that can act on a delayed notification, listen for the [ACTION_BOOT_COMPLETED](/reference/android/content/Intent#ACTION_BOOT_COMPLETED) message.\n\nIf the user has unlocked the device, you can find out by calling\n[UserManager.isUserUnlocked()](/reference/android/os/UserManager#isUserUnlocked()).\n\nMigrate existing data\n---------------------\n\nIf a user updates their device to use Direct Boot mode, you might have\nexisting data that needs to get migrated to device encrypted storage. Use\n[Context.moveSharedPreferencesFrom()](/reference/android/content/Context#moveSharedPreferencesFrom(android.content.Context, java.lang.String)) and\n[Context.moveDatabaseFrom()](/reference/android/content/Context#moveDatabaseFrom(android.content.Context, java.lang.String)), with the destination context as the method caller and the source context as the argument, to migrate preference and database\ndata between credential encrypted storage and device encrypted storage.\n\nDon't migrate private user information, such as passwords or authorization tokens, from\ncredential encrypted storage to device encrypted storage. Use your best judgment when deciding what\nother data to migrate to device encrypted storage. In some scenarios, you might need to manage\nseparate sets of data in the two encrypted stores.\n\nTest your encryption aware app\n------------------------------\n\nTest your encryption aware app with Direct Boot mode enabled.\n\nMost devices running recent versions of Android enable Direct Boot mode\nwhenever a lockscreen credential (PIN, pattern, or password) has been set.\nSpecifically, this is the case on all devices that use file-based encryption.\nTo check whether a device uses file-based encryption, run the following\nshell command: \n\n```\nadb shell getprop ro.crypto.type\n```\n\nIf the output is `file`, then the device has file-based encryption\nenabled.\n\nOn devices that don't use file-based encryption by default, there might be\nother options for testing Direct Boot mode:\n\n- Some devices that use full-disk encryption\n (`ro.crypto.type=block`) and are running Android 7.0 through\n Android 12 can be converted to file-based\n encryption. There are two ways to do this:\n\n - **Warning:**Either method of converting to file-based encryption wipes all user data on the device.\n - On the device, enable **Developer options** if you haven't already by going to **Settings \\\u003e About phone** and tapping **Build\n number** seven times. Then go to **Settings \\\u003e Developer\n options** and select **Convert to file encryption**.\n - Alternatively, run the following shell commands: \n\n adb reboot-bootloader\n fastboot --wipe-and-use-fbe\n\n- Devices running Android 13 or lower support an\n \"emulated\" Direct Boot mode that uses file permissions to simulate the\n effects of encrypted files being locked and unlocked. Only use emulated mode\n during development; it can cause data loss. To enable emulated\n Direct Boot mode, set a lock pattern on the device, choose \"No thanks\" if\n prompted for a secure start-up screen when setting a lock pattern, and then\n run the following shell command:\n\n ```\n adb shell sm set-emulate-fbe true\n ```\n\n To turn off emulated Direct Boot mode, run the following shell\n command: \n\n ```\n adb shell sm set-emulate-fbe false\n ```\n\n Running either of these commands causes the device to reboot.\n\nCheck device policy encryption status\n-------------------------------------\n\nDevice administration apps can use\n[DevicePolicyManager.getStorageEncryptionStatus()](/reference/android/app/admin/DevicePolicyManager#getStorageEncryptionStatus())\nto check the current encryption status of the device.\n\nIf your app targets an API level lower than Android 7.0 (API 24),\n`getStorageEncryptionStatus()` returns\n[ENCRYPTION_STATUS_ACTIVE](/reference/android/app/admin/DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE)\nif the device is using either full-disk encryption\nor file-based encryption with Direct Boot. In both of these cases, data is\nalways stored encrypted at rest.\n\nIf your app is targets Android 7.0 (API 24) or higher,\n`getStorageEncryptionStatus()` returns\n`ENCRYPTION_STATUS_ACTIVE` if the device is using full-disk encryption. It returns\n[ENCRYPTION_STATUS_ACTIVE_PER_USER](/reference/android/app/admin/DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_PER_USER) if the device is using file-based encryption\nwith Direct Boot.\n\nIf you build a device administration app\nthat targets Android 7.0, make sure to check for both\n`ENCRYPTION_STATUS_ACTIVE` and\n`ENCRYPTION_STATUS_ACTIVE_PER_USER` to determine whether the device is\nencrypted.\n\nAdditional code samples\n-----------------------\n\nThe [DirectBoot](https://github.com/android/security-samples/tree/main/DirectBoot/)\nsample further demonstrates the use of the APIs covered on this page."]]
  •