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