Как удалить уведомление после того, как действие было нажато

Так как уровень API 16 (Jelly Bean), есть возможность добавлять действия к уведомлению с помощью

builder.addAction(iconId, title, intent);

Но когда я добавляю действие к уведомлению и действие нажимается, уведомление не будет отклонено. Когда кликнуто само уведомление, его можно отклонить с помощью

notification.flags = Notification.FLAG_AUTO_CANCEL;

или

builder.setAutoCancel(true);

Но, очевидно, это не имеет ничего общего с действиями, связанными с уведомлением.

Любые подсказки? Или это еще не часть API? Я ничего не нашел.

Ответ 1

Когда вы вызвали уведомление в диспетчере уведомлений, вы указали ему идентификатор - это уникальный идентификатор, который вы можете использовать для доступа к нему позже (это из диспетчера уведомлений:

notify(int id, Notification notification)

Чтобы отменить, вы должны позвонить:

cancel(int id)

с тем же идентификатором. Итак, в основном, вам нужно отслеживать идентификатор или, возможно, поместить идентификатор в пакет, который вы добавляете к намерению внутри PendingIntent?

Ответ 2

Обнаружено, что это проблема при использовании уведомления Lollipop Heads Up Display. См. рекомендации по разработке. Здесь полный (ish) код для реализации.

До сих пор наличие кнопки "Dismiss" было менее важным, но теперь это больше в вашем лице.

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

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

}

AndroidManifest.xml (атрибуты, необходимые для предотвращения фокусировки SystemUI на задний стек)

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

Ответ 3

Я обнаружил, что когда вы используете кнопки действий в расширенных уведомлениях, вам приходится писать дополнительный код, и вы более ограничены.

Вы должны вручную отменить свое уведомление, когда пользователь нажимает кнопку действия. Уведомление отменяется автоматически для действия по умолчанию.

Также, если вы запускаете широковещательный приемник с помощью кнопки, ящик уведомлений не закрывается.

В результате я создал новую NotificationActivity для решения этих проблем. Эта промежуточная деятельность без какого-либо пользовательского интерфейса отменяет уведомление, а затем начинает активность, которую я действительно хотел начать с уведомления.

Я разместил образец кода в связанном сообщении Нажатие на Android Notification Actions не закрывает ящик уведомлений.

Ответ 4

По моему мнению, использование 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];

NotificationCancelReceiver

public class NotificationCancelReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //Cancel your ongoing Notification
    };
}

Ответ 5

Вы всегда можете cancel() Notification от того, что вызывается действием (например, в onCreate() активности, связанной с PendingIntent, которую вы указываете на addAction()).

Ответ 7

Просто поместите эту строку:

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