#android #android-notifications #channel #securityexception
Вопрос:
Я создаю уведомление из потока:
final NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel chan = new NotificationChannel("MyNotificationChannel","Notification Title", NotificationManager.IMPORTANCE_HIGH);
chan.setSound(null, null);
manager.createNotificationChannel(chan);
final Notification notification =
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? new Notification.Builder(context, "MyNotificationChannel") : new Notification.Builder(context))
.setContentTitle(context.getString(R.string.app_name))
.setContentText("Text")
.setSmallIcon(R.drawable.logo)
.setFullScreenIntent(PendingIntent.getActivity(context, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT), true)
.setCategory(Notification.CATEGORY_ALARM)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setOngoing(true)
.build();
((Service) context).startForeground(12345678, notification);
Когда я пытаюсь удалить это уведомление в списке действий, оно работает на большинстве устройств, но на некоторых устройствах Motorola или Xiaomi с Android 10:
protected void onDestroy() {
try {
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(12345678);
mNotificationManager.deleteNotificationChannel("MyNotificationChannel");
}catch(Exception e){
e.printStackTrace();
}
}
Это исключение является сквозным, и уведомление не удаляется, я пытаюсь удалить в потоке и в других действиях:
java.lang.SecurityException: Not allowed to delete channel "MyNotificationChannel" with a foreground service
Комментарии:
1. Вероятно, вам нужно заранее остановить службу переднего плана
2. Ваша служба объявлена как START_STICKY ? Где вы удаляете канал уведомлений ? Когда запускается приложение ?
3. myIntent-это не услуга, это действие, которое я показываю в виде всплывающего окна. Таким образом, пользователь может видеть его с заблокированным телефоном. Я пытаюсь удалить уведомление в службах de, которые запускают уведомление, и ondestroy myIntent. На других телефонах уведомление удаляется, но на motorola e6 нет, и бросьте не разрешать удалять канал
4. Вы уверены, что служба правильно остановлена перед удалением связанного
NotificationChannel
? Обходной путь состоит в том, чтобы окружитьdeleteNotificationChannel()
методtry / catch
5. Я отредактировал код и добавил отмену с идентификатором уведомления и теми же хэпенами, работает на большинстве устройств, но не на Moto e. Нет службы y используйте уведомление для отправки действия на передний план при заблокированном устройстве.
Ответ №1:
Аналогичная нить была и в других местах. Что сработало для меня, так это то, что я аккуратно поймал исключение, используя блок окружения try catch, и двинулся вперед. Наилучшей практикой было бы не удалять канал, когда он используется службой FG, или остановить службу, прежде чем вы продолжите и удалите канал
Комментарии:
1. Пожалуйста, добавьте дополнительные сведения, чтобы расширить свой ответ, например, ссылки на рабочий код или документацию.
Ответ №2:
Я нашел решение после слишком многих тестов. Я добавляю это к AndroidManifest.xml:
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.REORDER_TASKS" />
На службе:
boolean locked = false;
KeyguardManager myKM = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if( myKM.inKeyguardRestrictedInputMode()) {
locked = true;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O amp;amp; locked) {
final NotificationManager manager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
try {
manager.cancel(12345678);
}catch(Exception e){
e.printStackTrace();
}
NotificationChannel chan;
final NotificationManager manager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String channel = "MyNotificationChannel";
chan = manager.getNotificationChannel(channel);
if (chan == null){
chan = new NotificationChannel(
channel,
"Notification Title",
NotificationManager.IMPORTANCE_HIGH);
chan.setSound(null, null); // Service manages its own sound.
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
manager.createNotificationChannel(chan);
}
PendingIntent pending = PendingIntent.getActivity(context, 0, myIntent, PendingIntent.FLAG_ONE_SHOT);
final Notification notification =
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
new Notification.Builder(context, channel) :
new Notification.Builder(context))
.setContentTitle(context.getString(R.string.app_name))
.setContentText("Notification text")
.setSmallIcon(R.drawable.log_trans_mini)
.setFullScreenIntent(pending, true)
.setContentIntent(pending)
.setCategory(Notification.CATEGORY_ALARM)
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_MAX)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setOngoing(true)
.setLights(Color.WHITE, 1000, 1000)
.build();
((Service) context).startForeground(12345678, notification);
} else {
context.startActivity(myIntent);
}
Что нужно сделать дальше, так это удалить канал в устройствах, которые я могу, потому что теперь после того, как вы получили уведомление, канал всегда там. В moto g6 я все еще не могу удалить канал, но отображается уведомление.