从onDestroy()调用stopForeground(true)不能移除通知。

14
我想在前台服务被销毁后删除通知。我尝试从 onDestroy()unbind() 调用stopForeground(true)。尽管 onUnbind() 和 onDestroy() 已被调用(我可以从日志中看到),但通知仍然存在。我通过从活动中调用 unbindService(playerConnection)stopService(this) 来停止服务。
为什么这种方法不起作用?有没有办法在销毁服务时删除通知?
更新:当我玩弄通知时,我注意到了一件有趣的事情:
fun hideNotification() {
    stopForeground(true)
    Log.d("PlayerService", "hideNotification")
}

当我按下按钮时,我会从我的活动中调用它。然后它会移除通知。但是当相同的函数从活动的onStop()或服务的onUnbind()或onDestroy()中调用时,它不起作用。我无法理解这些情况之间的区别。


你解决了吗? 我似乎遇到了同样的问题。 - Klitos G.
你尝试过在不同的安卓操作系统版本上运行吗? - KenIchi
3个回答

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
        }

一些参考资料:
如何删除旧的通知渠道?
停止前台运行服务的正确方式是什么?


通知渠道的创建在API级别26或更高版本之后,但即使在此之前,通知也不会被删除。 - juztcode

1
经过数小时的调试,我发现两个服务之间的区别在于一个服务移除了通知,而另一个没有。唯一的不同之处在于其中一个服务将Android属性设置为false。
 <service
        ...
        ...
        android:exported="false">

我不知道为什么将导出设置为false可以使我删除通知,但我想分享这个解决方案。

我仍然无法使用android:exported="true"使其正常工作,但我发现以下内容:1- 这种情况发生在三星设备上,其他设备(如Google Pixel)可以正常工作。 2- 在调用stopForeground(true)后,通知会被正确地删除,但是立即创建另一个通知。 - Victor

-4

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

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

例如:ID = 210;

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

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

希望这可以帮助您。


1
谢谢您的评论,但它并没有起作用。我使用startForeground(NOTIFICATION_ID,notification)调用启动通知。因此,它应该通过stopForeground(true)调用被解除。此外,如果我在onDestroy之前从单独的方法中调用stopForeground,它确实可以工作。请参见更新。 - AlexKost

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接