一旦前台服务不再处于前台,使来自前台服务的通知可取消。

4
我有一个音乐控制通知,允许用户开始/停止音乐。我希望它的行为与 Google Play 音乐应用程序通知完全相同:当音乐正在播放时,服务在前台且通知不可取消;当音乐未播放时,服务不再在前台,通知可以被移除。它运行良好,但当我取消服务的前台时,通知会很快被移除,然后立即重新出现。
以下是我的代码,首先是如何构建通知:
NotificationCompat.Builder notifBuilder =
            new android.support.v7.app.NotificationCompat.Builder(getApplicationContext())
                    .setStyle(new android.support.v7.app.NotificationCompat.MediaStyle()
                            .setShowActionsInCompactView(1, 2, 3)
                            .setShowCancelButton(true)
                            .setCancelButtonIntent(deletePendingIntent)))
                    .setSmallIcon(R.drawable.notif_logo)
                    .setColor(ResourcesCompat.getColor(getResources(), R.color.blue, getTheme()))
                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                    .setShowWhen(false);

    notifBuilder.setContentIntent(pendingIntent);
    notifBuilder.setDeleteIntent(deletePendingIntent);

这是我启动和更新通知的方法:

private void showNotification(NotificationCompat.Builder notifBuilder, boolean foreground) {
    if (foreground) {
        startForeground(NOTIFICATION_ID, notifBuilder.build());
    } else {
        stopForeground(false);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(NOTIFICATION_ID, notifBuilder.build());
    }
}

如果我使用stopForeground(false),通知在运行后仍然无法取消。如果我使用stopForeground(true),通知会被快速删除然后再次添加,这会导致奇怪的闪烁。
如何设置一个通知,在服务退出前台时可取消,而不必先删除再添加通知?
1个回答

8
根据在前台服务文档中使用MediaStyle通知的说明:

在Android 5.0(API级别21)及更高版本中,一旦服务不再在前台运行,您可以滑动通知以停止播放器。在较早的版本中无法执行此操作。为了允许用户在Android 5.0(API级别21)之前删除通知并停止播放,您可以通过调用setShowCancelButton(true)setCancelButtonIntent()在通知的右上角添加取消按钮。

您永远不需要调用setOngoing(false)/setOngoing(true),因为这受到您的服务当前是否在前台的控制。
根据媒体会话回调文档,当您的音乐暂停时,应调用stopForeground(false) - 这将删除前台优先级并允许用户在API 21+设备上滑动通知。

你好,谢谢您的回复。我尝试了stopForeground(false),但它并没有起作用,通知仍然无法被取消或滑动。我正在API 25设备上进行测试。我已更新了代码和问题的最后一部分。 - MickaelG
您在模拟器或Nexus/Pixel设备上是否看到相同的行为? - ianhanniballake
终于找到了这个 bug!为了让 stopForeground(false) 正常工作,我需要将目标版本设置为 21 或更高。我之前的目标版本是 20。 我创建了一个最小化项目来重现这个 bug:https://github.com/MickaelGuilbeaud/AndroidForegroundNotification 我没有想到使用 NotificationCompat 时,targetSdkVersion 21 是必须的。 - MickaelG
一旦调用stopForeground(false),服务似乎会在一两分钟内被操作系统清理,并且通知消失了。这听起来很合理,因为它不再处于前台,也没有任何绑定到它的东西,但是其他音乐流媒体应用程序能够保持通知一直存在并且可以无限期地取消 - 他们做了什么不同的事情呢? - user888867
2
@user888867 - 他们可能正在使用 ServiceCompat.stopForegroundSTOP_FOREGROUND_DETACH,这可以在服务销毁时仍让通知保持显示。 - ianhanniballake

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