update start services running oreo apps always android service kotlin android-8.0-oreo

android - services - El bloqueo del servicio enlazado con "Context.startForegroundService() no llamó al error Service.startForeground()”



service android 8 (4)

Actualmente estoy trabajando en la aplicación de reproducción de audio y estoy usando un servicio vinculado para reproducir música en segundo plano. Comienzo y me vinculo al servicio usando el siguiente código.

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

Cuando se reproduce, se pasa a primer plano cuando se reproduce y se baja de categoría cuando se detiene la música.

// onAudioPlay service.startForeground(NOTIFY_ID, notification) // onAudioPause service.stopForeground(false)

Servicio de trabajo bien hasta ahora. Pero cuando el usuario desliza (elimina) la notificación en el estado de pausa, el servicio se bloquea después de unos segundos dando este error.

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)

Esto solo sucede en Oreo y ya leí sobre las limitaciones de fondo en Oreo. Pero los siguientes puntos me molestan.

  • Este servicio es un servicio vinculado (que no está afectado por limitaciones)
  • Nunca uso Context.startForegroundService () para iniciar el servicio (y no quiero usarlo)
  • El servicio no falla cuando es degradado desde el primer plano, sucede cuando se elimina la notificación.

¿Por qué el servicio está fallando? ¿Qué estoy haciendo mal? Estoy muy agradecido si alguien me dice qué está pasando aquí.


De los cambios de comportamiento docs 8.0

El sistema permite que las aplicaciones llamen a Context.startForegroundService () incluso cuando la aplicación está en segundo plano. Sin embargo, la aplicación debe llamar al método startForeground () de ese servicio dentro de los cinco segundos posteriores a la creación del servicio.

Por lo tanto, debe llamar a startForeground dentro de onCreate () para su servicio.


Encontré el problema. En mi notificación he puesto

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

Entonces, cuando el usuario elimina la notificación, llama a startForegroundService () porque antes llamé a stopForeground () cuando estaba en pausa.

Para superar, utilicé un intento pendiente personalizado y lo onStartCommand() en onStartCommand() lugar de PendingIntent de MediaButtonReveiver


Para ampliar la respuesta de UdeshUk, cualquier uso de MediaButtonReceiver (ya sea para construir intentos pendientes o simplemente para recibir botones de medios) puede hacer que se llame a su servicio con startForegroundService , porque MediaButtonReceiver.onReceive inicia su servicio de esa manera en Oreo. No he visto esto documentado en ninguna parte.


Debe llamar a este método dentro de su clase de servicio método 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); } }