Permitir cancelación de la notificación después de llamar a stopForeground (false)
Tengo un servicio de medios que usa startForeground () para mostrar una notificación cuando se inicia la reproducción. Tiene botones de pausa / parada al reproducir, botones de reproducción / parada mientras está en pausa.
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this); // setup... Notification n = mBuilder.build(); if (state == State.Playing) { startForeground(mId, n); } else { stopForeground(false); mNotificationManager.notify(mId, n); }
El problema aquí es cuando se muestra / actualizar la notificación en su estado de pausa, se le debe permitir eliminarlo. mBuilder.setOngoing(false)
parece no tener ningún efecto ya que el startForeground
anterior startForeground
anula.
- IntentService - encuentra el número de Intents esperando en la cola
- El servicio se reinicia al matar el proceso de actividad
- ¿Por qué mis métodos ServiceConnection nunca se ejecutan?
- Servicio AIDL que no se conecta después de bindService ()
- Servicio de ventana superpuesta en Android
Llamar stopForeground(true);
Con el mismo código funciona como se esperaba, pero la Notificación parpadea cuando se destruye y se vuelve a crear. ¿Hay una forma de "actualizar" la notificación creada desde startForeground para permitir que se elimine después de llamar a stop?
Editar: Según se solicita, aquí está el código completo que crea la notificación. CreateNotification se llama cuando el servicio se reproduce o pausa.
private void createNotification() { NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("No Agenda") .setContentText("Live stream"); if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (state == State.Playing) { Intent pauseIntent = new Intent(this, MusicService.class); pauseIntent.setAction(ACTION_PAUSE); PendingIntent pausePendingIntent = PendingIntent.getService(MusicService.this, 0, pauseIntent, 0); mBuilder.addAction(R.drawable.pause, "Pause", pausePendingIntent); //mBuilder.setOngoing(true); } else if (state == State.Paused) { Intent pauseIntent = new Intent(this, MusicService.class); pauseIntent.setAction(ACTION_PAUSE); PendingIntent pausePendingIntent = PendingIntent.getService(MusicService.this, 0, pauseIntent, 0); mBuilder.addAction(R.drawable.play, "Play", pausePendingIntent); mBuilder.setOngoing(false); } Intent stopIntent = new Intent(this, MusicService.class); stopIntent.setAction(ACTION_STOP); PendingIntent stopPendingIntent = PendingIntent.getService(MusicService.this, 0, stopIntent, 0); setNotificationPendingIntent(mBuilder); mBuilder.addAction(R.drawable.stop, "Stop", stopPendingIntent); } else { Intent resultIntent = new Intent(this, MainActivity.class); PendingIntent intent = PendingIntent.getActivity(this, 0, resultIntent, 0); mBuilder.setContentIntent(intent); } Notification n = mBuilder.build(); if (state == State.Playing) { startForeground(mId, n); } else { stopForeground(true); mNotificationManager.notify(mId, n); } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void setNotificationPendingIntent(NotificationCompat.Builder mBuilder) { Intent resultIntent = new Intent(this, MainActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT ); mBuilder.setContentIntent(resultPendingIntent); }
Edición de seguimiento:
Uno de los comentarios a continuación mencionó que la respuesta puede ser "frágil", ya partir de la liberación de Android 4.3, el comportamiento detrás de startForeground
ha cambiado. StartForeground obligará a su aplicación a mostrar una notificación mientras está en primer plano, y el método sólo se debe llamar con la notificación para mostrar. No he probado, pero la respuesta aceptada ya no puede funcionar como estaba previsto.
En términos de detener el parpadeo cuando se llama stopForeground
, no creo que valga la pena luchar contra el marco para.
Hay alguna información adicional sobre el cambio de notificación de Android 4.3 aquí .
- Cómo se registra una aplicación de Android en el sistema operativo
- ¿Cómo dirigir la queja de la pelusa del android sobre las implementaciones exportadas del servicio de la mensajería de Firebase?
- Servicio de Android puede ser obligar sin iniciar?
- Listener de Internet Ejemplo de Android
- Servicio v / s AsyncTask
- Cómo ejecutar un servicio de arranque en Android 2.3 (Gingerbread) sin chocar
- Android proceso remoto: messenger vs aidl? ¿Cual es mejor?
- Enviar datos de la actividad al servicio en ejecución
Usted puede considerar el uso de un enfoque diferente.
Puesto que usted debe utilizar el servicio del primero plano para tal tarea (el jugar de los medios) le sugiero que usted continúe haciendo el start foreground()
, pero en vez de pasarle una notificación apenas fije la identificación 0 y la notificación null como esto startForeground(0, null);
.
De esta manera, el servicio de primer plano no mostrará ninguna notificación.
Ahora, para sus propósitos, puede utilizar notificaciones regulares y actualizar sus estados (en curso, diseño, texto, etc …), de esta manera no dependerá del comportamiento de notificación del servicio de primer plano.
Espero que esto ayude.
De acuerdo con documentos este comportamiento es por diseño antes de Lollipop
Las aplicaciones dirigidas a esta o una versión posterior obtendrán estos nuevos cambios de comportamiento:
…
- Llamar Service.stopForeground con removeNotification false modificará la notificación todavía publicada para que ya no se vea forzada a estar en curso.
En lugar de stopService(true)
, stopService(false)
conservará la notificación como está (sin estado en curso) a menos que sea descartada por el usuario / eliminada mediante programación o si el servicio se detiene. Por lo tanto, sólo llama a stopService (false) y notificación de actualización para mostrar el estado de pausa y ahora la notificación puede ser rechazada por el usuario. Esto también evita que parpadee ya que no estamos recreando la notificación.
- No se puede registrar la llamada usando MediaRecorder
- Android: ¿Por qué crear imágenes específicas para ldpi, mdpi y hdpi?