首页 文章

绑定服务崩溃与“Context.startForegroundService()然后没有调用Service.startForeground()”错误

提问于
浏览
16

我正在制作音频播放应用程序,我正在使用一个启动绑定服务在后台播放音乐 . 我使用以下代码启动并绑定到服务 .

val intent = Intent(context, MusicService::class.java)
context.startService(intent)
context.bindService(intent, serviceConnection, 0)

它在播放时被提升为前景,在音乐暂停时被降级 .

// onAudioPlay
service.startForeground(NOTIFY_ID, notification)

// onAudioPause
service.stopForeground(false)

到目前为止服务工作很好 . 但是当用户在暂停状态下刷新(删除)通知时,服务会在几秒钟后崩溃,从而出现此错误 .

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myplayer, PID: 4380
    android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
        android.app.ActivityThread$H.handleMessage(ActivityThread.java:1775)
        android.os.Handler.dispatchMessage(Handler.java:105)
        android.os.Looper.loop(Looper.java:164)
        android.app.ActivityThread.main(ActivityThread.java:6541)
        java.lang.reflect.Method.invoke(Native Method)
      com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

这只发生在奥利奥上,我已经读过奥利奥的背景限制 . 但以下几点让我感到困惑 .

  • 此服务是绑定服务(不受限制影响)

  • 我从不使用Context.startForegroundService()来启动服务 . (并且不想使用它)

  • 删除通知时,服务没有't crash when it gets demoted from foreground, it' .

为什么服务崩溃了?我究竟做错了什么?如果有人告诉我这里发生了什么,我很感激 .

4 回答

  • 7

    要扩展UdeshUk's answer - 任何使用 MediaButtonReceiver (构建待定意图或仅接收媒体按钮意图)都可能导致使用 startForegroundService 调用您的服务,因为 MediaButtonReceiver.onReceive 在Oreo上以这种方式启动您的服务 . 我没有在任何地方看到这个记录 .

  • 2

    我发现了问题 . 在我的通知中,我已经设定了

    setDeleteIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(service, PlaybackStateCompat.ACTION_STOP))
    

    因此,当用户删除通知时,它会调用startForegroundService(),因为我在暂停时调用了stopForeground() .

    为了克服,我使用了一个自定义待定意图并在 onStartCommand() 处理它而不是 MediaButtonReveiver's PendingIntent

  • 4

    You must call this method inside your Service class onCreate() method:->

    private void startServiceOreoCondition(){
            if (Build.VERSION.SDK_INT >= 26) {
    
    
                String CHANNEL_ID = "my_service";
                String CHANNEL_NAME = "My Background Service";
    
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                        CHANNEL_NAME,NotificationManager.IMPORTANCE_NONE);
                ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
    
                Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                        .setCategory(Notification.CATEGORY_SERVICE).setSmallIcon(R.drawable.ic_tgc_icon).setPriority(PRIORITY_MIN).build();
    
                startForeground(101, notification);
            }
        }
    
  • 4

    来自文档8.0 Behavior Changes

    即使应用程序在后台,系统也允许应用程序调用Context.startForegroundService() . 但是,应用程序必须在创建服务后的五秒内调用该服务的startForeground()方法 .

    因此,您必须在onCreate()内为您的服务调用startForeground .

相关问题