限制从后台启动 Activity

Android 10(API 级别 29)及更高版本对应用在后台运行时启动 Activity 施加了限制。这些限制有助于最大限度地减少对用户的干扰,并让用户更好地控制屏幕上显示的内容。

本指南将通知作为从后台启动 Activity 的替代方案。它还列出了限制不适用的具体情况。

改为显示通知

几乎在所有情况下,后台应用都必须显示时效性通知,以便向用户提供紧急信息,而不是直接启动 Activity。此类通知包括处理来电或活动闹钟。

这种基于通知的提醒和提醒系统为用户提供了多项优势

  • 使用设备时,用户会看到一个浮动通知,允许他们做出响应。用户会保留当前上下文,并可以控制屏幕上显示的内容。
  • 时效性通知会遵循用户的“勿扰”规则。例如,当“勿扰”模式启用时,用户可能只允许来自特定联系人或重复来电者的呼叫。
  • 当设备屏幕关闭时,全屏 Intent 会立即启动。
  • 在设备的“设置”屏幕中,用户可以查看最近发送通知的应用,包括来自特定通知渠道的应用。在此屏幕中,用户可以控制其通知偏好设置。

应用何时可以启动 Activity

在 Android 10 或更高版本上运行的应用在满足以下一个或多个条件时可以启动 Activity

  • 应用具有可见窗口,例如在前台的 Activity。
  • 应用在前台任务的返回栈中有一个 Activity。
  • 应用在最近任务屏幕上现有任务的返回栈中有一个 Activity。

  • 应用有一个最近启动的 Activity。

  • 应用最近在某个 Activity 上调用了 finish()。这仅适用于应用在调用 finish() 时,在前台或前台任务的返回栈中有一个 Activity 的情况。

  • 应用具有系统绑定的以下服务之一。这些服务可能需要启动 UI。

  • 应用有一个由另一个可见应用绑定的服务。绑定到该服务的应用必须保持可见,以便后台应用成功启动 Activity。

  • 应用从系统接收通知 PendingIntent。对于服务和广播接收器的 PendingIntent,应用可以在 PendingIntent 发送后的几秒钟内启动 Activity。

  • 应用接收到由另一个可见应用发送的 PendingIntent

  • 应用接收到系统广播,应用应在此广播中启动 UI。例如,ACTION_NEW_OUTGOING_CALLSECRET_CODE_ACTION。应用可以在广播发送后的几秒钟内启动 Activity。

  • 应用通过 CompanionDeviceManager API 与配套硬件设备关联。此 API 允许应用响应用户在配对设备上执行的操作来启动 Activity。

  • 应用是运行在设备所有者模式下的设备政策控制器。示例用例包括完全托管的企业设备,以及数字标牌和自助服务终端等专用设备

  • 用户授予了应用 SYSTEM_ALERT_WINDOW 权限。

从 PendingIntent 启动 Activity 时需要选择启用

为避免基于列出的条件意外启动 Activity,从 Android 14 开始,提供了明确的 API,允许您选择启用或禁用授予应用启动 Activity 的权限。

以 Android 15 或更高版本为目标的应用将默认不再隐式授予其创建的 PendingIntent 后台 Activity 启动 (BAL) 权限。因此,需要明确选择启用;以下是根据应用是发送还是创建 PendingIntent 而定的选项。

Pending intents table
图 1:后台 Activity 启动决策流程图。

由 PendingIntent 的发送方决定

以 Android 14 或更高版本为目标并希望启动 PendingIntent 的应用必须

  • 满足列出的条件并且
  • 选择启用以允许根据这些例外情况启动后台 Activity

只有在应用开发者知道应用将要启动 Activity 时,才应执行此选择启用操作。

要选择启用,应用应将包含 setPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)ActivityOptions 软件包传递给 PendingIntent.send() 或类似方法。

由 PendingIntent 的创建者决定

以 Android 15 或更高版本为目标并创建 PendingIntent 的应用,如果希望这些 PendingIntent列出的条件下可启动,则现在必须明确选择启用以允许后台 Activity 启动。

在大多数情况下,启动 PendingIntent 的应用应进行选择启用。但是,如果创建应用需要授予这些权限

  • 只要创建应用可见,PendingIntent 即可随时启动。
  • 如果创建应用具有特殊权限,则 PendingIntent 可随时启动。

要选择启用,应用应将包含 setPendingIntentCreatorBackgroundActivityStartMode (ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)ActivityOptions 软件包传递给 PendingIntent.getActivity() 或类似方法。

阅读相关参考文档了解更多详情

严格模式

从 Android 16 开始,应用开发者可以启用严格模式,以便在 Activity 启动被阻止(或在应用的目标 SDK 提高时有被阻止的风险)时收到通知。

在您的 Application、Activity 或其他应用组件的 Application.onCreate() 方法早期启用的示例代码

 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     StrictMode.setVmPolicy(
         StrictMode.VmPolicy.Builder()
         .detectBlockedBackgroundActivityLaunch()
         .penaltyLog()
         .build());
     )
 }

阅读严格模式文档了解更多详情。