Как обновить текст уведомления для службы переднего плана в Android?

У меня есть настройка переднего плана в Android. Я хотел бы обновить текст уведомления. Я создаю службу, как показано ниже.

Как обновить текст уведомления, который настроен в этой службе переднего плана? Какова наилучшая практика для обновления уведомления? Любой образец кода будет оценен.

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

    }

Я создаю службу в своем основном действии, как показано ниже:

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

Ответ 1

Я думаю, что startForeground() вызов startForeground() с тем же уникальным идентификатором и Notification с новой информацией будет работать, хотя я не пробовал этот сценарий.

Обновление: на основе комментариев вы должны использовать NotifcationManager для обновления уведомлений, и ваша служба продолжает оставаться в режиме переднего плана. Посмотрите на ответ ниже.

Ответ 2

Если вы хотите обновить набор уведомлений с помощью startForeground(), просто создайте новое уведомление, а затем используйте NotificationManager для его уведомления.

Ключевым моментом является использование того же идентификатора уведомления.

Я не тестировал сценарий многократного вызова startForeground() для обновления Notification, но я думаю, что лучше использовать NotificationManager.notify.

Обновление Уведомления НЕ удалит Сервис из статуса переднего плана (это можно сделать только путем вызова stopForground);

Пример:

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

Документация гласит

Чтобы настроить уведомление, чтобы его можно было обновить, введите его с идентификатором уведомления, вызвав NotificationManager.notify(). Чтобы обновить это уведомление после его выдачи, обновите или создайте объект NotificationCompat.Builder, создайте из него объект Notification и выполните Notification с тем же идентификатором, который вы использовали ранее. Если предыдущее уведомление все еще отображается, система обновляет его из содержимого объекта Notification. Если предыдущее уведомление было отклонено, вместо него создается новое уведомление.

Ответ 3

Улучшение ответа Luca Manzo в android 8. 0+ при обновлении уведомления оно будет звучать и показываться как Heads-up.
чтобы предотвратить это вам нужно добавить setOnlyAlertOnce(true)

так что код:

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

Ответ 4

вот код для в вашем сервисе. Создайте новое уведомление, но попросите менеджера уведомлений уведомить тот же идентификатор уведомления, который вы использовали в startForeground.

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

notificationManager.notify(ONGOING_NOTIFICATION, notify);

для полных образцов кода, вы можете проверить здесь:

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