美文网首页
Disallowed call from unknown not

Disallowed call from unknown not

作者: CZKGO | 来源:发表于2019-07-11 11:20 被阅读0次

    问题:

    java.lang.SecurityException: Disallowed call from unknown notification listener: android.service.notification.INotificationListener$Stub$Proxy@130eeac class android.service.notification.INotificationListener$Stub$Proxy
            at android.os.Parcel.createException(Parcel.java:1950)
            at android.os.Parcel.readException(Parcel.java:1918)
            at android.os.Parcel.readException(Parcel.java:1868)
            at android.app.INotificationManager$Stub$Proxy.cancelNotificationsFromListener(INotificationManager.java:2381)
            at android.service.notification.NotificationListenerService.cancelNotification(NotificationListenerService.java:590)
            at com.app.service.MyNotificationListenerService.deleteNotification(MyNotificationListenerService.java:190)
            at com.app.service.MyNotificationListenerService$1.run(MyNotificationListenerService.java:304)
            at com.neat.async.TaskQueue.run(TaskQueue.java:41)
         Caused by: android.os.RemoteException: Remote stack trace:
            at com.android.server.notification.ManagedServices.checkServiceTokenLocked(ManagedServices.java:601)
            at com.android.server.notification.NotificationManagerService$11.cancelNotificationsFromListener(NotificationManagerService.java:2844)
            at android.app.INotificationManager$Stub.onTransact(INotificationManager.java:665)
            at android.os.Binder.execTransact(Binder.java:752)
    

    原因:

            调用cancelNotification方法时,如果NotificationListenerService断开连接,就会产生该bug,NotificationListenerService会在授权成功时连接,授权关闭时断开连接,但也会因为一些其他原因导致连接断开,如下:

    NotificationListenerService不能监听到通知,研究了一天不知道是什么原因? - 知乎

    分析:

             根据堆栈信息,在ManagedServices类的checkServiceTokenLocked方法中找到了该bug的出处,如下:

    public ManagedServiceInfo checkServiceTokenLocked(IInterface service) {
        checkNotNull(service);
        final IBinder token = service.asBinder();
        final int N = mServices.size();
        for (int i=0; i<N; i++) {
            final ManagedServiceInfo info = mServices.get(i);
            if (info.service.asBinder() == token) return info;
        }
        throw new SecurityException("Disallowed call from unknown " + getCaption() + ": "
                + service);
    }
    
    

             可以看到,当传进来的参数IInterface不在mServices列表里时,就会产生该bug,在ManagedServices类的mServices属性前有如下注释:

    // contains connections to all connected services, including app services
    // and system services
    protected final ArrayList<ManagedServiceInfo> mServices = new ArrayList<ManagedServiceInfo>();
    

    解决方案:

             有上文可知,属性mServices包括所有已连接的服务,所以,我们可以在继承NotificationListenerService的服务中重写onListenerConnected和onListenerDisconnected两个方法,并用一个bool值listenerConnected来标记该服务连接状态,如下:

    private boolean listenerConnected;
    @Override
    public void onListenerConnected() {
        super.onListenerConnected();
        listenerConnected = true;
    }
    
    @Override
    public void onListenerDisconnected() {
        super.onListenerDisconnected();
        listenerConnected = false;
    }
    
    

             然后再调用cancelNotification前先判断连接状态:

    if (listenerConnected) {
        if (Build.VERSION.SDK_INT >= 21) {
            cancelNotification(key);
        } else {
            cancelNotification(packageName, tag, id);
        }
    }
    

    相关文章

      网友评论

          本文标题:Disallowed call from unknown not

          本文链接:https://www.haomeiwen.com/subject/tbfrkctx.html