【问题标题】:Android - Remove action button from notificationAndroid - 从通知中删除操作按钮
【发布时间】:2020-05-18 16:19:09
【问题描述】:

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

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

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

(我认为没有必要放任何代码,但如果有必要我会...)

【问题讨论】:

    标签: android notifications


    【解决方案1】:

    如果您使用 v4 支持库中的 NotificationCompat.Builder,您可以直接访问构建器的操作集合(遗憾的是没有提供公共修改器)。

    以下方法可以解决问题(当然你必须更新重新通知):

    NotificationCompat.Builder notifBuilder = NotificationCompat.Builder(context);
    ...
    notifBuilder.mActions.clear();
    

    【讨论】:

    • 我知道这篇文章已经过时了,但我只是第一次遇到这个问题,老实说,这显然是通知 API 的一个非常糟糕的缺点。要么你必须创建一个新的构建器实例,然后重新设置所有降低代码可读性的字段,要么你使用你的解决方案——它有效——但非常难看,因为mActions应该是一个私人成员,而谷歌没有提供一种清除动作的方法。好可惜……
    • @coxc 当您更新到 gradle 插件版本 3.3.0 时,它会抱怨上面的语句:错误:只能从同一个库组中访问 Builder.mActions (groupId=androidx.core) [受限 API]
    • Builder.mActions can only be accessed from within the same library group (groupId=com.android.support)
    • 即使它显示为红色(RestrictedApi),就好像它是一个错误一样,它仍然有效。我不知道这样做的缺点。有没有人?从头开始创建NotificationBuilder object 可能不是一个好的解决方案,因为它“可能”导致notification 在更新时弹出/闪烁。所以,我还是用这个,一味地忽略RestrictedApi ...
    【解决方案2】:

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

    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
    }
    

    从这里:https://code.google.com/p/android/issues/detail?id=68063

    注意: Proguard 可能会在混淆构建中破坏按钮清除。修复是在proguard-rules.pro中添加以下两行

    -keep class androidx.core.app.NotificationCompat { *; }
    -keep class androidx.core.app.NotificationCompat$* { *; }
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题并找到了解决方案。 我创建了另一个构建器并添加了两个这样的“空”操作:

      builder.addAction(0, null, null);
      builder.addAction(0, null, null);
      

      (我每个按钮一个,所以如果你有三个,就调用它三次)。

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

      【讨论】:

      • 删除按钮内容,但在按钮原来的位置留下空白。
      【解决方案4】:

      即使接受的答案有效,但根据文档,设计方法是使用 NotificationCompat.Extender 类。例如在 Kotlin 中:

      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)
      }
      

      【讨论】:

      • 与接受的答案相同的错误:“Builder.mActions 只能从同一个库组中访问”。
      【解决方案5】:
      NotificationCompat.Builder notifBuilder = NotificationCompat.Builder(context);
      

      删除整个操作按钮:

      builder.mActions.clear();
      

      删除特殊操作按钮:

      builder.mActions.remove(index);
      

      终于:

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

      【讨论】:

        【解决方案6】:

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

        通知抽屉由

        组成
        • 视图(包含标题、细节、小图标)
        • 动作(用户点击通知抽屉视图时可能发生的任何动作)

        要设置通知以便更新通知,请通过调用 NotificationManager.notify(ID, notification) 向其发出通知 ID。要在发出通知后更新此通知,请更新或创建一个 NotificationCompat.Builder 对象,从中构建一个 Notification 对象,然后使用您之前使用的相同 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());
          ...
        

        【讨论】:

        • 我已经知道...我也调用了 NotificationCompat.builder.setAction() 但我需要知道任何方法来删除添加的操作,所以你的回答没有帮助:(
        • 很抱歉,我认为我没有完全理解您的问题。也许这个 shashikawlp.wordpress.com/2013/05/08/…> 会帮助你。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-26
        相关资源
        最近更新 更多