【问题标题】:Does updating a Notification remove a Service's foreground status?更新通知会删除服务的前台状态吗?
【发布时间】:2012-01-07 13:30:36
【问题描述】:

在我的应用程序中,我将我的服务放在前台,以防止它被杀死:

startForeground(NOTIFY_ID, notification);

这也会向用户显示通知(这很棒)。问题是稍后我需要更新通知。所以我使用代码:

notification.setLatestEventInfo(getApplicationContext(), someString, someOtherString, contentIntent);
mNotificationManager.notify(NOTIFY_ID, notification);

那么问题是:这样做会不会让服务脱离它的特殊前台状态?

this answerCommonsWare 表示这种行为是可能的,但他不确定。那么有人知道实际答案吗?


注意:我知道摆脱这个问题的一个简单方法是每次我想更新通知时重复调用startForeground()。我想知道这个替代方案是否也有效。

【问题讨论】:

  • 顺便说一句,虽然您可以更新现有通知的文本,但对于给定的通知,您不能让代码文本多次出现在状态栏中,即使您更改了它——在至少不使用 Notification.FLAG_ONGOING_EVENT。要为现有通知显示新的代码文本,您需要取消通知然后重新启动它。

标签: android android-service android-notifications


【解决方案1】:

澄清这里所说的:

据我了解,如果您取消通知服务 将不再是前台服务,因此请记住这一点;如果你 取消通知,您需要再次调用 startForeground() 恢复服务的前台状态。

这部分答案表明可以通过在持久性Notification 上使用NotificationManager.cancel() 来删除由Service 设置的正在进行的Notification。 这不是真的。 使用NotificationManager.cancel() 无法删除startForeground() 设置的持续通知。

删除它的唯一方法是调用stopForeground(true),因此正在进行的通知被删除,这当然也使Service 停止在前台。所以实际上是相反的; Service 不会停止在前台,因为 Notification 已取消,Notification 只能通过停止 Service 在前台来取消。

当然可以在此之后立即调用startForeground(),以使用新的Notification 恢复状态。如果必须再次显示代码文本,您希望这样做的一个原因是,它只会在第一次显示 Notification 时运行。

没有记录此行为,我浪费了 4 个小时试图弄清楚为什么我无法删除 Notification。 更多关于这里的问题:NotificationManager.cancel() doesn't work for me

【讨论】:

    【解决方案2】:

    Android 开发者网站上的RandomMusicPlayer(archived) 应用程序使用 NotificationManager 来更新前台服务的通知,因此它很有可能保留前台状态。

    (参见 MusicService.java 类中的 setUpAsForeground()updateNotification()。)

    据我了解,如果您取消通知,该服务将不再是前台服务,因此请记住这一点;如果取消通知,则需要再次调用 startForeground() 来恢复服务的前台状态。

    【讨论】:

    • 链接已损坏,我猜是谷歌删除了那个样本
    • @kudroid 我找到了源的存档版本,请参阅:android.googlesource.com/platform/development/+/…
    • 谢谢@Lorne,我确实试过了,更新后,通知仍然表现得像一个新服务正在启动(带有声音和抬头)。有没有办法让我们静默更新内容?
    【解决方案3】:

    当您想更新由 startForeground() 设置的通知时,只需构建一个新通知,然后使用 NotificationManager 通知它。

    关键点是使用相同的通知ID。

    更新通知不会将服务从前台状态中移除(这只能通过调用 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      相关资源
      最近更新 更多