需要指定前台服务类型

为了帮助开发者更明确地定义面向用户的前台服务,Android 10 在<service> 元素中引入了android:foregroundServiceType 属性。

如果您的应用面向 Android 14,则必须指定适当的前台服务类型。与 Android 的先前版本一样,可以组合多种类型。此列表显示了可供选择的前台服务类型

如果您的应用中的用例与这些类型中的任何一个都不相关,我们强烈建议您迁移您的逻辑以使用WorkManager用户启动的数据传输作业

health、remoteMessaging、shortService、specialUsesystemExempted 类型是 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权限。你需要在清单中声明locationmediaPlayback。如果用户开始跑步并且只想追踪他们的位置,你的应用程序应该调用startForeground()并只传递location服务类型。然后,如果用户想要开始播放音频,则再次调用startForeground()并传递location|mediaPlayback

系统运行时检查

系统会检查前台服务类型的正确使用情况,并确认应用程序已请求正确的运行时权限或使用了必需的 API。例如,系统期望使用前台服务类型FOREGROUND_SERVICE_TYPE_LOCATION的应用程序请求ACCESS_COARSE_LOCATIONACCESS_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
运行时先决条件

以下条件中至少必须满足一个:

注意: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
运行时先决条件

以下条件中至少必须满足一个:

  • 应用程序通过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
运行时先决条件
描述

保留供系统应用程序和特定系统集成使用,以继续使用前台服务。

要使用此类型,应用程序必须满足以下条件之一:

使用前台服务类型的 Google Play 策略执行

如果您的应用的目标是 Android 14 或更高版本,您需要在 Play Console 的应用内容页面(**策略 > 应用内容**)中声明您的应用的前台服务类型。有关如何在 Play Console 中声明前台服务类型的更多信息,请参阅 了解前台服务和全屏意图要求