无法在模拟器内复制 ForegroundServiceStartNotAllowedException

问题描述 投票:0回答:1

根据 Google Play Console 崩溃和 ANR,我的应用程序在 Android 12+ 设备上遇到了很多

ForegroundServiceStartNotAllowedException
崩溃。这是因为 Google 引入了后台应用程序无法启动前台服务的限制。

该应用程序是一个音乐播放器。

我没有 Android 12+ 设备,因此我设置了运行 Android 13 的模拟器来进行复制。但是,我无法复制此崩溃,我想知道这是否是因为我正在使用模拟器。 有没有办法设置模拟器来确保它发生?

堆栈跟踪示例

以下是 Google Play Console 报告的堆栈跟踪示例:

Exception java.lang.RuntimeException:
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:5261)
  at android.app.ActivityThread.-$$Nest$mhandleServiceArgs
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2447)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loopOnce (Looper.java:226)
  at android.os.Looper.loop (Looper.java:313)
  at android.app.ActivityThread.main (ActivityThread.java:8757)
  at java.lang.reflect.Method.invoke
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:571)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067)
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.readParcelableInternal (Parcel.java:4787)
  at android.os.Parcel.readParcelable (Parcel.java:4755)
  at android.os.Parcel.createExceptionOrNull (Parcel.java:3018)
  at android.os.Parcel.createException (Parcel.java:3007)
  at android.os.Parcel.readException (Parcel.java:2990)
  at android.os.Parcel.readException (Parcel.java:2932)
  at android.app.IActivityManager$Stub$Proxy.setServiceForeground (IActivityManager.java:6978)
  at android.app.Service.startForeground (Service.java:743)
  at github.daneren2005.dsub.util.Notifications.startForeground (Notifications.java:462)
  at github.daneren2005.dsub.util.Notifications.shutGoogleUpNotification (Notifications.java:384)
  at github.daneren2005.dsub.service.DownloadService.onStartCommand (DownloadService.java:317)
  at android.app.ActivityThread.handleServiceArgs (ActivityThread.java:5243)

当前复制过程

  1. 开始在我的应用程序中播放音乐。
  2. 单击“主页”按钮。
  3. 单击模拟器上的CALL DEVICE。 (此时音乐暂停)。
  4. 挂断电话。 (短暂暂停后,音乐再次开始播放 - 这就是我预计崩溃的地方)。

我知道应该会发生崩溃,因为我已将日志记录添加到启动前台服务的代码中:

...
Log.d(TAG, "Notifications, current state: " + ProcessLifecycleOwner.get().getLifecycle().getCurrentState());
downloadService.startForeground(notificationId, notification);
...

此时,生命周期状态为 CREATED,我认为这意味着它位于后台。但是,崩溃似乎并未发生,并且应用程序继续运行。

我尝试过的事情

  • 确保应用程序启用电池优化 - 尝试“优化”和“限制”。
  • 更改了模拟器中的电池设置。
  • 启用 ActivityManager 记录受限前台启动。这样我就在 logcat 中看到了
    ActivityManager: Service.startForeground() not allowed due to bg restriction: service ga.asti.android/github.daneren2005.dsub.service.DownloadService
    这是同样的问题吗?为什么它不会导致崩溃?

有很多关于修复这个问题的指南,但是我想知道如何首先复制它,这样我知道我的修复正在起作用

android android-emulator android-service android-12 android-13
1个回答
0
投票

我暂时将其作为答案,除非有人可以提供一种在模拟器中产生更直观的崩溃的方法。

我发现我的应用程序在后台运行时请求前台服务的唯一迹象是配置 ActivityManager 以警告此类情况,然后按照 grep logcat 报告它们。

  1. 启用 ActivityManager 记录受限前台启动。

    adb shell device_config put activity_manager \
       default_fgs_starts_restriction_notification_enabled true
    
  2. 单击主页键将应用程序置于后台

  3. 开始观看logcat:

    adb logcat -T 1 | grep ActivityManager
    
  4. 导致可能运行startForeground的行为(在我的应用程序中,音乐播放器:播放音乐时,在模拟器中拨打电话,接听电话,然后挂断)。

  5. 观察 logcat 输出是否有类似以下内容:

    Service.startForeground() not allowed due to bg restriction: service my.app.packagename/my.app.XyzService
    
© www.soinside.com 2019 - 2024. All rights reserved.