web-dev-qa-db-fra.com

Mettre à jour le texte de la notification, pas la notification entière

Prélude

J'essaie d'ajouter un chronomètre sur la notification. Le chronomètre est un service. Chaque seconde, cette ligne est appelée (continuer Thread est un booléen "en cours d'exécution", timeString est la chaîne élaborée indiquant l'heure):

NotificationChrono.updateNotification(getApplicationContext(), continueThread, 
NOTIF_ID, timeString, "Chronometer", notificationManager);

Voici la classe NotificationChrono:

public class NotificationChrono {

    static public void updateNotification(Context context, boolean running,
        int id, String title, String text,
        NotificationManager notificationManager) {

        Intent stopIntent = new Intent("com.corsalini.david.barcalc.STOP");
        PendingIntent stopPendingIntent = PendingIntent.getBroadcast(context,
            0, stopIntent, 0);

    Intent startIntent = new Intent(
            "com.corsalini.david.barcalc.STARTPAUSE");
    PendingIntent startPendingIntent = PendingIntent.getBroadcast(context,
            0, startIntent, 0);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(
            context)

            .setContentText(context.getString(R.string.notif_text))

            .setContentTitle(title)

            .setSmallIcon(R.drawable.ic_action_alarm_2)

            .setAutoCancel(false)

            .setOngoing(running)

            .setOnlyAlertOnce(true)

            .setContentIntent(
                    PendingIntent.getActivity(context, 10, new Intent(
                            context, FrontActivity.class)
                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP), 0))
            .addAction(
                    running ? R.drawable.ic_action_pause
                            : R.drawable.ic_action_play,
                    running ? context.getString(R.string.pause) : context
                            .getString(R.string.start), startPendingIntent)
            .addAction(R.drawable.ic_action_stop,
                    context.getString(R.string.stop), stopPendingIntent);

    notificationManager.notify(id, builder.build());
}
}

Problème

Chaque seconde, la notification est supprimée et recréée, cela signifie visuellement que chaque seconde la notification disparaît et réapparaît dans la liste des notifications.

Ce que je voudrais, c'est simplement mettre à jour le texte TITLE, sans recréer la notification entièrement toutes les secondes. C'est possible?

44
David Corsalini

Assurez-vous d'utiliser le même générateur NotificationCompat.Builder À chaque fois pour créer le Notification!

Bien que la première fois que vous devez tout définir, la deuxième fois en utilisant le Builder, vous n'avez qu'à définir la ou les valeurs que vous souhaitez mettre à jour. Après cela, il appelle notificationManager.notify(id, builder.build()) comme vous l'avez fait. Si vous utilisez le même ID, la notification est mise à jour (important!).

Exemple:

//First time
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
            .setContentText(context.getString(R.string.notif_text))
            .setContentTitle(title)
            .setSmallIcon(R.drawable.ic_action_alarm_2)
            .setAutoCancel(false)
            .setOngoing(running)
            .setOnlyAlertOnce(true)
            .setContentIntent(
                    PendingIntent.getActivity(context, 10, 
                            new Intent(context, FrontActivity.class)                                 
                            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP),
                    0)
            )
            .addAction(running ? R.drawable.ic_action_pause 
                               : R.drawable.ic_action_play,
                       running ? context.getString(R.string.pause)
                               : context.getString(R.string.start),
                       startPendingIntent)
            .addAction(R.drawable.ic_action_stop, context.getString(R.string.stop),
                    stopPendingIntent);

notificationManager.notify(id, builder.build());

//Second time
builder.setContentTitle(title);
notificationManager.notify(id, builder.build());

Mais vous pouvez également utiliser la méthode setUsesChronometer de la classe NotificationCompat. Cela affiche automatiquement un chronomètre en utilisant l'horodatage donné (capable de définir avec setWhen ).

96
PieterAelse

Merci pour l'idée PieterAelse!

Dans mon cas, je devais y aller (créer une nouvelle notification) pour la deuxième fois et les suivantes:

        builder.setContentText(getConvertedTime(millisUntilFinished));
        Notification notification = builder.getNotification();
        notification.flags = Notification.FLAG_ONGOING_EVENT;            
        nm.notify(R.string.app_name,notification);

J'espère que ça aide.

4
daros