【问题标题】:stopForeground(true) called from onDestroy() doesn't remove a notification从 onDestroy() 调用的 stopForeground(true) 不会删除通知
【发布时间】:2017-09-25 23:13:49
【问题描述】:

我想在我的前台服务被销毁后删除通知。我尝试从onDestroy()unbind() 拨打stopForeground(true)。虽然 onUnbind() 和 onDestroy() 被调用(我可以从日志中看到)通知仍然存在。我通过在我的活动中调用 unbindService(playerConnection)stopService(this) 来停止服务。

为什么它不能这样工作?关于如何在服务被销毁时删除通知的任何想法?

UPATE:我在玩通知时注意到了一件有趣的事情。我在服务内部做了一个特殊的方法:

fun hideNotification() {
    stopForeground(true)
    Log.d("PlayerService", "hideNotification")
}

当我按下按钮时,我从我的活动中调用它。它会删除通知。但是从活动的 onStop() 或服务的 onUnbind() 或 onDestroy() 调用相同的函数却没有。我不明白这些情况之间有什么区别。

【问题讨论】:

  • 您解决了吗?我好像遇到了同样的问题
  • 你在不同的安卓操作系统版本上试过这个吗?

标签: android


【解决方案1】:

在两个服务之间进行了数小时的调试后,一个删除了通知,另一个没有,我发现它们之间的唯一区别是其中一个将 android 属性导出为 false。

 <service
        ...
        ...
        android:exported="false">

我忽略了设置导出为 false 使我能够删除通知但我想分享此解决方案的原因

【讨论】:

  • 为我工作!谢谢
【解决方案2】:

我在尝试停止前台服务并删除它的所有通知时遇到了同样的问题。

作为一种解决方法,我删除通知通道并在需要时重新创建它。

解决这个问题的方法如下:

  1. 在 onStartCommand() 中(或服务中的其他位置)停止服务。
  2. StopForeground(true)
  3. 删除通知通道(这实际上清除了所有通知)。

例子:

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        var stopService : Boolean  # Service stop condition
        var isRunning : Boolean  # stopSelf() raise exception if service is not running.
        if (stopService}){
            stopForeground(true)
            notificationManager.deleteNotificationChannel("channel_id");
            if (isRunning){
                Log.d(TAG, "Service is running, stopping.")
                stopSelf()
            }else
                Log.d(TAG, "Service is not running, no need to stop.")
            return START_NOT_STICKY
        }

一些参考资料:
How to remove old notification channels?
What is the proper way to stop a service running as foreground

【讨论】:

  • 通知通道的创建在 API 级别 26 之后或等于 26 级之后,但在此之前通知不会被删除
【解决方案3】:

要删除通知,您必须使用 notificationManager.cancel(ID);在 onDestry() 或您想删除通知时。

ID:用于显示通知的ID,需要在cancel()中给出相同的ID

例如: ID = 210;

notificationManager.notify(ID, 通知); ==> 用于显示通知。

notificationManager.cancel(ID) ===> 用于删除通知。

希望对你有所帮助。

【讨论】:

  • 感谢您的评论,但它不起作用。我通过 startForeground(NOTIFICATION_ID, notification) 调用开始通知。所以它应该被 stopForeground(true) 调用解散。此外,如果我在 onDestroy 之前从单独的方法调用它,stopForeground 确实有效。查看更新。
猜你喜欢
  • 2019-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多