NotificationListenerService失效的两种情况

当NotificationListenerService在onCreate或onBind过程中崩溃,会导致服务无法正常启动并接收通知。由于系统在注册时会添加tag,崩溃后tag未移除,使得服务失效,即使修复代码并重启应用也无法恢复。解决办法通常是重启设备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、在NotificationListenerService onCreate或Onbind过程中crash。这种情况只能重启手机,即使修改了crash部分的代码重新安装程序也一样不能收到通知。原因是NLS在registerListenerService时会有一个tag标记(可能是为了防止一个service多次启动)bind前会加tag,bind成功结束后会去掉tag。那么在bind时cash标签不会去掉,就导致NLS无效,即使想重新注册,因为有一个tag存在,也会直接return。


private void registerListenerService(final ComponentName name, final int userid) {  
    //servicesBindingTag可以理解为需要启动的service的标签  
    final String servicesBindingTag = name.toString() + "/" + userid;  
    //如果mServicesBinding中已经包含正在处理的service则直接return退出  
    if (mServicesBinding.contains(servicesBindingTag)) {  
    // stop registering this thing already! we're working on it  
       return;  
    }  
    //将准备启动的service标签添加到mServicesBinding中  
    mServicesBinding.add(servicesBindingTag);  
  
    //... ...省略  
    //使用bindServiceAsUser启动service  
    Intent intent = new Intent(NotificationListenerService.SERVICE_INTERFACE);  
    intent.setComponent(name);  
  
    intent.putExtra(Intent.EXTRA_CLIENT_LABEL,  
            R.string.notification_listener_binding_label);  
    intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(  
            mContext, 0, new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS), 0));  
  
    try {  
        if (DBG) Slog.v(TAG, "binding: " + intent);  
        if (!mContext.bindServiceAsUser(intent,  
                new ServiceConnection() {  
                    INotificationListener mListener;  
                    @Override  
                    public void onServiceConnected(ComponentName name, IBinder service) {  
                        synchronized (mNotificationList) {  
                            //服务成功启动之后删除标签  
                            mServicesBinding.remove(servicesBindingTag);  
                            try {  
                                mListener = INotificationListener.Stub.asInterface(service);  
                                NotificationListenerInfo info = new NotificationListenerInfo(  
                                        mListener, name, userid, this);  
                                service.linkToDeath(info, 0);  
                                mListeners.add(info);  
                            } catch (RemoteException e) {  
                                // already dead  
                            }  
                        }  
                    }  
  
                    @Override  
                    public void onServiceDisconnected(ComponentName name) {  
                        Slog.v(TAG, "notification listener connection lost: " + name);  
                    }  
                },  
                Context.BIND_AUTO_CREATE,  
                new UserHandle(userid)))  
        {  
            //绑定服务失败后删除标签  
            mServicesBinding.remove(servicesBindingTag);  
            Slog.w(TAG, "Unable to bind listener service: " + intent);  
            return;  
        }  
    } catch (SecurityException ex) {  
        Slog.e(TAG, "Unable to bind listener service: " + intent, ex);  
        return;  
    }  
}  
}  

2、被第三方软件杀掉或者service被系统杀掉,可以通过重新绑定服务使NLS重新生效。可以通过adb shell dumpsys notification命令查看手机里enable和live的notificationlistener。如果live里没有说明你的服务没有存活,也就是NLS的无效。可以通过一个函数来重新绑定:

public static void toggleNotificationListenerService(Context context) {
        Log.e(TAG,"toggleNLS");
        PackageManager pm = context.getPackageManager();
        pm.setComponentEnabledSetting(
                new ComponentName(context, com.zhenglei.launcher_test.qianghongbao.NotificationService.class),
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

        pm.setComponentEnabledSetting(
                new ComponentName(context, com.zhenglei.launcher_test.qianghongbao.NotificationService.class),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
    }

以上参考: 点击打开链接 

本文只做整理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值