如何撤销点击后的行动通知

从 API 级别16(Jelly Bean)开始,就有可能使用

builder.addAction(iconId, title, intent);

但是,当我向通知添加一个操作并按下该操作时,通知不会被忽略。 当单击通知本身时,可以使用

notification.flags = Notification.FLAG_AUTO_CANCEL;

或者

builder.setAutoCancel(true);

但显然,这与与通知相关的操作没有任何关系。

- 有什么线索吗? 或者这还不是 API 的一部分?-我什么都没找到。

130513 次浏览

您总是可以从操作所调用的任何内容中调用 Notification(例如,您提供给 addAction()的绑定到 PendingIntent的活动的 onCreate())。

当你调用通知管理器的通知时,你给它一个 id ——这是你以后可以用来访问它的唯一 id (这是来自通知管理器的:

notify(int id, Notification notification)

如果要取消,你可以打电话:

cancel(int id)

用同样的身份证。因此,基本上,您需要跟踪 id 或者可能将 id 放入您添加到 PendingInant 内部的意图的 Bundle 中?

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

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

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

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

我已经张贴了一个相关的后 单击“ Android 通知操作”不会关闭“通知”抽屉样本代码。

发现这是一个问题时,使用棒棒糖的头向上显示通知。参见 设计指引。下面是要实现的完整(ish)代码。

直到现在,有一个“解散”按钮还不那么重要,但现在它更多的是在你的脸上。

heads up notification

生成通知

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


}

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

<activity
android:name=".NotificationActivity"
android:taskAffinity=""
android:excludeFromRecents="true">
</activity>

在我看来,使用 BroadcastReceiver是取消通知的一种更干净的方式:

在 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
};
}

只要写下这句话:

 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());

在新的 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

SetAutoCancel (true) ;

也在 Android 9上进行了测试。

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

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

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

总结一下:

NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);


Intent intent = new Intent(context, MyNotificationReceiver.class);
intent.putExtra("Notification_ID", 2022);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
intent,
...);


Notification notification = new NotificationCompat.Builder(...)
...
.addAction(0, "Button", pendingIntent)
.build();


notificationManager.notify(2022, notification);

对于 撤销通知,你有两个选择:

方法1 : (在 MyNotificationReceiver中)

NotificationManager manager = (NotificationManager)
context.getSystemService(NOTIFICATION_SERVICE);
manager.cancel(intent.getIntExtra("Notification_ID", -1));

方法2 : (在 MyNotificationReceiver中)

NotificationManagerCompat manager = NotificationManagerCompat.from(context);
manager.cancel(intent.getIntExtra("Notification_ID", -1));

最后是 manifest:

<receiver android:name=".MyNotificationReceiver" />