android - 服务被系统自动杀死时取消Android通知

标签 android android-notifications android-mediasession

我有一个实现 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

服务上没有任何明显的 Hook (例如 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 属性。这是分离调用的产物。我们选择在很久以前的某个时候这样做是为了避免通知被系统收集。经过反射(reflection),我们应该允许它像其他应用程序一样被终止。

关于android - 服务被系统自动杀死时取消Android通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55191295/

相关文章:

android - 在android中使用opencv捕获视频帧

android - 如何从移动 webview 元素中删除 Activity 状态

android - 在自定义通知中添加按钮操作

Android:关于 MediaSessionManager 和 RemoteController 我不清楚的地方

android - 如何创建订单?

android - 在不连接计算机的情况下检查 Android 上的元素

android - 在 singleTask Activity 的 onCreate() 中使用旧的额外内容

java - 警报通知未出现

java - MediaControllerCompat 内存泄漏

android-service - 如何从 Activity 调用 mediaBrowserService 中的 getDuration?