Android 10(API 级别 29)及更高版本对应用在后台运行时启动 Activity 施加了限制。这些限制有助于最大限度地减少对用户的干扰,并让用户更好地控制屏幕上显示的内容。
本指南将通知作为从后台启动 Activity 的替代方案。它还列出了限制不适用的具体情况。
改为显示通知
几乎在所有情况下,后台应用都必须显示时效性通知,以便向用户提供紧急信息,而不是直接启动 Activity。此类通知包括处理来电或活动闹钟。
这种基于通知的提醒和提醒系统为用户提供了多项优势
- 使用设备时,用户会看到一个浮动通知,允许他们做出响应。用户会保留当前上下文,并可以控制屏幕上显示的内容。
- 时效性通知会遵循用户的“勿扰”规则。例如,当“勿扰”模式启用时,用户可能只允许来自特定联系人或重复来电者的呼叫。
- 当设备屏幕关闭时,全屏 Intent 会立即启动。
- 在设备的“设置”屏幕中,用户可以查看最近发送通知的应用,包括来自特定通知渠道的应用。在此屏幕中,用户可以控制其通知偏好设置。
应用何时可以启动 Activity
在 Android 10 或更高版本上运行的应用在满足以下一个或多个条件时可以启动 Activity
- 应用具有可见窗口,例如在前台的 Activity。
- 应用在前台任务的返回栈中有一个 Activity。
应用在最近任务屏幕上现有任务的返回栈中有一个 Activity。
应用有一个最近启动的 Activity。
应用最近在某个 Activity 上调用了
finish()
。这仅适用于应用在调用finish()
时,在前台或前台任务的返回栈中有一个 Activity 的情况。应用具有系统绑定的以下服务之一。这些服务可能需要启动 UI。
AccessibilityService
AutofillService
CallRedirectionService
HostApduService
InCallService
TileService
(不适用于 Android 14 (API 级别 34) 及更高版本)VoiceInteractionService
VrListenerService
.
应用有一个由另一个可见应用绑定的服务。绑定到该服务的应用必须保持可见,以便后台应用成功启动 Activity。
应用从系统接收通知
PendingIntent
。对于服务和广播接收器的 PendingIntent,应用可以在 PendingIntent 发送后的几秒钟内启动 Activity。应用接收到由另一个可见应用发送的
PendingIntent
。应用接收到系统广播,应用应在此广播中启动 UI。例如,
ACTION_NEW_OUTGOING_CALL
和SECRET_CODE_ACTION
。应用可以在广播发送后的几秒钟内启动 Activity。应用通过
CompanionDeviceManager
API 与配套硬件设备关联。此 API 允许应用响应用户在配对设备上执行的操作来启动 Activity。用户授予了应用
SYSTEM_ALERT_WINDOW
权限。
从 PendingIntent 启动 Activity 时需要选择启用
为避免基于列出的条件意外启动 Activity,从 Android 14 开始,提供了明确的 API,允许您选择启用或禁用授予应用启动 Activity 的权限。
以 Android 15 或更高版本为目标的应用将默认不再隐式授予其创建的 PendingIntent
后台 Activity 启动 (BAL) 权限。因此,需要明确选择启用;以下是根据应用是发送还是创建 PendingIntent
而定的选项。
由 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()
或类似方法。
阅读相关参考文档了解更多详情
ActivityOptions.setPendingIntentBackgroundActivityStartMode
ActivityOptions.setPendingIntentCreatorBackgroundActivityStartMode
严格模式
从 Android 16 开始,应用开发者可以启用严格模式,以便在 Activity 启动被阻止(或在应用的目标 SDK 提高时有被阻止的风险)时收到通知。
在您的 Application、Activity 或其他应用组件的 Application.onCreate()
方法早期启用的示例代码
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectBlockedBackgroundActivityLaunch()
.penaltyLog()
.build());
)
}
阅读严格模式文档了解更多详情。