当服务被终止时,销毁前台通知

5

我有一个前台服务来下载一些网络内容。

不幸的是,由于一个错误 在这里报告 ,当接收器在我的服务内部接收广播时,我的服务被杀死了,但它的通知不会被杀死,我在我的logcat中看到了以下日志:

I/ActivityManager(449): Killing 11073:my-package-name/u0a102 (adj 0): remove task

当父服务被操作系统杀死时,是否有任何方法可以销毁前台通知?


1
你尝试在onTaskRemoved()内调用stopForground(true)了吗? - Nikola Despotoski
@NikolaDespotoski 这不是一个适合前台服务的好方法。 - Ali
6个回答

1

服务结束后移除前台通知。

@Override
public void onDestroy() {
    // mycleanup first
    stopForeground(true);
    super.onDestroy();
}

1
使用 stopForeground:
@Override
public void onDestroy() {
 // as the bug seems to exists for android 4.4
 if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.KITKAT)
 {
    stopForeground(true);
 }
  super.onDestroy();
}

or

public void onTaskRemoved (Intent rootIntent)
{
 // as the bug seems to exists for android 4.4
 if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.KITKAT)
 {
   stopForeground(true);
 }
}

1

在通知中,定期检查服务是否仍在运行(例如使用下面的代码:Handler):

public static boolean isMyServiceRunning(Context context) {
    ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))                           {
        if (MyService.class.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

如果不是,就关闭通知。
private static final int DEALY = 10000;
private Handler handler = new Handler();

...
handler.postDelayed(ensureSericeIsRunning, DELAY);
...

private Runnable ensureSericeIsRunning = new Runnable() {

    @Override
    public void run() {
        if (!isMyServiceRunning(getActivity())){
            //shut down notification
        } else {
            handler.postDelayed(ensureSericeIsRunning, DELAY);
        }
    }
};

很好的建议,但请注意,每当服务被操作系统终止时,所有其他引用也将被删除! - Ali
什么意思?通知还不能通过通知管理器取消吗? - bgplaya
我相信这就是你需要的:当服务被杀死后,下一次调用isMyServiceRunning将返回false,然后你可以取消通知。你能否澄清一下问题在哪里? - bgplaya

0
你可以在服务类中的 onStoponDestroy 中移除通知。但请注意,这并不能保证一定有效。在 API 14 及以上版本中,即使没有前台通知,服务仍然可能在运行。你可以返回 START_STICKY,这将使系统在销毁服务后重新启动它。
 @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}

不行,这在我的情况下不起作用,即使是START_STICKY也无法在KitKat中重新启动服务!!! - Ali
你能分享一下你用的手机型号以及你是使用原厂 ROM 还是自定义 ROM 吗? - Kosh
是的,这是装有AOSP KitKat ROM的Nexus 5,请也查看此链接https://dev59.com/n2Ij5IYBdhLWcg3wGRiM#20681898。 - Ali
我没有在使用 Galaxy S5 刷机的官方 ROM 时遇到那个 bug。两天前我还在使用 CM11,相信我,在 AOSP 上开发并不是一个好主意。我的最后一个自由职业应用程序有很多问题,而在 CM11 上运行时更是如此。尝试恢复到官方 ROM 并进行测试,你会发现在官方 ROM 和 AOSP 上运行之间存在很多差异。 - Kosh

0

使用onDestroy()方法。尽管文档中说它不能保证被调用,但我已经测试了多次,唯一不会被调用的情况是系统杀死进程,但在那个时候你的通知也会被杀死,所以没关系。


1
不,当服务被操作系统杀死时,通知不会被杀死! - Ali

0

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