如何在单击操作后关闭通知

end*_*ner 132 android action android-notifications

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

builder.addAction(iconId, title, intent);
Run Code Online (Sandbox Code Playgroud)

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

notification.flags = Notification.FLAG_AUTO_CANCEL;
Run Code Online (Sandbox Code Playgroud)

要么

builder.setAutoCancel(true);
Run Code Online (Sandbox Code Playgroud)

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

任何提示?或者这不是API的一部分?我没找到任何东西.

Kae*_*iil 143

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

notify(int id, Notification notification)
Run Code Online (Sandbox Code Playgroud)

要取消,您可以致电:

cancel(int id)
Run Code Online (Sandbox Code Playgroud)

具有相同的ID.那么,基本上,你需要跟踪id或者可能将id放入你添加到PendingIntent里面的Intent的Bundle中?

  • 谢谢,这解决了我的问题.但是,我仍然认为它有点过于复杂.在按下某个操作时,您不必仅提供API来自动关闭通知,而是必须使用intent和通知id传递来实现相同的功能. (23认同)
  • 来自onCreate()的代码示例:Bundle extras = getIntent().getExtras(); if(extras!= null){String tag = extras.getString(NotificationReceiver.INTENT_EXTRA_NOTIFICATION_TAG); int id = extras.getInt(NotificationReceiver.INTENT_EXTRA_NOTIFICATION_ID); if(NotificationReceiver.NOTIFICATION_ID == id && NotificationReceiver.NOTIFICATION_TAG.equals(tag)){//活动已通过通知操作启动,解除//通知NotificationManager manager =(NotificationManager)getSystemService(Service.NOTIFICATION_SERVICE); manager.cancel(tag,id); }} (5认同)
  • 如果您认为这很复杂,请不要考虑更新通知(不要丢失该ID),也不要检查它是否显示(API不会跟踪它,您必须这样做)...: P (2认同)
  • @Daksh:基本上,您将通知标记和id添加到您的意图中,当您按下操作时,它会启动.通过这些额外信息,您可以检查启动活动是否通过通知操作启动. (2认同)
  • 在新的 API 中你有 notify(String tag, int id, Notification notification) 和相应的 cancel(String tag, int id) (2认同)

aar*_*gas 61

在使用Lollipop的Heads Up Display通知时发现这是一个问题.请参阅设计指南.这是要实现的完整(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());
Run Code Online (Sandbox Code Playgroud)

NotificationActivity

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

}
Run Code Online (Sandbox Code Playgroud)

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

<activity
    android:name=".NotificationActivity"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>
Run Code Online (Sandbox Code Playgroud)

  • 在这里使用BroadcastReceiver取消通知会不会更有效?这是一个显示实现的好例子,但它可以进一步减少:http://stackoverflow.com/a/19745745/793150 (3认同)

Vic*_*cki 16

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

当用户单击操作按钮时,您必须手动取消通知.通知仅在默认操作时自动取消.

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

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

我在相关帖子中发布了示例代码.单击Android通知操作不会关闭通知抽屉.

  • 太糟糕了,他们仍然没有把它融入到API中......这样做真是太乱了.但仍然是唯一的方法,特别是如果您无法控制目标意图,例如查看URL. (2认同)

小智 7

只需添加这一行:

 builder.setAutoCancel(true);
Run Code Online (Sandbox Code Playgroud)

完整的代码是:

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());
Run Code Online (Sandbox Code Playgroud)


Mal*_*asz 7

在新的 API 中不要忘记 TAG:

notify(String tag, int id, Notification notification)
Run Code Online (Sandbox Code Playgroud)

并相应地

cancel(String tag, int id) 
Run Code Online (Sandbox Code Playgroud)

代替:

cancel(int id)
Run Code Online (Sandbox Code Playgroud)

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


Him*_*wal 6

在我的意见中使用a BroadcastReceiver是一种更简洁的取消通知方式:

在AndroidManifest.xml中:

<receiver 
    android:name=.NotificationCancelReceiver" >
    <intent-filter android:priority="999" >
         <action android:name="com.example.cancel" />
    </intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)

在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];
Run Code Online (Sandbox Code Playgroud)


Com*_*are 5

您可以随时cancel()Notification从任何正在被调用的动作(例如,在onCreate()绑在活动的PendingIntent您提供的addAction()).

  • 但是如何访问已调用的活动中的通知? (2认同)

Hou*_*lla 5

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

NotificationManagerCompat.from(this).cancel(null, notificationId);
Run Code Online (Sandbox Code Playgroud)

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