仅限 Android 9 (Pie):Context.startForegroundService() 没有调用 Service.startForeground() - 在 Oreo 上工作正常

Posted

技术标签:

【中文标题】仅限 Android 9 (Pie):Context.startForegroundService() 没有调用 Service.startForeground() - 在 Oreo 上工作正常【英文标题】:Android 9 (Pie) Only: Context.startForegroundService() did not then call Service.startForeground() - Works fine on Oreo 【发布时间】:2019-03-31 13:50:24 【问题描述】:

我们调整了 Oreo 的持续通知,效果很好。现在,仅在 Pie 上(不在 Oreo 设备上发生),我们得到了标题错误。我缺少的 Pie 中的前台服务有什么变化吗?

这是前台服务的 onCreate 代码 ->

override fun onCreate() 
    super.onCreate()

    val notification: Notification = NotificationCompat.Builder(this, packageName)
            .setSmallIcon(R.drawable.status_notification_icon)
            .setContentTitle(getString(R.string.ongoing_notify_temp_title))
            .setContentText(getString(R.string.ongoing_notify_temp_message))
            .setGroup(AppConstants.NOTIFICATION_GROUP_ONGOING)
            .setColor(ContextCompat.getColor(this, R.color.custom_blue))
            .build()

    startForeground(ONGOING_NOTIFY_ID, notification)

    appSettings = AppSettings(this)

    weatherLookUpHelper = WeatherLookUpHelper()
    MyRoomDatabase.getInstance().invalidationTracker.addObserver(onChange)

    retrieveCurrentLocation()
    createAlarmManager()

如您所见,我们只是创建通知,然后调用 startForeground。关于为什么此代码会生成标题错误的任何想法?

旁注:Fabric Crashlytics 显示此崩溃仅发生在运行 Pie 的像素设备(像素、像素 xl、像素 2、像素 2 xl)上

编辑:我们确实在清单中拥有前台权限

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

【问题讨论】:

你的manifest里有这个权限吗Manifest.permission.FOREGROUND_SERVICE @MayRestinPeace 是的,我们这样做 这个问题你解决了吗? @knowledgeDrilling 不幸的是没有。从那以后我已经换了工作,我现在正在进行的项目没有这个问题,所以我怀疑我会跟进这个问题。对不起:( 【参考方案1】:

这里提到Background Service Limitations,app/service有5秒时间调用startForeground(),如果app在时限内没有调用startForeground(),系统会停止服务并声明app为ANR。

有一些可能性:

    在调用 startForeground() 方法之前,您的前台服务会被销毁/完成。 或者如果前台服务已经被实例化并且它被再次调用,那么onCreate方法将不会被调用,而是onStartCommand会被调用。然后把你的逻辑移到onStartCommand调用startForeground()方法。 你的通知id在startForegroundmust not be 0,否则也会导致崩溃。

【讨论】:

将 startForeground 放在 onStartCommand 中是否会有重复调用的风险? 不,onStartCommand 只会在您启动服务时在onCreate 之后被调用一次。但是,如果你多次启动服务,那么onStartCommand当然会被多次调用。【参考方案2】:

我缺少的 Pie 中的前台服务有什么变化吗?

是的 看看这里migration notes of Android 9 / Pie

改变

前台服务权限

总结

想要使用前台服务的应用现在必须首先请求FOREGROUND_SERVICE 权限。这是一个正常的权限,因此系统会自动将其授予请求的应用程序。未经许可启动前台服务会引发 SecurityException。

更新

Google 问题跟踪器中的相关问题 Context.startForegroundService() did not then call Service.startForeground

【讨论】:

@Psest328 你能分享你的日志吗 @Psest328 这里有问题检查issuetracker.google.com/issues/76112072 @Psest328 你能分享一下你ONGOING_NOTIFY_ID的价值吗?【参考方案3】:
    我恢复使用 startService() 而不是使用 startForeground() 解决了我的问题。

【讨论】:

同样的问题...在添加 API > Oreo 检查并使用startForegroundService(intent) 这会导致崩溃,即使我在onStartCommand 的服务中使用startForeground(0, builder.build()); 【参考方案4】:

ONCREATE 中实现以下代码后,我停止收到错误

Intent intent1 = new Intent(this, YourActivity.class);
          try 
                startService(intent1);
            catch ( Exception e1)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
                    this.startForegroundService(intent1);
                else 
                    Crashlytics.log("crash for first time, trying another.");
                    this.startService(intent1);
                
            

对我来说听起来很奇怪,但工作正常而不会崩溃。

【讨论】:

当应用程序从 API > Android oreo 关闭时,它不会崩溃,但只是服务(不是前台)将不起作用

以上是关于仅限 Android 9 (Pie):Context.startForegroundService() 没有调用 Service.startForeground() - 在 Oreo 上工作正常的主要内容,如果未能解决你的问题,请参考以下文章

Android(9)Pie中如何允许所有网络连接类型HTTP和HTTPS?

如何在 Android 9.0(PIE) 中获取 WIFI SSID?

Android Api(Okhttps)未在android 9(pie)及更高版本中调用[重复]

为啥 Android Studio 不会在 Android Pie (9.0) 上运行应用程序?

Android 9 (Pie),Context.startForegroundService() 没有调用 Service.startForeground():ServiceRecord

Android 9 Pie 崩溃 (com.google.android.gms...ClassNotFoundException)