如何取消前台服务使用通知(滑动清除)或清除所有通知?

30

我目前在创建一个带有通知的前台服务,当服务启动时通知会出现在通知栏中。如果服务停止,通知也会被关闭。我的问题是,是否有一种方法可以在“清除所有通知”或者通知消失(滑动)时停止服务?

更新内容包括通知实现:

public int onStartCommand(Intent intent, int flags, int startId)
{   
    Log.d(CLASS, "onStartCommand service started.");

    if (getString(R.string.service_start_action) == intent.getAction())
    {
        Intent intentForeground = new Intent(this, ServiceMain.class)
            .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);    
        PendingIntent pendIntent = PendingIntent.getActivity(getApplicationContext(), 0, intentForeground, 0);      
        Notification notification;
        Notification.Builder builder = new Notification.Builder(getApplicationContext())
            .setSmallIcon(android.R.drawable.btn_star)
            .setTicker("Service started...")
            .setContentIntent(pendIntent)
            .setDefaults(Notification.DEFAULT_ALL)
            .setOnlyAlertOnce(true)
            .setOngoing(false);
        notification = builder.build();
        notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;

        startForeground(SERV_NOTIFY, notification);
        player.start();
    }
    else
    {
        Log.d(CLASS, "onStartCommand unable to identify acition.");
    }

    return START_STICKY;        
}

看一下谷歌的这个示例:https://github.com/googlesamples/android-ActiveNotifications。它展示了如何监听已取消的通知,以及整个通知组。 - IgorGanapolsky
1
据我所知,如果不创建通知,您不能“创建”前台服务。Android要求这样做是因为他们不希望你在用户不知情的情况下运行服务。当您的活动已被销毁且您的前台服务正在运行时,删除通知需要发出通知,您不能简单地取消它。只有通过调用“.stopForeground(true)”来取消前台服务本身,才能取消通知,布尔参数指示是否想要停止前台及通知。 - Neon Warge
6个回答

38

用户无法滑动由正在运行的前台服务生成的通知。

因此,首先使用stopForeground(false),然后允许用户在之后可以滑动该通知(至少在Lollipop+上)。对于早期版本的Android系统(pre-Lollipop),您可能需要使用stopForeground(true)停止前台并移除通知,然后使用notificationManager.notify(yourNotificationID,yourNotificationObject)重新发布通知,使得您的通知可见但仍可被滑动。

重要的是,设置一个删除意图,当用户将其滑动消失时触发这个意图来处理它。

(new NotificationCompat.builder(this).setDeleteIntent(deletePendingIntent)).build()

其中deletePendingIntent是类似于以下内容的东西:

Intent deleteIntent = new Intent(this, YourService.class);
deleteIntent.putExtra(someKey, someIntValue);
PendingIntent deletePendingIntent = PendingIntent.getService(this,
someIntValue, 
deleteIntent, 
PendingIntent.FLAG_CANCEL_CURRENT);
当用户滑动它时,带有额外信息的意图将被传递给服务。在 onStartCommand 中处理传递的额外信息,即检查 intent != nullintent.getExtras() != null,然后从 extras bundle 中提取给定 someKey 的值,并且如果它与 someIntValue 匹配,则调用 stopSelf()

5
我需要使用 startForeground(false),但我还需要从我的 NotificationBuilder 代码中删除对 .setOngoing(true) 的调用。 - caitcoo0odes
1
在Android 13及以上版本中,用户可以在不调用stopForeground的情况下关闭通知。 - Adam Burley

8

这段代码在我的电脑上能够正常运行:

this.stopForeground(false);
mNotificationManager.cancel(NOTIFY_ID);

你需要设置onStartCommand的返回值,使用STRAT_STICKY可以重新启动你的服务。


我们把这段代码放在哪里?因为我们找不到通知划动功能。 - Gaurav Mandlik
1
这实际上并没有取消前台服务。 - IgorGanapolsky

6

前台服务的通知无法被清除。唯一的方法是停止服务。

所以我相信你想解决的问题永远不会发生。


5
我的问题是,当“清除所有通知”或者滑动消除通知时,是否有一种方法可以停止服务?
假设你的通知已经设置为允许被清除,当它被清除时,deleteIntent 应该会被调用。你可以将其设置为一个指向已在清单中注册的 BroadcastReceiver 的 getBroadcast() PendingIntent,该 BroadcastReceiver 调用 stopService()。

谢谢,这本来是我的初始方法,但一旦服务的通知出现在通知栏中,就没有“清除所有通知”的按钮,而且似乎禁用了滑动消除功能。 - d.moncada
@moncadad:编辑你的问题,在你创建“Notification”的代码处发布它,并在这里发表评论让我知道你已经发布了它。 - CommonsWare
4
嗯...好的,你没有设置“FLAG_NO_CLEAR”,我在源代码中也没有看到“Notification.Builder”设置“FLAG_NO_CLEAR”,因此Android必须将“FLAG_FOREGROUND_SERVICE”视为意味着“FLAG_NO_CLEAR”。顺便说一句,你不必自己设置“FLAG_FOREGROUND_SERVICE”—— 根据文档,“startForeground()”会为你完成。我总是自己设置“FLAG_NO_CLEAR”,并且错误地认为如果不设置它,将得到一个正常的通知,如果用户清除了它,你可能会失去前台权限。 - CommonsWare
1
谢谢您的帮助,看起来这种行为不被服务通知允许。我想我会在通知本身中添加一个“关闭”按钮来停止服务。 - d.moncada
@androiddeveloper:“前台服务通知中的deleteIntent会被调用吗?”--我从未尝试过。通常我将前台服务通知设置为持续运行,因此它们无法单独解除。 - CommonsWare
显示剩余6条评论

0

你可以在创建的通知中设置dismissIntent,但我认为前台服务通知无法被清除?


有一个 dismissintent?那个 API 规范在哪里? - IgorGanapolsky
@IgorGanapolsky NotificationCompat.Builder#setDeleteIntent(...) - Dogcat
@Dogcat,我在API中没有看到dismissIntent - IgorGanapolsky
这是一个答案还是一个问题? - Vahid Amiri

0
我做了以下操作,它对我起作用了:
  1. 在调用前台服务之前,我创建了一个通知,使用与前台服务通知相同的id和通知通道

  2. 我通过通知id取消了通知

  3. 我创建了另一个具有所需结构的通知

  4. 您可以消除或滑动此最后一个通知,而不停止您的前台服务


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