Android-从通知中删除操作按钮

Android-从通知中删除操作按钮,android,notifications,Android,Notifications,我想在单击这些操作按钮时关闭通知操作按钮(而不是整个通知)。(比方说:一个带有停止操作按钮的下载通知。当单击停止时,关闭停止按钮并将contentText更改为“下载已取消”) 我唯一想到的是取消通知并通知另一个具有相同id的通知,但这似乎是一个丑陋的解决方法 那么,有没有办法从通知中删除操作按钮 (我认为没有必要输入任何代码,但如果有必要,我会这样做。)Android提供了通知区域,用于提醒用户已发生的事件。它还提供了一个通知抽屉,用户可以下拉该抽屉查看有关通知的更多详细信息 通知出票人包括

我想在单击这些操作按钮时关闭通知操作按钮(而不是整个通知)。(比方说:一个带有停止操作按钮的下载通知。当单击停止时,关闭停止按钮并将contentText更改为“下载已取消”)

我唯一想到的是取消通知并通知另一个具有相同id的通知,但这似乎是一个丑陋的解决方法

那么,有没有办法从通知中删除操作按钮


(我认为没有必要输入任何代码,但如果有必要,我会这样做。)

Android提供了通知区域,用于提醒用户已发生的事件。它还提供了一个通知抽屉,用户可以下拉该抽屉查看有关通知的更多详细信息

通知出票人包括

  • 视图(包含标题、细节、小图标)
  • 操作(用户单击通知抽屉视图时可能发生的任何操作)
要设置通知以便对其进行更新,请通过调用NotificationManager.notify(ID,notification)向其发出通知ID。要在发出通知后更新此通知,请更新或创建NotificationCompat.Builder对象,从中生成通知对象,并使用以前使用的相同ID发出通知

mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    // Sets an ID for the notification, so it can be updated
    int notifyID = 1;
    mNotifyBuilder = new NotificationCompat.Builder(this)
    .setContentTitle("New Message")
    .setContentText("You are downloading some image.")
    .setSmallIcon(R.drawable.ic_stop)
   numMessages = 0;  
  // Start of a loop that processes data and then notifies the user
  ...
  mNotifyBuilder.setContentText("Download canceled")
    .setNumber(++numMessages);
  // Because the ID remains unchanged, the existing notification is
  // updated.
  mNotificationManager.notify(
        notifyID,
        mNotifyBuilder.build());
  ...

我也遇到了同样的问题,并找到了解决办法。 我创建了另一个生成器并添加了两个“空”操作,如下所示:

builder.addAction(0, null, null);
builder.addAction(0, null, null);
(我的每个按钮对应一个,如果有三个按钮,请调用三次)


然后在调用Notify时,它会删除按钮。

我正在使用以下解决方法:

NotificationCompat.Builder builder = //existing instance of builder
//...
try {
    //Use reflection clean up old actions
    Field f = builder.getClass().getDeclaredField("mActions");
    f.setAccessible(true);
    f.set(builder, new ArrayList<NotificationCompat.Action>());
} catch (NoSuchFieldException e) {
    // no field
} catch (IllegalAccessException e) {
    // wrong types
}

如果您使用的是v4支持库中的NotificationCompat.Builder,则只需直接访问生成器的操作集合即可(遗憾的是,没有提供公共变量)

以下内容将实现此目的(当然,您必须更新并重新通知):

移除整个操作按钮:

builder.mActions.clear();
对于“删除特殊操作”按钮:

builder.mActions.remove(index);
最后:

notificationManager.notify(notificationID, builder.build());

尽管公认的答案是有效的,但根据文档,实现这一点的设计方法是使用
NotificationCompat.Extender
类。例如,在科特林:

private val clearActionsNotificationExtender = NotificationCompat.Extender { builder ->
    builder.mActions.clear()
    builder
}

private val notificationBuilder by lazy {
     NotificationCompat.Builder(context)
           .addAction(R.drawable.ic_play_arrow, "Play", playPendingIntent)
}

private fun updateNotification(){
     notificationBuilder
          .extend(clearActionsNotificationExtender) // this will remove the play action
          .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent)
}

我已经知道。。。我还调用了NotificationCompat.builder.setAction(),但我需要知道如何删除添加的操作,因此您的回答没有帮助:(很抱歉,我想我没有完全理解你的问题。也许这会对你有所帮助。删除按钮内容,但在按钮原来的位置留下空白。我知道帖子很旧,但我只是第一次面对这个问题,老实说,这显然是通知API的一个非常糟糕的缺点。或者你必须创建一个新的构建器实例,然后重新设置所有字段,这会降低代码的可读性,或者你使用你的解决方案-这很有效-但非常难看,因为
mActions
应该是一个私有成员,而谷歌没有提供一个方法来清除操作。很遗憾…@coxc当你更新到gradle插件版本3.3.0时,它会被删除将对上述声明提出投诉:错误:Builder.mActions只能从同一个库组(groupId=androidx.core)[RestrictedApi]
Builder.mActions只能从同一个库组(groupId=com.android.support)
中访问,即使它以红色显示(
RestrictedApi
),好像这是一个错误,它仍然有效。我不知道这样做的缺点。有人这样做吗?从头开始创建
NotificationBuilder对象可能不是一个好的解决方案,因为它“可能”更新时导致
通知的弹出/闪烁。因此,我仍然使用此选项,并盲目忽略
限制API
…与公认的答案相同的错误:“Builder.mActions只能从同一库组中访问”。
builder.mActions.remove(index);
notificationManager.notify(notificationID, builder.build());
private val clearActionsNotificationExtender = NotificationCompat.Extender { builder ->
    builder.mActions.clear()
    builder
}

private val notificationBuilder by lazy {
     NotificationCompat.Builder(context)
           .addAction(R.drawable.ic_play_arrow, "Play", playPendingIntent)
}

private fun updateNotification(){
     notificationBuilder
          .extend(clearActionsNotificationExtender) // this will remove the play action
          .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent)
}