从后台启动活动的限制

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

本指南介绍了通知作为从后台启动活动的替代方案。它还列出了不受限制的具体情况。

改为显示通知

在几乎所有情况下,后台应用都必须 显示时间敏感的通知 向用户提供紧急信息,而不是直接启动活动。此类通知包括处理传入的电话呼叫或活动的闹钟。

这种基于通知的警报和提醒系统为用户提供了以下几个优势

  • 使用设备时,用户会看到一个弹出通知,让他们可以做出响应。用户会保留其当前上下文,并可以控制在屏幕上看到的内容。
  • 时间敏感的通知会尊重用户的 请勿打扰 规则。例如,用户可能只允许来自特定联系人的电话呼叫,或来自重复来电者的电话呼叫,即使已启用请勿打扰模式。
  • 当设备的屏幕关闭时,全屏意图会立即启动。
  • 在设备的设置屏幕中,用户可以看到哪些应用最近发送了通知,包括来自特定通知频道的通知。用户可以从此屏幕控制其通知偏好。

当应用可以启动活动时

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

  • 应用有一个可见窗口,例如前台的活动。
  • 应用在前台任务的后退堆栈中有一个活动。
  • 应用在最近使用的应用屏幕上现有任务的后退堆栈中有一个活动。

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

  • 应用最近在活动上调用了finish()。这仅适用于应用在调用finish()时在前台有一个活动,或者在前台任务的后退堆栈中有一个活动。

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

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

  • 应用从系统接收通知PendingIntent。在服务和广播接收器挂起意图的情况下,应用可以在发送挂起意图后几秒内启动活动。

  • 应用接收来自另一个可见应用的PendingIntent

  • 应用接收系统广播,其中应用需要启动 UI。示例包括ACTION_NEW_OUTGOING_CALLSECRET_CODE_ACTION。应用可以在发送广播后几秒内启动活动。

  • 应用通过CompanionDeviceManager API 与伴侣硬件设备相关联。此 API 允许应用启动活动以响应用户在配对设备上执行的操作。

  • 应用是在设备策略控制器中运行的设备所有者模式。使用案例示例包括完全管理的企业设备以及专用设备(如数字标牌和信息亭)。

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

从挂起意图启动活动时需要选择加入

为了避免基于列出的条件允许意外启动活动,从 Android 14 开始,有一些显式 API 允许您选择加入或退出授予应用启动活动的权限。

以 Android 15 或更高版本为目标的应用将默认不再为其创建的PendingIntents隐式授予后台活动启动(BAL)权限。需要显式选择加入,为此,以下选项取决于应用是发送还是创建PendingIntents

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

由挂起意图的发送方

以 Android 14 或更高版本为目标的应用,如果要启动PendingIntent,则必须

  • 满足列出的条件以及
  • 选择加入以允许基于这些异常启动后台活动

此选择加入应在应用开发者知道应用将启动活动的情况下进行。

要选择加入,应用应将带有setPendingIntentBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)ActivityOptions包传递给PendingIntent.send()或类似方法。

由挂起意图的创建方

以 Android 15 或更高版本为目标的应用,如果要创建PendingIntent,现在必须显式选择加入以允许后台活动启动,如果他们希望这些PendingIntents可以在列出的条件下启动。

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

  • 创建的应用可见时,可以随时启动PendingIntent
  • 如果创建的应用具有特殊权限,则可以随时启动PendingIntent

要选择加入,应用应将带有setPendingIntentCreatorBackgroundActivityStartMode (ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)ActivityOptions包传递给PendingIntent.getActivity()或类似方法。

阅读相关参考文档以获取更多详细信息