应用休眠

如果您的应用的目标 Android 11(API 级别 30)或更高版本,并且用户几个月内 未与您的应用互动,系统会将您的应用置于休眠状态。系统会优化存储空间而不是性能,并保护用户数据。此系统行为类似于用户从系统设置手动强制停止您的应用时发生的情况。

休眠的影响

如表 1 所示,休眠的影响取决于您的应用的目标 SDK 版本以及运行您的应用的设备。

表 1. 休眠对您的应用的影响
目标 SDK 版本 设备特性 休眠影响
Android 12 或更高版本 运行 Android 12 或更高版本

您的应用的 运行时权限 将被重置。此操作的效果与用户在系统设置中查看权限并将您的应用的访问级别更改为拒绝的效果相同。

您的应用无法运行后台作业或警报。

您的应用无法接收推送通知,包括通过 Firebase Cloud Messaging 发送的高优先级消息。

您应用的 应用缓存 中的任何文件都将被删除。

Android 11 运行 Android 11 您的应用的运行时权限将被重置。
Android 11 运行 Android 6.0(API 级别 23)到 Android 10(API 级别 29)(含),并且由 Google Play 服务 提供支持

您的应用的运行时权限将被重置。

此行为将于 2021 年 12 月生效。请在以下博文中了解更多信息:让权限自动重置功能惠及数十亿更多设备

应用退出休眠时的系统行为

当用户下次与您的应用互动时,您的应用将退出休眠状态,并且可以再次创建作业、警报和通知。

但是,系统不会为您的应用执行以下操作:

  1. 重新授予您的应用的运行时权限。

    用户必须为您的应用重新授予这些权限。

  2. 重新安排在您的应用进入休眠状态之前安排的任何作业、警报和通知。

    为了更轻松地支持此工作流程,请使用WorkManager。您也可以在ACTION_BOOT_COMPLETED广播接收器中添加重新调度逻辑,该接收器在您的应用退出休眠状态以及设备启动后被调用。

应用使用情况

以下部分提供应用使用示例,以及系统不认为是应用使用情况的操作示例。

应用使用示例

当您应用中的活动恢复时,系统会将此事件视为用户交互。因此,系统会延长您的应用进入休眠状态之前的时间。

在 Android 11 及更高版本中,以下行为也被视为用户交互

  • 用户与小部件进行交互。
  • 用户与通知进行交互,但取消通知除外。

需要注意的是,休眠的应用使用情况并不明确要求用户交互。只要调用了包的组件,它仍然被认为是应用使用情况。一些示例包括

  • 设备或操作系统上的其他应用绑定了服务的应用或内容提供商。例如,输入法编辑器 (IME) 或密码管理器。
  • 包中的广播接收器接收来自外部包的显式广播。

非示例

如果您的应用仅表现出以下列表中描述的行为,则您的应用会在几个月后进入休眠状态

系统休眠豁免

Android 在某些情况下会授予系统级应用休眠豁免。如果您的应用属于以下类别之一,则它将免于应用使用标准,并且不会休眠。

启动器上未显示的应用
启动器上没有活动快捷方式图块的任何应用。
工作配置文件应用
用户在工作配置文件上安装的任何应用。请注意,如果同一应用也驻留在个人资料中,则只有工作配置文件应用才豁免。
设备策略控制器
控制本地设备策略和设备上系统应用的应用。
运营商特权应用
移动电话运营商预装在设备上并认为对合同服务义务(例如语音邮件或客户服务应用)必要的任何应用。
第三方安装程序应用
第三方应用商店,用于在必要时自动更新其已安装的应用。

用户休眠豁免

如果您预计应用中的核心用例会受到休眠的影响,您可以向用户申请应用休眠豁免。此豁免对于用户期望您的应用主要在后台运行的情况非常有用,即使用户没有与您的应用交互,例如当您的应用执行以下任何操作时:

  • 定期报告家庭成员的位置,以提供家庭安全。
  • 在设备和您的应用服务器之间同步数据。
  • 与智能设备(如电视)通信。
  • 与配套设备(如手表)配对。

要申请豁免,请完成以下部分中的步骤。

检查用户是否已为您的应用禁用休眠

要检查用户是否已为您的应用禁用休眠,请使用getUnusedAppRestrictionsStatus() API。

有关如何在您的应用中使用此 API 的更多详细信息,请参阅此页面上的API 代码示例

请求用户为您的应用禁用休眠

如果用户尚未为您的应用禁用休眠,您可以向用户发送请求。为此,请完成以下步骤

  1. 显示一个 UI,向用户解释为什么他们需要为您的应用禁用休眠。
  2. 调用createManageUnusedAppRestrictionsIntent() API,如API 代码示例所示。此 API 会创建一个意图,在设置中加载**应用信息**屏幕。在这里,用户可以关闭您的应用的休眠功能。

    发送此意图时,务必调用startActivityForResult(),而不是startActivity()

    如表 2 所示,选项的位置和名称取决于安装您的应用的设备的特性

    表 2.禁用您应用休眠功能的选项
    设备特性 选项显示的页面 要关闭的选项的名称
    运行 Android 13 或更高版本 应用信息 如果未使用则暂停应用活动
    运行 Android 12 应用信息 删除权限并释放空间
    运行 Android 11 应用信息 > 权限 如果应用未使用则删除权限
    运行 Android 6.0 到 Android 10(含),并且由 Google Play 服务提供支持 Play 应用 > 菜单 > Play 保护 > 未使用应用的权限 如果应用未使用则删除权限

API 代码示例

此代码示例显示如何检查您的应用是否启用了休眠功能,以及正确请求用户禁用您的应用休眠功能的方法。

Kotlin

val future: ListenableFuture<Int> =
    PackageManagerCompat.getUnusedAppRestrictionsStatus(context)
future.addListener({ onResult(future.get()) }, ContextCompat.getMainExecutor(context))

fun onResult(appRestrictionsStatus: Int) {
  when (appRestrictionsStatus) {
    // Couldn't fetch status. Check logs for details.
    ERROR -> { }

    // Restrictions don't apply to your app on this device.
    FEATURE_NOT_AVAILABLE -> { }

    // The user has disabled restrictions for your app.
    DISABLED -> { }

    // If the user doesn't start your app for a few months, the system will
    // place restrictions on it. See the API_* constants for details.
    API_30_BACKPORT, API_30, API_31 -> handleRestrictions(appRestrictionsStatus)
  }
}

fun handleRestrictions(appRestrictionsStatus: Int) {
  // If your app works primarily in the background, you can ask the user
  // to disable these restrictions. Check if you have already asked the
  // user to disable these restrictions. If not, you can show a message to
  // the user explaining why permission auto-reset or app hibernation should be
  // disabled. Then, redirect the user to the page in system settings where they
  // can disable the feature.
  val intent = IntentCompat.createManageUnusedAppRestrictionsIntent(context, packageName)

  // You must use startActivityForResult(), not startActivity(), even if
  // you don't use the result code returned in onActivityResult().
  startActivityForResult(intent, REQUEST_CODE)
}

旧版平台 API

操作系统还包含一个与休眠功能交互的 API。但是,此 API 仅适用于运行 Android 11 或更高版本的设备;此 API 不处理向早期 Android 版本移植的休眠功能。因此,我们不建议使用此 API。

如果您需要暂时出于兼容性目的继续使用此 API,则以下列表显示了如何使用它

手动调用休眠行为

要测试您的应用在系统将其置于休眠状态后的行为,请完成以下步骤

  1. (仅限 Android 12 及更高版本)在您的设备上启用休眠行为

    adb shell device_config put app_hibernation app_hibernation_enabled true
    
  2. 设置系统等待进入休眠状态的默认时间。这样,您可以在测试后恢复它

    threshold=$(adb shell device_config get permissions \
      auto_revoke_unused_threshold_millis2)
    
  3. 减少系统等待的时间。在以下示例中,系统经过修改,以便您的应用在您停止与应用交互后仅一秒钟就进入休眠状态

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  4. 通过运行以下命令等待测试设备上的任何启动时广播完成

    adb shell am wait-for-broadcast-idle
    

    广播完成后,此命令会返回消息:All broadcast queues are idle!

  5. 手动调用应用休眠进程

    adb shell cmd jobscheduler run -u 0 -f \
      com.google.android.permissioncontroller 2
    
  6. (仅限 Android 12 及更高版本)使用以下方法之一确认应用已休眠。

    • 观察测试设备现在显示通知,指示未使用应用已休眠。
    • 运行以下命令

      adb shell cmd app_hibernation get-state PACKAGE-NAME
      
  7. 恢复系统在将您的应用置于休眠状态之前等待的默认时间

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold