How do I update the notification text for a foreground service in Android?

后端 未结 5 1956
感情败类
感情败类 2020-12-02 06:25

I have a foreground service setup in Android. I would like to update the notification text. I am creating the service as shown below.

How can I update the notifica

相关标签:
5条回答
  • 2020-12-02 07:00

    Improving on Luca Manzo answer in android 8.0+ when updating the notification it will make sound and show as Heads-up.
    to prevent that you need to add setOnlyAlertOnce(true)

    so the code is:

    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);
    }
    
    0 讨论(0)
  • 2020-12-02 07:00

    here's the code to do so in your service. Create a new notification, but ask notification manager to notify the same notification id you used in startForeground.

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

    for full sample codes, you can check here:

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

    0 讨论(0)
  • 2020-12-02 07:06

    When you want to update a Notification set by startForeground(), simply build a new notication and then use NotificationManager to notify it.

    The key point is to use the same notification id.

    I didn't test the scenario of repeatedly calling startForeground() to update the Notification, but I think that using NotificationManager.notify would be better.

    Updating the Notification will NOT remove the Service from the foreground status (this can be done only by calling stopForground );

    Example:

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

    The documentation states

    To set up a notification so it can be updated, issue it with a notification ID by calling NotificationManager.notify(). To update this notification after you've issued it, update or create a NotificationCompat.Builder object, build a Notification object from it, and issue the Notification with the same ID you used previously. If the previous notification is still visible, the system updates it from the contents of the Notification object. If the previous notification has been dismissed, a new notification is created instead.

    0 讨论(0)
  • 2020-12-02 07:13

    I would think that calling startForeground() again with the same unique ID and a Notification with the new information would work, though I have not tried this scenario.

    Update: Based on the comments, you should use NotifcationManager to update the notification and your service continues to stay in the foreground mode. Take a look at the answer below.

    0 讨论(0)
  • 2020-12-02 07:24

    It seems none of the existing answers show how to handle the full case - to startForeground if it's the first call but update the notification for subsequent calls.

    You can use the following pattern to detect the right case:

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

    Additionally you need to build the notification and channel as in other answers:

    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);
    }
    
    0 讨论(0)
提交回复
热议问题