当服务自动被系统杀死时,取消Android通知



我有一个实现MediaBrowserServiceCompat的应用程序。播放音乐时,它会在前景中运行,并发出媒体控制通知,该通知表明该系统可使其不可抗解。暂停时,它从前景中出来,并保留了通知。标准内容。

当该服务自动被系统杀死时,未删除通知。

您可以通过将应用程序放置在非前处暂停状态,离开应用程序并发出此命令来模拟此命令:

adb shell am kill com.myapp.package

该通知仍然存在。您会收到此logcat消息:

W/ActivityManager: Scheduling restart of crashed service com.myapp.package/com.myapp.package.playback.platform.AndroidMediaService

该服务上没有一个明显的钩子(例如onDestroyonTaskRemoved等)被称为 - 似乎是完全被杀死的。因为该服务是从START_NOT_STICKY开始的,所以我们也不会在新实例上调用onCreate

部分解决方案是使服务粘稠,并在服务恢复时取消通知。但是,这可能需要大量时间实际发生,在此期间通知不起作用,因此并不理想。它也可能会产生进一步的后果。

其他应用似乎没有问题。

重复此情况(暂停,离开应用程序)并执行命令,例如在Google Play音乐上:

adb shell am kill com.google.android.music

或Spotify:

adb shell am kill com.spotify.music

,您发现它们的通知立即消失,好像它们在拆除时被取消一样。

他们可能会做什么来实现这一目标?

我已经找到了答案,当然,这是我自己的错。其他应用程序没有什么特别的 - 这是一种平台行为,我们是离群的。

我迟来地发现,从前景过渡到背景时,我们打电话给:

ServiceCompat.stopForeground(service, ServiceCompat.STOP_FOREGROUND_DETACH)

我通过dumpsys发现了这一点,例如:

adb shell dumpsys activity services com.google.android.music

我发现了一些差异。

我的应用程序:

ServiceRecord{294309d u0 com.myapp.debug/com.myapp.playback.platform.AndroidMediaService}
    intent={cmp=com.myapp.debug/com.myapp.playback.platform.AndroidMediaService}
    packageName=com.myapp.debug
    processName=com.myapp.debug:main
    baseDir=/data/app/com.myapp.debug-GM-nBaeXA_e47EmJKnM27g==/base.apk
    dataDir=/data/user/0/com.myapp.debug
    app=ProcessRecord{83fb4ffd0 23567:com.myapp.debug:main/u0a381}
    createTime=-27s211ms startingBgTimeout=--
    lastActivity=-26s911ms restartTime=-27s211ms createdFromFg=true
    startRequested=true delayedStop=false stopIfKilled=true callStart=true lastStartId=2

播放音乐:

ServiceRecord{8693ccb u0 com.google.android.music/.playback2.MusicPlaybackService}
    intent={cmp=com.google.android.music/.playback2.MusicPlaybackService}
    packageName=com.google.android.music
    processName=com.google.android.music:main
    baseDir=/data/app/com.google.android.music-lrn1VQr_3_RDi5PMbqozdw==/base.apk
    dataDir=/data/user/0/com.google.android.music
    app=ProcessRecord{9a3c417d0 22921:com.google.android.music:main/u0a191}
    isForeground=false foregroundId=1 foregroundNoti=Notification(channel=playback_v1 pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x2 color=0xffff5722 category=transport actions=5 vis=PUBLIC semFlags=0x0 semPriority=0 semMissedCount=0)
    createTime=-9m33s792ms startingBgTimeout=--
    lastActivity=-20s825ms restartTime=-9m33s792ms createdFromFg=true
    startRequested=true delayedStop=false stopIfKilled=false callStart=true lastStartId=1

您可以在我的应用程序日志中看到缺少的foregroundNoti属性。这是分离电话的产物。我们选择在很久以前的某个时候这样做,以避免系统收集的通知。在反思中,我们应该像其他应用程序一样允许它被杀死。

尝试在清单中添加此标志以在杀死应用程序时停止服务:

<service
    ...
    android:stopWithTask="true"/>

如果它没有删除通知,则将其设置为false应触发服务中的回调,您应该在其中删除通知

@Override 
public void onTaskRemoved(Intent rootIntent) {
    ...
}

另外,此答案可能是相关的。

更新

由于上述不起作用,所以我研究了本机上如何在清单中声明本机音乐应用程序,但他们不使用我的建议。他们使用的是什么,可能是

<service
   ...
   android:process=":main" />

在所有服务以及更改通知的接收器中。值得尝试。

您应该将通知的优先级设置为" low" ,在服务销毁方法中,您可以通过以下代码手动删除通知,

 notificationManager.cancelAll();

最新更新