web-dev-qa-db-ja.com

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

このシナリオを試したことはありませんが、同じ一意のIDでstartForeground()を再度呼び出し、新しい情報でNotificationを呼び出すとうまくいくと思います。

更新:コメントに基づいて、NotifcationManagerを使用して通知を更新する必要があります。サービスは引き続きフォアグラウンドモードのままです。以下の答えをご覧ください。

52
CommonsWare

StartForeground()によって設定された通知を更新する場合は、新しい通知を作成し、NotificationManagerを使用して通知します。

重要な点は、同じ通知IDを使用することです。

StartForeground()を繰り返し呼び出して通知を更新するシナリオはテストしませんでしたが、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()を呼び出して通知IDを発行します。この通知を発行した後に更新するには、_NotificationCompat.Builder_オブジェクトを更新または作成し、そこからNotificationオブジェクトを作成し、以前に使用したのと同じIDでNotificationを発行します。前の通知がまだ表示されている場合、システムはNotificationオブジェクトのコンテンツからそれを更新します。以前の通知が却下された場合、代わりに新しい通知が作成されます。

193
Luca Manzo

Android 8.0+でLuca Manzoの回答を改善すると、通知を更新すると音が鳴り、ヘッドアップとして表示されます。
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);
}
15
humazed

これを行うコードは、サービスでです。新しい通知を作成しますが、startForegroundで使用したのと同じ通知IDを通知するよう通知マネージャーに依頼します。

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

4
Daniel Kao