167 Stimmen

Wie aktualisiere ich den Benachrichtigungstext für einen Dienst im Vordergrund in Android?

Ich habe in Android einen Dienst im Vordergrund eingerichtet. Ich würde gerne den Benachrichtigungstext aktualisieren. Ich erstelle den Dienst wie unten gezeigt.

Wie kann ich den Benachrichtigungstext aktualisieren, der in diesem Vordergrunddienst eingerichtet ist? Was ist die beste Vorgehensweise für die Aktualisierung der Benachrichtigung? Für ein Codebeispiel wären wir dankbar.

public class NotificationService extends Service {

    private static final int ONGOING_NOTIFICATION = 1;

    private Notification notification;

    @Override
    public void onCreate() {
        super.onCreate();

        this.notification = new Notification(R.drawable.statusbar, getText(R.string.app_name), System.currentTimeMillis());
        Intent notificationIntent = new Intent(this, AbList.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        this.notification.setLatestEventInfo(this, getText(R.string.app_name), "Update This Text", pendingIntent);

        startForeground(ONGOING_NOTIFICATION, this.notification);

    }

Ich erstelle den Dienst in meiner Hauptaktivität wie unten gezeigt:

    // Start Notification Service
    Intent serviceIntent = new Intent(this, NotificationService.class);
    startService(serviceIntent);

279voto

Luca Manzo Punkte 3051

Wenn Sie eine durch startForeground() gesetzte Benachrichtigung aktualisieren möchten, erstellen Sie einfach eine neue Benachrichtigung und verwenden Sie dann NotificationManager, um sie zu benachrichtigen.

Wichtig ist, dass Sie dieselbe Melde-ID verwenden.

Ich habe das Szenario des wiederholten Aufrufs von startForeground() zur Aktualisierung der Benachrichtigung nicht getestet, aber ich denke, dass die Verwendung von NotificationManager.notify besser wäre.

Durch die Aktualisierung der Benachrichtigung wird der Dienst NICHT aus dem Vordergrundstatus entfernt (dies kann nur durch den Aufruf von stopForground geschehen);

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

En Dokumentation Staaten

Um eine Meldung so einzurichten, dass sie aktualisiert werden kann, geben Sie sie mit einer Benachrichtigungs-ID durch Aufruf von NotificationManager.notify() . Zur Aktualisierung diese Meldung zu aktualisieren, aktualisieren oder erstellen Sie eine NotificationCompat.Builder Objekt, erstellen Sie ein Notification Objekt von und geben die Notification mit der gleichen ID, die Sie zuvor verwendet haben. Wenn die vorherige Benachrichtigung noch sichtbar ist, aktualisiert das System sie mit dem Inhalt der Datei Notification Gegenstand. Wenn die vorherige Benachrichtigung verworfen wurde, wird stattdessen eine neue Benachrichtigung erstellt.

69voto

CommonsWare Punkte 950864

Ich würde denken, dass der Aufruf startForeground() wieder mit der gleichen eindeutigen ID und einer Notification mit den neuen Informationen funktionieren würde, obwohl ich dieses Szenario nicht ausprobiert habe.

Update: Ausgehend von den Kommentaren sollten Sie NotifcationManager verwenden, um die Benachrichtigung zu aktualisieren, und Ihr Dienst bleibt weiterhin im Vordergrundmodus. Werfen Sie einen Blick auf die Antwort unten.

33voto

humazed Punkte 70855

Verbesserung der Antwort von Luca Manzo in Android 8.0+, wenn die Benachrichtigung aktualisiert wird, ertönt ein Ton und es wird ein Heads-up angezeigt.
Um dies zu verhindern, müssen Sie Folgendes hinzufügen setOnlyAlertOnce(true)

Der Code lautet also:

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){
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
        ((NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(
        NotificationChannel("timer_notification","Timer Notification",NotificationManager.IMPORTANCE_HIGH))
}

        // The PendingIntent to launch our activity if the user selects
        // this notification
        PendingIntent contentIntent=PendingIntent.getActivity(this,
        0,new Intent(this,MyActivity.class),0);

        return new NotificationCompat.Builder(this,"my_channel_01")
        .setContentTitle("some title")
        .setContentText(text)
        .setOnlyAlertOnce(true) // so when data is updated don't make sound and alert in android 8.0+
        .setOngoing(true)
        .setSmallIcon(R.drawable.ic_launcher_b3)
        .setContentIntent(contentIntent)
        .build();
}

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

6voto

Daniel Kao Punkte 345

Hier ist der entsprechende Code zu Ihren Diensten . Erstellen Sie eine neue Benachrichtigung, aber bitten Sie den Benachrichtigungsmanager, die gleiche Benachrichtigungs-ID zu benachrichtigen, die Sie in startForeground verwendet haben.

Notification notify = createNotification();
final NotificationManager notificationManager = (NotificationManager) getApplicationContext()
    .getSystemService(getApplicationContext().NOTIFICATION_SERVICE);

notificationManager.notify(ONGOING_NOTIFICATION, notify);

Die vollständigen Beispielcodes finden Sie hier:

https://github.com/plateaukao/AutoScreenOnOff/blob/master/src/com/danielkao/autoscreenonoff/SensorMonitorService.java

6voto

Nick Cardoso Punkte 20040

Es scheint, dass keine der vorhandenen Antworten zeigt, wie man den vollen Fall behandelt - startForeground, wenn es der erste Aufruf ist, aber die Benachrichtigung für nachfolgende Aufrufe zu aktualisieren.

Sie können das folgende Muster verwenden, um den richtigen Fall zu erkennen:

private void notify(@NonNull String action) {
    boolean isForegroundNotificationVisible = false;
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    StatusBarNotification[] notifications = notificationManager.getActiveNotifications();
    for (StatusBarNotification notification : notifications) {
        if (notification.getId() == FOREGROUND_NOTE_ID) {
            isForegroundNotificationVisible = true;
            break;
        }
    }
    Log.v(getClass().getSimpleName(), "Is foreground visible: " + isForegroundNotificationVisible);
    if (isForegroundNotificationVisible){
        notificationManager.notify(FOREGROUND_NOTE_ID, buildForegroundNotification(action));
    } else {
        startForeground(FOREGROUND_NOTE_ID, buildForegroundNotification(action));
    }
}

Zusätzlich müssen Sie die Benachrichtigung und den Kanal wie in anderen Antworten erstellen:

private Notification buildForegroundNotification(@NonNull String action) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        createNotificationChannel();
    }
    //Do any customization you want here
    String title;
    if (ACTION_STOP.equals(action)) {
        title = getString(R.string.fg_notitifcation_title_stopping);
    } else {
        title = getString(R.string.fg_notitifcation_title_starting);
    }
    //then build the notification
    return new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(title)
            .setOngoing(true)
            .build();
}

@RequiresApi(Build.VERSION_CODES.O)
private void createNotificationChannel(){
    NotificationChannel chan = new NotificationChannel(CHANNEL_ID, getString(R.string.fg_notification_channel), NotificationManager.IMPORTANCE_DEFAULT);
    chan.setLightColor(Color.RED);
    chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    assert manager != null;
    manager.createNotificationChannel(chan);
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X