为了帮助开发者更明确地定义面向用户的前台服务,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、红外、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
运行时权限受使用中限制的约束。因此,当你的应用程序处于后台时,你无法创建使用人体传感器的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()
回调被认为是最佳实践。Android 13 及更低版本中不存在
Service.onTimeout()
回调。如果相同服务在这些设备上运行,则它不会收到超时,也不会出现 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 Console 中提交您的应用时,会审查这些值和相应的用例。您提供的用例是自由格式的,您应该确保提供足够的信息,让审核者了解您为什么需要使用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 应用(使用 **设置 > 网络和互联网 > VPN** 配置)
否则,声明此类型会导致系统抛出
ForegroundServiceTypeNotAllowedException
错误。
使用前台服务类型的 Google Play 策略执行
如果您的应用的目标是 Android 14 或更高版本,您需要在 Play Console 的应用内容页面(**策略 > 应用内容**)中声明您的应用的前台服务类型。有关如何在 Play Console 中声明前台服务类型的更多信息,请参阅 了解前台服务和全屏意图要求。