Android 使前台服务的通知在该服务不再位于前台时可取消

Android 使前台服务的通知在该服务不再位于前台时可取消,android,service,notifications,foreground-service,Android,Service,Notifications,Foreground Service,我有一个音乐控制通知,允许用户启动/停止音乐。我想要与Google Play音乐应用程序通知完全相同的行为:播放音乐时,服务在前台,通知不可取消;播放音乐时,服务不再在前台,通知可以删除。它可以正常工作,但当我取消前台服务时,通知会很快被删除,然后再次出现 以下是我的代码,首先是如何构建通知: NotificationCompat.Builder notifBuilder = new android.support.v7.app.NotificationCompat.Bu

我有一个音乐控制通知,允许用户启动/停止音乐。我想要与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());
    }
}
以下是我如何启动和更新通知:

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),通知会很快被删除,然后再次添加,这会导致奇怪的闪烁

在服务退出前台后,我如何才能获得可取消的通知,而不必删除然后再次添加通知?

根据:

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

您永远不需要调用
setconsuming(false)
/
setconsuming(true)
,因为这取决于您的服务当前是否在前台


根据,当音乐暂停时,应调用
停止前台(false)
,这将删除前台优先级,并允许用户在API 21+设备上滑动通知。

您好,感谢您的回复。stopForeground(false)是我尝试的第一件事,但它不起作用,通知仍然不可取消/运行后无法刷取。我正在API 25设备上测试。我更新了代码和问题的最后一部分。你在模拟器或Nexus/像素设备上看到相同的行为吗?终于找到了错误!要使stopForeground(false)按预期工作,我需要将目标设置为版本21或更高。我的目标是版本20。我创建了一个简单的项目来重现这个bug:当我使用NotificationCompat时,我不希望targetSdkVersion 21是强制性的。一旦调用stopForeground(false),该服务似乎在一两分钟内被操作系统清除,通知消失。这听起来很合理,因为它已经不在前景中了,也没有任何东西与之相关,然而,其他音乐流应用程序能够使通知保持活动状态并无限期地取消-它们有什么不同吗?@user888667-它们可能正在使用允许通知保留,即使服务被破坏。