针对从后台启动前台服务的限制

以 Android 12(API 级别 31)或更高版本为目标平台的应用在后台运行时,将无法启动前台服务,但少数特殊情况除外。如果应用在后台运行时尝试启动前台服务,并且该前台服务不符合任何一种例外情况,系统会抛出 ForegroundServiceStartNotAllowedException。

此外,如果应用想要启动需要使用时权限(例如身体传感器、相机、麦克风或位置信息权限)的前台服务,则无法在应用处于后台时创建该服务,即使应用属于后台启动限制的豁免情况之一也是如此。启动需要“在使用时”权限的前台服务的限制部分介绍了这样做的原因。

免于后台启动限制

在以下情况下,即使应用在后台运行,也可以启动前台服务:

对启动需要“使用时”权限的前台服务的限制

在 Android 14(API 级别 34)或更高版本中,如果您要启动需要“使用时”权限的前台服务,则需要注意一些特殊情况。

如果您的应用以 Android 14 或更高版本为目标平台,操作系统会在您创建前台服务时进行检查,以确保您的应用具有该服务类型的所有适当权限。例如,当您创建 microphone 类型的前台服务时,操作系统会验证您的应用当前是否具有 RECORD_AUDIO 权限。如果您没有该权限,系统会抛出 SecurityException。

对于“仅在使用时允许”权限,这会带来潜在问题。如果您的应用具有“仅在使用期间”权限,则该应用仅在前台运行时具有该权限。这意味着,如果您的应用在后台运行,并尝试创建类型为相机、位置信息或麦克风的前台服务,系统会发现您的应用目前没有所需的权限,并会抛出 SecurityException。

同样,如果您的应用在后台运行,并且创建了需要 BODY_SENSORS 权限的健康服务,则该应用目前不具有该权限,系统会抛出异常。(如果健康服务需要不同的权限,例如 ACTIVITY_RECOGNITION,则不适用。)调用 PermissionChecker.checkSelfPermission() 不会阻止此问题。如果您的应用具有“仅在使用时允许”权限,并且调用 checkSelfPermission() 来检查其是否具有该权限,则即使应用在后台运行,该方法也会返回 PERMISSION_GRANTED。当该方法返回 PERMISSION_GRANTED 时,表示“您的应用在使用期间具有此权限”。

因此,如果您的前台服务需要“使用期间”权限,您必须在应用具有可见 activity 时调用 Context.startForegroundService() 或 Context.bindService(),除非该服务属于定义的豁免情形之一。

免于受“使用时”权限限制

在某些情况下,即使前台服务是在应用 在后台运行时启动的,它仍然可以在应用在前台运行时(“在使用时”)访问位置信息、相机和麦克风信息。

在这些相同情况下,如果服务声明的前台服务类型为 location,并且由具有 ACCESS_BACKGROUND_LOCATION 权限的应用启动,则此服务可以随时访问位置信息,即使应用在后台运行也是如此。

以下列表包含这些情况:

  • 系统组件启动服务。
  • 该服务首先会与应用微件互动。
  • 该服务通过与通知互动来启动。
  • 该服务作为从其他可见应用发送的 PendingIntent 启动。
  • 该服务由在设备所有者模式下运行的设备政策控制器应用启动。
  • 该服务由提供 VoiceInteractionService 的应用启动。
  • 该服务由具有 START_ACTIVITIES_FROM_BACKGROUND 特权权限的应用启动。

确定应用中的哪些服务受到影响

测试您的应用时,请启动其前台服务。如果启动的服务对位置信息、麦克风和摄像头的访问受到限制,Logcat 中就会显示以下消息:

Foreground service started from background can not have \
location/camera/microphone access: service SERVICE_NAME