【问题标题】:Android 10 java.lang.SecurityException: Not allowed to delete channel MyNotificationChannel with a foreground serviceAndroid 10 java.lang.SecurityException:不允许使用前台服务删除频道 MyNotificationChannel
【发布时间】:2021-09-24 15:24:09
【问题描述】:

我从一个线程创建一个通知:

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

当我尝试删除有关 ondestroy 活动的通知时,它适用于大多数设备,但适用于某些摩托罗拉设备或搭载 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

【问题讨论】:

  • 可能需要提前停止前台服务
  • 您的服务是否声明为 START_STICKY ?你在哪里删除通知渠道?应用何时启动?
  • myIntent 不是服务而是活动,我将其显示为弹出窗口。所以用户可以在手机锁定的情况下看到它。我尝试删除启动通知的de服务中的通知和myIntent的ondestroy。在其他手机上通知被删除但在摩托罗拉e6上没有,并抛出不允许删除频道
  • 您确定在删除关联的NotificationChannel之前服务已正确停止吗?一种解决方法是用try / catch 包围deleteNotificationChannel() 方法
  • 我编辑了代码并添加了带有通知 ID 的取消,同样的情况,适用于大多数设备,但不适用于 Moto e。没有服务可以使用通知在设备锁定的情况下将活动发送到前台。

标签: android android-notifications channel securityexception


【解决方案1】:

其他地方也有类似的话题。对我有用的是,我使用 try catch 环绕块巧妙地捕获了异常并继续前进。最佳做法是在 FG 服务正在使用该频道时不要删除该频道,或者在继续删除频道之前停止该服务

【讨论】:

  • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
【解决方案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 && 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 中我仍然无法删除频道,但正在显示通知。

【讨论】:

    猜你喜欢
    • 2021-09-28
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    相关资源
    最近更新 更多