为了帮助开发者更有意图地定义面向用户的前台服务,Android 10 在 <service>
元素中引入了 android:foregroundServiceType
属性。
如果您的应用面向 Android 14,则必须指定合适的前台服务类型。与之前的 Android 版本一样,可以组合多种类型。以下列出了可供选择的前台服务类型:
camera
connectedDevice
dataSync
health
location
mediaPlayback
mediaProjection
microphone
phoneCall
remoteMessaging
shortService
specialUse
systemExempted
如果您的应用中的用例不与这些类型中的任何一种关联,我们强烈建议您将逻辑迁移到使用 WorkManager 或 用户发起的数据传输作业。
health、remoteMessaging、shortService、specialUse
和 systemExempted
类型是 Android 14 中新增的。
以下代码片段提供了一个在前台服务类型在清单中声明的示例:
<manifest ...>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<application ...>
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="false">
</service>
</application>
</manifest>
如果面向 Android 14 的应用在清单中没有为给定服务定义类型,则在为该服务调用 startForeground()
时,系统将引发 MissingForegroundServiceTypeException
。
声明使用前台服务类型的新权限
如果面向 Android 14 的应用使用前台服务,它们必须根据 Android 14 引入的前台服务类型声明一个特定权限。这些权限显示在本页面的每个前台服务类型的预期用例和强制执行部分中标记为“您必须在清单文件中声明的权限”的部分。
所有权限都定义为普通权限,并默认授予。用户不能撤销这些权限。
在运行时包含前台服务类型
应用程序启动前台服务的最佳实践是使用 startForeground()
的 ServiceCompat
版本(在 androidx-core 1.12 及更高版本中可用),在该版本中您传入前台服务类型的位整数。您可以选择传入一个或多个类型值。
通常,您应该只声明特定用例所需的类型。这使得满足系统对每个前台服务类型的期望变得更容易。在以前台服务启动时具有多种类型的情况下,前台服务必须遵守所有类型的平台强制执行要求。
ServiceCompat.startForeground(0, notification, FOREGROUND_SERVICE_TYPE_LOCATION)
如果在调用中未指定前台服务类型,则类型默认为清单中定义的值。如果您在清单中未指定服务类型,系统将抛出 MissingForegroundServiceTypeException
。
如果前台服务在启动后需要新的权限,您应该再次调用 startForeground()
并添加新的服务类型。例如,假设一个健身应用运行一个跑步跟踪服务,该服务始终需要 location
信息,但可能需要或不需要 media
权限。您需要在清单中同时声明 location
和 mediaPlayback
。如果用户开始跑步并只想跟踪其位置,您的应用应调用 startForeground()
并仅传递 location
服务类型。然后,如果用户想开始播放音频,再次调用 startForeground()
并传递 location|mediaPlayback
。
系统运行时检查
系统会检查前台服务类型的正确使用情况,并确认应用已请求正确的运行时权限或使用所需的 API。例如,系统期望使用前台服务类型 FOREGROUND_SERVICE_TYPE_LOCATION
的应用请求 ACCESS_COARSE_LOCATION
或 ACCESS_FINE_LOCATION
。
这意味着应用程序在请求用户权限和启动前台服务时必须遵循非常特定的操作顺序。权限必须在应用程序尝试调用 startForeground()
之前请求并授予。在前台服务启动后请求相应权限的应用程序必须更改此操作顺序,并在启动前台服务之前请求权限。
平台强制执行的具体细节显示在本页面的每个前台服务类型的预期用例和强制执行部分中标记为“运行时要求”的部分。
每个前台服务类型的预期用例和强制执行
为了使用给定的前台服务类型,您必须在清单文件中声明特定的权限,必须满足特定的运行时要求,并且您的应用必须满足该类型的一个预期用例集。以下部分解释了您必须声明的权限、运行时先决条件以及每种类型的预期用例。
相机
- 在清单中
android:foregroundServiceType
下声明的前台服务类型 camera
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_CAMERA
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_CAMERA
- 运行时先决条件
请求并授予
CAMERA
运行时权限注意:
CAMERA
运行时权限受限于“使用时”限制。因此,您的应用在后台运行时,您无法创建camera
前台服务,但有一些例外情况。有关更多信息,请参阅对需要“使用时”权限的前台服务启动的限制。- 描述
在后台继续访问相机,例如允许多任务的视频聊天应用。
已连接设备
- 在清单中声明的前台服务类型
android:foregroundServiceType
connectedDevice
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_CONNECTED_DEVICE
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE
- 运行时先决条件
以下至少一项条件必须为真:
在您的清单中声明以下至少一项权限:
请求并授予以下至少一项运行时权限:
- 描述
与需要蓝牙、NFC、IR、USB 或网络连接的外部设备交互。
- 替代方案
如果您的应用需要持续向外部设备传输数据,请考虑改用伴侣设备管理器。使用伴侣设备存在 API 可帮助您的应用在伴侣设备在范围内时保持运行。
如果您的应用需要扫描蓝牙设备,请考虑改用蓝牙扫描 API。
数据同步
- 在清单中声明的前台服务类型
android:foregroundServiceType
dataSync
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_DATA_SYNC
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_DATA_SYNC
- 运行时先决条件
- 无
- 描述
数据传输操作,例如:
- 数据上传或下载
- 备份和恢复操作
- 导入或导出操作
- 获取数据
- 本地文件处理
- 通过网络在设备和云端之间传输数据
- 替代方案
有关详细信息,请参阅数据同步前台服务的替代方案。
健康
- 在清单中声明的前台服务类型
android:foregroundServiceType
health
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_HEALTH
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_HEALTH
- 运行时先决条件
以下至少一项条件必须为真:
在您的清单中声明
HIGH_SAMPLING_RATE_SENSORS
权限。请求并授予以下至少一项运行时权限:
注意:
BODY_SENSORS
和基于传感器的 READ 运行时权限受“使用时”限制。因此,除非您已获得BODY_SENSORS_BACKGROUND
(API 级别 33 到 35)或READ_HEALTH_DATA_IN_BACKGROUND
(API 级别 36 及更高版本)权限,否则您的应用在后台时,您无法创建使用身体传感器的health
前台服务。有关更多信息,请参阅对需要“使用时”权限的前台服务启动的限制。- 描述
支持健身类别应用(例如运动跟踪器)的任何长时间运行用例。
位置
- 在清单中声明的前台服务类型
android:foregroundServiceType
location
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_LOCATION
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_LOCATION
- 运行时先决条件
用户必须已启用位置服务,并且应用必须被授予以下至少一项运行时权限:
注意:要检查用户是否已启用位置服务并授予运行时权限,请使用
PermissionChecker#checkSelfPermission()
注意:位置运行时权限受使用时限制。因此,除非您已获得
ACCESS_BACKGROUND_LOCATION
运行时权限,否则您的应用在后台运行时,您无法创建location
前台服务。有关更多信息,请参阅对需要“使用时”权限的前台服务启动的限制。- 描述
需要位置访问的长时间运行用例,例如导航和位置共享。
- 替代方案
如果您的应用需要在用户到达特定位置时触发,请考虑改用地理围栏 API。
媒体
- 在清单中声明的前台服务类型
android:foregroundServiceType
mediaPlayback
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_MEDIA_PLAYBACK
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
- 运行时先决条件
- 无
- 描述
- 在后台继续音频或视频播放。支持 Android TV 上的数字视频录制 (DVR) 功能。
- 替代方案
- 如果您正在显示画中画视频,请使用画中画模式。
媒体投影
- 在清单中声明的前台服务类型
android:foregroundServiceType
mediaProjection
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_MEDIA_PROJECTION
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
- 运行时先决条件
在启动前台服务之前调用
createScreenCaptureIntent()
方法。这样做会向用户显示一个权限通知;用户必须在您创建服务之前授予权限。创建前台服务后,您可以调用
MediaProjectionManager.getMediaProjection()
。- 描述
使用
MediaProjection
API 将内容投影到非主显示器或外部设备。此内容不一定仅限于媒体内容。- 替代方案
要将媒体流式传输到另一个设备,请使用 Google Cast SDK。
麦克风
- 在清单中声明的前台服务类型
android:foregroundServiceType
microphone
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_MICROPHONE
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_MICROPHONE
- 运行时先决条件
请求并授予
RECORD_AUDIO
运行时权限。注意:
RECORD_AUDIO
运行时权限受限于“使用时”限制。因此,您的应用在后台运行时,您无法创建microphone
前台服务,但有一些例外情况。有关更多信息,请参阅对需要“使用时”权限的前台服务启动的限制。- 描述
在后台继续麦克风捕获,例如录音机或通信应用。
电话呼叫
- 在清单中声明的前台服务类型
android:foregroundServiceType
phoneCall
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_PHONE_CALL
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_PHONE_CALL
- 运行时先决条件
以下至少一项条件必须为真:
- 应用已在其清单文件中声明
MANAGE_OWN_CALLS
权限。
- 应用已在其清单文件中声明
- 应用是默认拨号器应用,通过
ROLE_DIALER
角色。
- 应用是默认拨号器应用,通过
- 描述
使用
ConnectionService
API 继续正在进行的通话。- 替代方案
如果您需要拨打电话、视频或 VoIP 通话,请考虑使用
android.telecom
库。考虑使用
CallScreeningService
来筛选通话。
远程消息
- 在清单中声明的前台服务类型
android:foregroundServiceType
remoteMessaging
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_REMOTE_MESSAGING
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING
- 运行时先决条件
- 无
- 描述
- 在设备之间传输短信。当用户切换设备时,有助于保持其消息任务的连续性。
短服务
- 在清单中声明的前台服务类型
android:foregroundServiceType
shortService
- 您必须在清单中声明的权限
- 无
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_SHORT_SERVICE
- 运行时先决条件
- 无
- 描述
快速完成不能中断或推迟的关键工作。
这种类型有一些独特的特点:
- 只能运行一小段时间(约 3 分钟)。
- 不支持粘性前台服务。
- 无法启动其他前台服务。
- 不需要类型特定权限,但仍需要
FOREGROUND_SERVICE
权限。 shortService
只有在应用当前有资格启动新的前台服务时才能更改为其他服务类型。- 前台服务可以随时将其类型更改为
shortService
,此时超时期限开始。
shortService
的超时从调用Service.startForeground()
的那一刻开始。应用应在超时发生之前调用Service.stopSelf()
或Service.stopForeground()
来停止其服务。否则,将调用新的Service.onTimeout()
,为应用提供短暂的机会调用stopSelf()
或stopForeground()
来停止其服务。在调用
Service.onTimeout()
后不久,应用进入缓存状态,并且不再被视为处于前台,除非用户正在积极与应用交互。在应用缓存且服务未停止后不久,应用会收到 ANR。ANR 消息会提到FOREGROUND_SERVICE_TYPE_SHORT_SERVICE
。因此,实现Service.onTimeout()
回调被认为是最佳实践。Service.onTimeout()
回调在 Android 13 及更低版本上不存在。如果同一服务在此类设备上运行,它不会收到超时,也不会 ANR。请确保您的服务一旦完成处理任务就立即停止,即使它尚未收到Service.onTimeout()
回调。需要注意的是,如果
shortService
的超时未得到遵守,即使应用有其他有效的前台服务或其他应用生命周期进程正在运行,应用也会 ANR。如果应用对用户可见或满足允许从后台启动前台服务的豁免条件之一,则再次调用带有
FOREGROUND_SERVICE_TYPE_SHORT_SERVICE
参数的Service.StartForeground()
会将超时再延长 3 分钟。如果应用对用户不可见且不满足任何豁免条件,则任何启动另一个前台服务(无论类型如何)的尝试都会导致ForegroundServiceStartNotAllowedException
。如果用户为您的应用禁用电池优化,它仍然受 shortService FGS 超时的影响。
如果您启动的前台服务包含
shortService
类型和另一个前台服务类型,系统将忽略shortService
类型声明。但是,该服务仍必须遵守其他声明类型的先决条件。有关更多信息,请参阅前台服务文档。
特殊用途
- 在清单中声明的前台服务类型
android:foregroundServiceType
specialUse
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_SPECIAL_USE
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_SPECIAL_USE
- 运行时先决条件
- 无
- 描述
涵盖其他前台服务类型未涵盖的任何有效前台服务用例。
除了声明
FOREGROUND_SERVICE_TYPE_SPECIAL_USE
前台服务类型外,开发者还应在清单中声明用例。为此,他们应在<service>
元素中指定<property>
元素。当您在 Google Play 管理中心提交应用时,将审核这些值和相应的用例。您提供的用例是自由格式的,您应确保提供足够的信息,让审核者了解您为什么需要使用specialUse
类型。<service android:name="fooService" android:foregroundServiceType="specialUse"> <property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE" android:value="explanation_for_special_use"/> </service>
系统豁免
- 在清单中声明的前台服务类型
android:foregroundServiceType
systemExempted
- 您必须在清单中声明的权限
FOREGROUND_SERVICE_SYSTEM_EXEMPTED
- 要传递给
startForeground()
的常量 FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED
- 运行时先决条件
- 无
- 描述
为系统应用和特定系统集成保留,以继续使用前台服务。
要使用此类型,应用必须满足以下至少一项条件:
- 设备处于演示模式状态
- 应用是设备所有者
- 应用是配置文件所有者
- 具有
ROLE_EMERGENCY
角色的安全应用 - 设备管理员应用
- 持有
SCHEDULE_EXACT_ALARM
或USE_EXACT_ALARM
权限并使用前台服务在后台继续闹钟的应用,包括仅振动闹钟。 VPN 应用(通过 Settings > Network & Internet > VPN 配置)
否则,声明此类型将导致系统抛出
ForegroundServiceTypeNotAllowedException
。
Google Play 使用前台服务类型的政策强制执行
如果您的应用面向 Android 14 或更高版本,您需要将应用的前台服务类型声明在 Play 管理中心的“应用内容”页面(政策 > 应用内容)中。有关如何在 Play 管理中心声明前台服务类型的更多信息,请参阅了解前台服务和全屏 Intent 要求。