Связанный сбой службы с "контекстом".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
