Я хочу отображать уведомление внутри приложения, которое исчезает, когда уведомление нажимается без запуска действия.
Я использую пустое намерение, и оно работает:
Intent intent = new Intent();
PendingIntent contentIntent = PendingIntent.getActivity(context, (int)System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, "")
.setSmallIcon(R.drawable.icon)
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(true)
.setTicker(text);
.setContentIntent(contentIntent);
Тем не менее, есть некоторые сбои:
java.lang.RuntimeException: bad array lengths
at android.os.Parcel.readIntArray(Parcel.java:789)
at android.app.INotificationManager$Stub$Proxy.enqueueNotificationWithTag(INotificationManager.java:339)
at android.app.NotificationManager.notify(NotificationManager.java:139)
at android.app.NotificationManager.notify(NotificationManager.java:112)
...
Согласно этот ТАК ответ, сбои происходят из-за того, что intent
не запускает действие.
Уведомление можно отклонить по его идентификатору, но я не могу отклонить его, когда нет активности для запуска и вызова метода отклонения.
Как я могу отклонить уведомление о касании внутри приложения, не используя пустое намерение?
Согласно это ТАК вопросы, похоже, проблема в Android. Сбои, о которых я сообщал, также происходили на Android 4.3.
Согласно этот ТАК ответ, похоже, это связано со слишком большим растровым изображением, установленным с помощью setLargeIcon
. Поэтому теперь я уменьшаю размер растрового изображения с помощью Glide.
Вы можете создать намерение, которое вызывает BroadcastReceiver
, которое затем отменяет уведомление.
Ваш PendingIntent
можно создать так:
private PendingIntent getCancelNotificationIntent() {
Intent cancelIntent = new Intent(context, CancelNotification.class);
return PendingIntent.getBroadcast(context, 0, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Класс CancelNotification.java
будет выглядеть примерно так:
public class CancelNotification extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
notificationManager.cancel(NOTIFICATION_ID);
}
}
Обновлено:NOTIFICATION_ID
— это константа, которую вы определяете и передаете NotificationManager
следующим образом:
notificationManager.notify(NOTIFICATION_ID, yourNotificationObject);
ПРИМЕЧАНИЕ: не забудьте зарегистрировать приемник в файле манифеста следующим образом:
<receiver android:name = "com.example.package.CancelNotification" />
Если кто-то найдет этот ответ, если у вас есть несколько уведомлений, ваш requestCode в PendingIntent должен быть уникальным (например, использовать идентификатор вашего уведомления).
Если вы не хотите начинать действие, когда пользователи касаются уведомления, вы можете создать ожидающее намерение, которое отправляет широковещательную рассылку или запускает службу.
Вот пример:
PendingIntent.getBroadcast(context, 12, new Intent("any intent action"), PendingIntent.FLAG_UPDATE_CURRENT)
Но что мешает вашей деятельности иметь такую реализацию:
@Override
public void onCreate(Bundle savedInstanceState) {}
с дополнительной темой nodisplay в манифесте:
android:theme = "@android:style/Theme.NoDisplay"
Это будет просто нет операции.
@IgorGanapolsky Это константа, которую вы определяете при публикации уведомления через
NotificationManager
:notificationManager.notify(NOTIFICATION_ID, yourNotificationObject);