webentwicklung-frage-antwort-db.com.de

Ein Absturz des gebundenen Dienstes mit dem Fehler "Context.startForegroundService () hat dann Service.startForeground () nicht aufgerufen"

Ich arbeite derzeit an einer App für die Audiowiedergabe und verwende einen gestarteten gebundenen Dienst, um Musik im Hintergrund abzuspielen. Ich starte und binde mit folgendem Code an den Dienst.

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

Es wird beim Abspielen in den Vordergrund befördert und beim Anhalten der Musik herabgestuft.

// onAudioPlay
service.startForeground(NOTIFY_ID, notification)

// onAudioPause
service.stopForeground(false)

Service funktioniert bisher einwandfrei. Wenn der Benutzer die Benachrichtigung im angehaltenen Zustand durchwischt (entfernt), stürzt der Dienst nach einigen Sekunden ab und gibt diesen Fehler aus.

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)

Dies passiert nur auf Oreo und ich habe bereits über die Hintergrundbeschränkungen in Oreo gelesen. Aber folgende Punkte nerven mich.

  • Dieser Service ist ein gebundener Service (der nicht von Einschränkungen betroffen ist)
  • Ich verwende niemals Context.startForegroundService (), um den Dienst zu starten (und möchte ihn nicht verwenden).
  • Der Dienst stürzt nicht ab, wenn er aus dem Vordergrund herabgestuft wird, sondern wenn die Benachrichtigung entfernt wird.

Warum stürzt der Dienst ab? Was mache ich falsch? Ich bin sehr dankbar, wenn mir jemand sagt, was hier passiert.

21
UdeshUK

Zum Erweitern auf deshUks Antwort - jede Verwendung von MediaButtonReceiver (entweder Erstellen ausstehender Absichten oder nur Empfangen von Medienknopf-Absichten) kann dazu führen, dass Ihr Dienst mit startForegroundService aufgerufen wird, weil MediaButtonReceiver.onReceive startet Ihren Dienst auf diese Weise auf Oreo. Ich habe das nirgendwo dokumentiert gesehen.

12
Andy S

Sie müssen diese Methode in Ihrer Service-Klasse onCreate () aufrufen: ->

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
Ramkailash

Ich habe das Problem gefunden. In meiner Benachrichtigung habe ich eingestellt

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

Wenn der Benutzer die Benachrichtigung entfernt, ruft er startForegroundService () auf, da ich zuvor stopForeground () aufgerufen habe, als ich angehalten habe.

Um dies zu überwinden, habe ich eine benutzerdefinierte ausstehende Absicht verwendet und sie in onStartCommand() anstelle von MediaButtonReveiver's PendingIntent behandelt

6
UdeshUK

Aus den Dokumenten 8.0 Verhaltensänderungen

Das System ermöglicht Apps, Context.startForegroundService () aufzurufen, auch wenn sich die App im Hintergrund befindet. Die App muss jedoch die startForeground () - Methode dieses Dienstes innerhalb von fünf Sekunden nach dem Erstellen des Dienstes aufrufen.

Sie müssen also startForeground in onCreate () für Ihren Dienst aufrufen.

2
lakshman.pasala

Spät zur Party, aber wie schon erwähnt, ist es das MediaButtonReceiver; es hat diesen Code:

    @Override
    public void onReceive(Context context, Intent intent) {
        ...
        startForegroundService(context, intent);
        ...
    }

Ich verwende den Empfänger in einem gebundenen Dienst, also habe ich eine Klasse erstellt, die bis auf diese Zeile genau den gleichen Code wie MediaButtonReceiver hat. Ich habe es ersetzt durch:

        context.startService(intent);
1
UpsideDownTree