Начиная с уровня API 16 (Jelly Bean), есть возможность добавлять действия в уведомление с помощью
builder.addAction(iconId, title, intent);
Но когда я добавляю действие к уведомлению, и действие нажимается, уведомление не будет закрыто. При нажатии на само уведомление его можно закрыть с помощью
notification.flags = Notification.FLAG_AUTO_CANCEL;
или
builder.setAutoCancel(true);
Но, очевидно, это не имеет ничего общего с действиями, связанными с уведомлением.
Есть подсказки? Или это еще не часть API? Ничего не нашел.
источник
Обнаружил, что это проблема при использовании уведомления Heads Up Display от Lollipop. См. Рекомендации по дизайну . Вот полный код для реализации.
Раньше наличие кнопки «Закрыть» было менее важным, но теперь это больше для вас.
Создание уведомления
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>
источник
Я обнаружил, что когда вы используете кнопки действий в расширенных уведомлениях, вам нужно писать дополнительный код, и вы более ограничены.
Вам необходимо вручную отменить уведомление, когда пользователь нажимает кнопку действия. Уведомление отменяется автоматически только для действия по умолчанию.
Также, если вы запускаете широковещательный приемник с помощью кнопки, панель уведомлений не закрывается.
В итоге я создал новую NotificationActivity для решения этих проблем. Эта промежуточная активность без какого-либо пользовательского интерфейса отменяет уведомление, а затем запускает действие, которое я действительно хотел начать с уведомления.
Я разместил образец кода в соответствующем сообщении. Щелчок по действиям с уведомлениями Android не закрывает ящик уведомлений .
источник
Вы можете всегда от того, что в настоящее время вызывается действием (например, в деятельности , привязанной к вам поставлять ).
cancel()
Notification
onCreate()
PendingIntent
addAction()
источник
cancel()
берет идентификаторNotification
, который вы использовали при вызовеnotify()
. Вам не нуженNotification
объект.ACTION_VIEW
а тип -image/jpeg
(поделиться изображением с другим приложением), то как должна срабатывать эта отмена? ИМО Android должен автоматически отменять, я озадачен, почему Android просто не заботится об этом ?!Notification
связанном с нимPendingIntent
, это не совсем то, как оно было разработано для работы, и поэтому вы столкнетесь с проблемами, подобными этой. «IMO Android должен автоматически отменяться» - я мог видеть предложение флага для этого в действии, но это не должно происходить постоянно. Если бы это было так, пропуск трека в уведомлении музыкального проигрывателя закрывал бы уведомление.На мой взгляд, использование a
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 }; }
источник
intent.putExtra()
и получить егоBroadcastReceiver
В новых 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
источник
cancel()
функция имеет 2 реализации; один с TAG и один без. Но мы должны предоставитьTAG
. Вотcancel
функция из документовpublic void cancel(@Nullable String tag, int id)
. Последний раз проверялось на Android QПросто поставьте эту строку:
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());
источник
Вам нужно будет запустить следующий код после того, как будет запущено ваше намерение удалить уведомление.
NotificationManagerCompat.from(this).cancel(null, notificationId);
NB: notificationId - это тот же идентификатор, который был передан для запуска вашего уведомления.
источник
builder.setAutoCancel (истина);
Также протестировано на Android 9.
источник