從背景啟動前景服務的相關限制

指定 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 時,表示「您的應用程式在使用期間具有這項權限」。

因此,如果前景服務需要使用中權限,則必須在應用程式有可見活動時呼叫 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