169

从 API 级别 16(Jelly Bean)开始,可以使用以下命令向通知添加操作

builder.addAction(iconId, title, intent);

但是,当我向通知添加操作并按下该操作时,通知不会被解除。单击通知本身时,可以将其关闭

notification.flags = Notification.FLAG_AUTO_CANCEL;

或者

builder.setAutoCancel(true);

但显然,这与通知相关的操作无关。

有什么提示吗?或者这还不是 API 的一部分吗?我什么也没找到。

4

9 回答 9

175

当您在通知管理器上调用 notify 时,您给了它一个 id - 这是您以后可以用来访问它的唯一 id(这来自通知管理器:

notify(int id, Notification notification)

要取消,您可以致电:

cancel(int id)

具有相同的ID。所以,基本上,您需要跟踪 id 或者可能将 id 放入您添加到 PendingIntent 内的 Intent 的 Bundle 中?

于 2012-08-09T13:15:23.183 回答
68

在使用 Lollipop 的抬头显示通知时发现这是一个问题。请参阅设计指南。这是要实现的完整(ish)代码。

到目前为止,拥有一个“关闭”按钮并不那么重要,但现在它更重要的是你的脸。

抬头通知

构建通知

int notificationId = new Random().nextInt(); // just use a counter in some util class...
PendingIntent dismissIntent = NotificationActivity.getDismissIntent(notificationId, context);

NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setPriority(NotificationCompat.PRIORITY_MAX) //HIGH, MAX, FULL_SCREEN and setDefaults(Notification.DEFAULT_ALL) will make it a Heads Up Display Style
        .setDefaults(Notification.DEFAULT_ALL) // also requires VIBRATE permission
        .setSmallIcon(R.drawable.ic_action_refresh) // Required!
        .setContentTitle("Message from test")
        .setContentText("message")
        .setAutoCancel(true)
        .addAction(R.drawable.ic_action_cancel, "Dismiss", dismissIntent)
        .addAction(R.drawable.ic_action_boom, "Action!", someOtherPendingIntent);

// Gets an instance of the NotificationManager service
NotificationManager notifyMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

// Builds the notification and issues it.
notifyMgr.notify(notificationId, builder.build());

通知活动

public class NotificationActivity extends Activity {

    public static final String NOTIFICATION_ID = "NOTIFICATION_ID";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.cancel(getIntent().getIntExtra(NOTIFICATION_ID, -1));
        finish(); // since finish() is called in onCreate(), onDestroy() will be called immediately
    }

    public static PendingIntent getDismissIntent(int notificationId, Context context) {
        Intent intent = new Intent(context, NotificationActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.putExtra(NOTIFICATION_ID, notificationId);
        PendingIntent dismissIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        return dismissIntent;
    }

}

AndroidManifest.xml(防止 SystemUI 聚焦到后台堆栈所需的属性)

<activity
    android:name=".NotificationActivity"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>
于 2014-11-22T23:38:11.253 回答
19

我发现当你在扩展通知中使用操作按钮时,你必须编写额外的代码并且你会受到更多的限制。

当用户单击操作按钮时,您必须手动取消通知。只有默认操作会自动取消通知。

此外,如果您从按钮启动广播接收器,通知抽屉不会关闭。

我最终创建了一个新的 NotificationActivity 来解决这些问题。这个没有任何 UI 的中间活动会取消通知,然后启动我真正想从通知开始的活动。

我在相关帖子中发布了示例代码Clicking Android Notification Actions does not close Notification drawer

于 2014-02-14T15:36:07.533 回答
9

在我看来,使用 aBroadcastReceiver是一种更简洁的方式来取消通知:

在 AndroidManifest.xml 中:

<receiver 
    android:name=.NotificationCancelReceiver" >
    <intent-filter android:priority="999" >
         <action android:name="com.example.cancel" />
    </intent-filter>
</receiver>

在java文件中:

Intent cancel = new Intent("com.example.cancel");
PendingIntent cancelP = PendingIntent.getBroadcast(context, 0, cancel, PendingIntent.FLAG_CANCEL_CURRENT);

NotificationCompat.Action actions[] = new NotificationCompat.Action[1];

通知取消接收者

public class NotificationCancelReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //Cancel your ongoing Notification
    };
}
于 2015-08-02T14:24:08.420 回答
8

在您的意图被触发以删除通知后,您将需要运行以下代码。

NotificationManagerCompat.from(this).cancel(null, notificationId);

注意:notificationId 与传递给运行通知的 id 相同

于 2020-04-28T15:00:50.423 回答
7

您始终可以cancel()Notification操作调用的任何内容中获取(例如,在onCreate()PendingIntent您提供的相关活动中addAction())。

于 2012-08-09T12:44:27.567 回答
7

在新的 API 中不要忘记 TAG:

notify(String tag, int id, Notification notification)

并且相应地

cancel(String tag, int id) 

代替:

cancel(int id)

https://developer.android.com/reference/android/app/NotificationManager

于 2018-11-14T11:02:10.510 回答
4

只需输入这一行:

 builder.setAutoCancel(true);

完整的代码是:

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    builder.setSmallIcon(android.R.drawable.ic_dialog_alert);
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.co.in/"));
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
    builder.setContentIntent(pendingIntent);
    builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.misti_ic));
    builder.setContentTitle("Notifications Title");
    builder.setContentText("Your notification content here.");
    builder.setSubText("Tap to view the website.");
    Toast.makeText(getApplicationContext(), "The notification has been created!!", Toast.LENGTH_LONG).show();

    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    builder.setAutoCancel(true);
    // Will display the notification in the notification bar
    notificationManager.notify(1, builder.build());
于 2018-03-13T13:14:55.737 回答
-3

builder.setAutoCancel(true);

在 Android 9 上也进行了测试。

于 2020-04-09T09:09:52.220 回答