web-dev-qa-db-de.com

Aktualisierung des Benachrichtigungstextes, nicht der gesamten Benachrichtigung

Auftakt

Ich versuche, der Benachrichtigung einen Chronometer hinzuzufügen. Der Chronometer ist eine Dienstleistung. Jede Sekunde wird diese Zeile aufgerufen (continue Thread ist ein "laufender" Boolescher Wert, timeString ist der ausgearbeitete String, der die Zeit anzeigt):

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

Dies ist die NotificationChrono-Klasse:

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

Problem

Jede Sekunde wird die Benachrichtigung gelöscht und neu erstellt. Visuell bedeutet dies, dass jede Sekunde die Benachrichtigung verschwindet und erneut in der Benachrichtigungsliste angezeigt wird.

Ich möchte nur den TITLE-Text aktualisieren und die Benachrichtigung nicht jede Sekunde neu erstellen. Ist es möglich?

44
David Corsalini

Stellen Sie sicher, dass Sie jedes Mal denselben Builder NotificationCompat.Builder Zum Erstellen des Notification verwenden!

Obwohl Sie beim ersten Mal alles einstellen müssen, müssen Sie beim zweiten Mal mit Builder nur die Werte einstellen, die Sie aktualisieren möchten. Danach ruft es notificationManager.notify(id, builder.build()) auf, so wie Sie es getan haben. Wenn Sie dasselbe ID verwenden, wird die Benachrichtigung aktualisiert (wichtig!).

Beispiel:

//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());

Sie können aber auch die Methode setUsesChronometer der Klasse NotificationCompat verwenden. Dies zeigt automatisch einen Chronometer mit dem angegebenen Zeitstempel an (einstellbar mit setWhen ).

96
PieterAelse

Danke für die Idee PieterAelse!

In meinem Fall musste ich dies zum zweiten und folgenden Mal tun (eine neue Benachrichtigung erstellen):

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

Ich hoffe es hilft.

4
daros