Cómo manejar correctamente startForegrounds dos notificaciones

Tengo un IntentService que carga un archivo. Todo funciona bien, pero estoy un poco confundido sobre cómo manejar las notificaciones. Cuando comienzo la notificación utilizo startForeground() porque los archivos pueden ser bastante grandes y no quiero que se cargue la carga a menos que sea absolutamente necesario. Cuando utilizo startForeground() muestra dos notificaciones en el área de notificación (una en Ongoing y otra en Notifications):

Ejemplo:

He leído a través de una serie de diferentes puestos de pila de desbordamiento y artículos web, pero ninguno de ellos responde a la pregunta que tengo … espero que no he perdido uno que habla de ths.

Es mi entendimiento que la notificación en curso en la imagen de arriba (aquél sin la barra de progreso) se pone puesto que esto está funcionando en el primero plano ( documentación de los servicios ). Eso está bien si me preguntas, y entiendo por qué. Sin embargo, no necesito dos notificaciones exhibidas y estoy bastante seguro que la mayoría de la gente no desearía dos notificaciones que atestan encima del área de la notificación tampoco. Me gustaría saber cómo manejar adecuadamente la notificación para que sólo una muestra y no desorden el área de notificación.

La única manera que he podido conseguir alrededor de esto es si startForeground (int id, Notification notification) el entero ID para el startForeground (int id, Notification notification) ( ONGOING_NOTIFICATION_ID en mi código abajo) a cero. Sin embargo, la documentación que cito arriba dice:

Caution: The integer ID you give to startForeground() must not be 0

Si se establece en 0 se deshabilita la notificación En curso y luego se muestra la notificación regular con la barra de progreso. Creo que podría "arreglar" esto estableciendo .setOngoing(true) hasta que .setOngoing(true) de cargar el archivo y luego establecer .setOngoing(false) una vez que haya terminado, por lo que se puede descartar. No estoy seguro exactamente cómo "prudente" uno tiene que ser con la fijación de la identificación entera a 0. Para mí que una cierta clase de parece una manera perezosa de poder conseguir alrededor del problema que estoy teniendo, pero no lo hago Saber si hay otras consecuencias para establecerlo en 0. También, esto sólo funciona si sólo tengo una notificación que estoy tratando. Si tengo varias notificaciones diferentes, necesitaré diferentes identificaciones para cada una y esto no funcionará. Actualización : Parece que la configuración de la ID a 0 no funcionará en Android 4.3 , así que ahora estoy de vuelta a la primera plaza.

¿Qué es una forma válida de desplazarse mostrando ambas notificaciones?

Duh, tomando un tiempo libre y luego volviendo a esto y comprobando lo que había hecho sobre la base de la recomendación de @dsandler me ayudó a averiguar lo que estaba haciendo mal. No estaba configurando el ID correcto cuando estaba haciendo la actualización de progreso, por lo que se creaba dos notificaciones y una no se actualizaba. Utilizar el mismo ID (ONGOING_NOTIFICATION_ID) para todas las notificaciones resolvió el problema para mí. Vea el código abajo para las piezas adicionales que no había incluido antes y donde había cometido el error.

Código relevante de UploadFile.java:

 public class UploadFile extends IntentService { private static final int ONGOING_NOTIFICATION_ID = 1; @Override protected void onHandleIntent(Intent intent) { mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mBuilder = new NotificationCompat.Builder(this); mBuilder.setContentTitle(getText(R.string.upload)) .setContentText("0% " + getText(R.string.upload_in_progress)) .setSmallIcon(android.R.drawable.stat_sys_upload); startForeground(ONGOING_NOTIFICATION_ID, mBuilder.build()); .... if (progress > 0){ percent = (Long.valueOf(progress) * 100) / totalSize; mBuilder.setProgress(100, percent.intValue(), false); mBuilder.setContentText(percent.intValue() + "% " + getText(R.string.upload_in_progress)); mNotifyManager.notify(ONGOING_NOTIFICATION_ID, mBuilder.build()); // <-- My problem was that I had set the ID here to 0 and did not make it the same as the ID I set above } .... } 

En primer lugar, a juzgar por su descripción, usted podría ser capaz de salirse con un servicio regular, reconociendo que el asesino fuera de la memoria no vendrá a llamar a menos que las cosas están recibiendo dire en el dispositivo y su servicio ha sido realmente ejecutando un mucho tiempo.

Dicho esto, si usted debe hacer el primer plano de servicio, la estrategia típica aquí es mostrar su progreso utilizando la Notificación que utilizó cuando puso su servicio en el estado de primer plano. Mediante NotificationManager.notify puede publicar tantas actualizaciones de esa notificación como desee, incluyendo ajustes a las barras de progreso a través de Notification.Builder.setProgress , por ejemplo.

De esta manera sólo muestra una notificación al usuario, y es la requerida por startForeground .

Cuando desee actualizar un conjunto de notificaciones por startForeground (), simplemente cree una nueva notificación y luego use NotificationManager para notificarlo.

El punto clave es usar el mismo id de notificación.

No probé el escenario de llamar repetidamente a startForeground () para actualizar la Notificación, pero creo que usar NotificationManager.notify sería mejor.

Actualizar la Notificación NO eliminará el Servicio del estado de primer plano (esto se puede hacer solamente llamando a stopForground);

Ejemplo:

 private static final int notif_id=1; @Override public void onCreate (){ this.startForeground(); } private void startForeground() { startForeground(notif_id, getMyActivityNotification("")); } private Notification getMyActivityNotification(String text){ // The PendingIntent to launch our activity if the user selects // this notification CharSequence title = getText(R.string.title_activity); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MyActivity.class), 0); return new Notification.Builder(this) .setContentTitle(title) .setContentText(text) .setSmallIcon(R.drawable.ic_launcher_b3) .setContentIntent(contentIntent).getNotification(); } /** this is the method that can be called to update the Notification */ private void updateNotification() { String text = "Some text that will update the notification"; Notification notification = getMyActivityNotification(text); NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(notif_id, notification); } 
  • Error en la conexión de Google Analytics con Google para el servicio
  • Android: Transmisión de datos entre servicio y actividad
  • ¿Por qué utilizar un servicio Android?
  • La mejor manera de enviar actualizaciones de ubicación de usuario al servidor en segundo plano (Android)
  • Cómo evitar que el servicio se ejecute de nuevo si ya está ejecutando android
  • ¿Es posible crear el widget como Google Play Música en la pantalla de bloqueo?
  • ¿Cómo usar loopJ SyncHttpClient para llamadas sincrónicas?
  • Android geofencing cuando se mata la aplicación
  • Paho MQTT Actividad de activación del servicio de Android
  • Cómo enviar el mensaje del servicio a la actividad
  • Cómo forzar el onServiceDisconnected () obtener llamado?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.