我升級我的應用程式targetSdkVersion,并compileSdkVersion以SDK 31,并開始接收在服務中應用下列崩潰的更新在后臺部件。
java.lang.RuntimeException:
at android.app.ActivityThread.handleReceiver (ActivityThread.java:4321)
at android.app.ActivityThread.access$1600 (ActivityThread.java:247)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2068)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:201)
at android.os.Looper.loop (Looper.java:288)
at android.app.ActivityThread.main (ActivityThread.java:7842)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1003)
Caused by: android.app.ForegroundServiceStartNotAllowedException:
at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:54)
at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel (ForegroundServiceStartNotAllowedException.java:50)
at android.os.Parcel.readParcelable (Parcel.java:3333)
at android.os.Parcel.createExceptionOrNull (Parcel.java:2420)
at android.os.Parcel.createException (Parcel.java:2409)
at android.os.Parcel.readException (Parcel.java:2392)
at android.os.Parcel.readException (Parcel.java:2334)
at android.app.IActivityManager$Stub$Proxy.startService (IActivityManager.java:5971)
at android.app.ContextImpl.startServiceCommon (ContextImpl.java:1847)
at android.app.ContextImpl.startForegroundService (ContextImpl.java:1823)
at android.content.ContextWrapper.startForegroundService (ContextWrapper.java:779)
at android.content.ContextWrapper.startForegroundService (ContextWrapper.java:779)
at com.mypackage.appname.ui.widget.widget_package.WidgetClassName.onUpdate (WidgetClassName.java:48)
at android.appwidget.AppWidgetProvider.onReceive (AppWidgetProvider.java:66)
at com.mypackage.appname.ui.widget.widget_package.WidgetClassName.onReceive (WidgetClassName.java)
at android.app.ActivityThread.handleReceiver (ActivityThread.java:4312)
at android.app.ActivityThread.access$1600 (ActivityThread.java:247)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2068)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:201)
at android.os.Looper.loop (Looper.java:288)
at android.app.ActivityThread.main (ActivityThread.java:7842)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1003)
Caused by: android.os.RemoteException:
at com.android.server.am.ActiveServices.startServiceLocked (ActiveServices.java:691)
at com.android.server.am.ActiveServices.startServiceLocked (ActiveServices.java:616)
at com.android.server.am.ActivityManagerService.startService (ActivityManagerService.java:11839)
at android.app.IActivityManager$Stub.onTransact (IActivityManager.java:2519)
at com.android.server.am.ActivityManagerService.onTransact (ActivityManagerService.java:2498)
此外,如果您使用的是 Firebase Crashlytics 之類的東西,那么您的堆疊跟蹤必須是這樣的 ->
Caused by android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service com.mypackage.appname/.ui.widget.widget_package.MyForegroundServiceName
at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel(ForegroundServiceStartNotAllowedException.java:54)
at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel(ForegroundServiceStartNotAllowedException.java:50)
at android.os.Parcel.readParcelable(Parcel.java:3333)
at android.os.Parcel.createExceptionOrNull(Parcel.java:2420)
at android.os.Parcel.createException(Parcel.java:2409)
at android.os.Parcel.readException(Parcel.java:2392)
at android.os.Parcel.readException(Parcel.java:2334)
at android.app.IActivityManager$Stub$Proxy.startService(IActivityManager.java:5971)
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1847)
at android.app.ContextImpl.startForegroundService(ContextImpl.java:1823)
at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:779)
at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:779)
at com.mypackage.appname.ui.widget.widget_package.WidgetClassName.onUpdate(WidgetClassName.java:48)
at android.appwidget.AppWidgetProvider.onReceive(AppWidgetProvider.java:66)
at com.mypackage.appname.ui.widget.widget_package.WidgetClassName.onReceive(WidgetClassName.java)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:4312)
at android.app.ActivityThread.access$1600(ActivityThread.java:247)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2068)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7842)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
我正在添加重現此問題的方法,并修復此問題,因為當我搜索它時,我沒有在 StackOverflow 上找到任何關于此的檔案。
uj5u.com熱心網友回復:
如何重現崩潰
步驟 1. 將您的targetSdkVersion和更新compileSdkVersion到 SDK 31。
第 2 步。嘗試在您的應用程式處于后臺時運行任何前臺服務。在我的例子中,它是onUpdate在updatePeriodMillis一段時間后呼叫小部件的方法,它將啟動一個前臺服務,該服務通過從互聯網獲取適當的資訊來更新資料。
請記住:Android 8.0 中添加的后臺執行限制與此問題無關。此限制/例外是在 Android 12/SDK 31 - Source 中添加的。
這是什么例外,為什么要添加它?
除少數特殊情況外,面向 Android 12(API 級別 31)或更高版本的應用無法在后臺運行時啟動前臺服務。如果應用程式在后臺運行時嘗試啟動前臺服務,并且前臺服務不滿足其中一種例外情況,則系統會拋出ForegroundServiceStartNotAllowedException.
這些特殊情況是:
您的應用程式從用戶可見的狀態(例如活動)轉換。
您的應用程式可以從后臺啟動 Activity,除非應用程式在現有任務的后臺堆疊中有一個 Activity。
您的應用使用 Firebase 云訊息傳遞接收高優先級訊息。
用戶對與您的應用相關的 UI 元素執行操作。例如,他們可能會與氣泡、通知、小部件或活動進行互動。
您的應用會呼叫準確的警報來完成用戶請求的操作。
您的應用是設備當前的輸入法。
您的應用收到與地理圍欄或活動識別轉換相關的事件。
在設備重新啟動并在廣播接收器中接收到 ACTION_BOOT_COMPLETED、ACTION_LOCKED_BOOT_COMPLETED 或 ACTION_MY_PACKAGE_REPLACED 意圖操作后。
您的應用在廣播接收器中接收 ACTION_TIMEZONE_CHANGED、ACTION_TIME_CHANGED 或 ACTION_LOCALE_CHANGED 意圖操作。
您的應用收到需要 BLUETOOTH_CONNECT 或 BLUETOOTH_SCAN 權限的藍牙廣播。
具有特定系統角色或權限的應用程式,例如設備所有者和組態檔所有者。
您的應用使用配套設備管理器并宣告 REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND 權限或 REQUEST_COMPANION_RUN_IN_BACKGROUND 權限。盡可能使用 REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND。
用戶為您的應用關閉電池優化。您可以通過將用戶發送到系統設定中應用的應用資訊頁面來幫助用戶找到此選項。為此,請呼叫包含 ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS 意圖操作的意圖。
可能的解決方案
解決方案1
這將在 Play 商店中作業一段時間,直到 Google 強制升級到 API 級別 31。
Currently, starting November 2021 all apps must target API Level 30 and above. So if you're using API Level 31 for your app, downgrading your compileSdkVersion & targetSdkVersion to API Level 30 should fix the issue (atleast for a while).
Solution 2
For time-sensitive work
If you were using Foreground service to do work that is time sensitive, start Foreground services within an exact alarm. Check out more about this from documentation here -> Set an exact alarm.
For time-insensitive/expedited work
This is the solution that I ended up using for my app. Use WorkManager to schedule and start the background work. Check out more about this from documentation here -> Schedule expedited work.
You can know more about WorkManager here -> WorkManager
Github Repo for WorkManager samples -> WorkManager Samples
I added this answer specifically because searching for this exception does not bring up any resources to know why the service behaves differently on Android 12. All this is present in Google's documentation, and always remember to check the behaviour changes from the doc.
Everything related to this change can be found here -> Android 12 Behavior Changes, specifically within the Foreground Service launch restrictions.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/325195.html
