Связанный сбой службы с "контекстом".startForegroundService () не вызывал службу.startForeground()" ошибка

В настоящее время я работаю над приложением воспроизведения звука, и я использую запущенную связанную службу для воспроизведения музыки в фоновом режиме. Я запускаю и привязываюсь к службе, используя следующий код.

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)

это происходит только на Oreo, и я уже читал о фоновых ограничениях в Oreo. Но следующие моменты меня беспокоят.

  • эта служба является связанной службой (на которую не влияют ограничения)
  • я никогда не использую контекст.startForegroundService () для запуска службы.(и не хочется)
  • служба не аварийно завершает работу, когда она понижается с переднего плана, это происходит при удалении уведомление.

почему служба рушится? Что я делаю не так? Я очень благодарен, если кто-нибудь скажет мне, что здесь происходит.

4 ответов


расширить на UdeshUk это!--5--> - любое использование MediaButtonReceiver (либо построение ожидающих намерений или просто получение намерений кнопки мультимедиа) может привести к вызову вашей службы с помощью startForegroundService, потому что MediaButtonReceiver.onReceive запускает вашу службу таким образом на Oreo. Я нигде этого не видел.


вы должны вызвать этот метод внутри вашего класса обслуживания onCreate () метод: ->

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);
        }
    }

документы 8.0 Изменения В Поведении

система позволяет приложениям вызывать контекст.startForegroundService () даже пока приложение находится в фоновом режиме. Однако приложение должно вызывать это службы startForeground() метод в течение пяти секунд после сервис создан.

Итак, вы должны вызвать startForeground внутри onCreate() для своей службы.


Я нашел проблему. В моем уведомлении я установил

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

поэтому, когда пользователь удаляет уведомление, он вызывает startForegroundService (), потому что я вызывал stopForeground () ранее при приостановке.

чтобы преодолеть, я использовал настраиваемое ожидающее намерение и обработал его в onStartCommand() вместо MediaButtonReveiver это PendingIntent