应用程序崩溃后通知监听器服务不工作

Notification Listener Service does not work after app is crashed

我的应用程序有问题,我想报告这个错误。

我开发了可以使用 NotificationListenerService 抓取通知的应用程序。

效果很好。

但是 NotificationListenerService class 有我认为的问题。

因为,如果应用程序崩溃了,应用程序根本无法抓取通知, 直到 phone 重新启动。

有谁能解决这个问题吗??

请帮帮我

bug很明显!!但是找到解决方案并不容易....

这点我看完全一样。我发现的唯一 "solution" 是在单独的进程中设置通知侦听器 运行。然后,如果应用程序的其余部分崩溃,它不会停止侦听器。所以只有在通知监听器服务崩溃时才需要重启。

虽然这似乎是一个糟糕且过于复杂的解决方案。

如果您已经有权限那么:

在您的服务 class 或其他 service/activity 中,您可以将 "component hability" 切换为收听通知​​:

    public void tryReconnectService() {
        toggleNotificationListenerService();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            ComponentName componentName =
                    new ComponentName(getApplicationContext(), NotificationReaderV2Service.class);

            //It say to Notification Manager RE-BIND your service to listen notifications again inmediatelly!
            requestRebind(componentName);
        }
    }

/**
* Try deactivate/activate your component service
*/
    private void toggleNotificationListenerService() {
        PackageManager pm = getPackageManager();
        pm.setComponentEnabledSetting(new ComponentName(this, NotificationReaderV2Service.class),
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
        pm.setComponentEnabledSetting(new ComponentName(this, NotificationReaderV2Service.class),
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
    }

你的通知监听器,是一个SERVICE,它可以被系统杀死,你可以把你的服务做为FOREGROUND来大大降低系统杀死你的服务的可能性。

@Override
    public void onListenerConnected() {
        super.onListenerConnected();
        Log.d(TAG, "Service Reader Connected");
    Notification not = createNotification();
    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    if (mNotificationManager != null) {
        mNotificationManager.notify(NOTIFICATION_ID, not);
    }

    startForeground(NOTIFICATION_ID, not);

    //Alarm to auto - send Intents to Service to reconnect, you can ommit next line.
    alarmIt();
}

如果你更喜欢"safe",你可以编程不友好的电池警报,请尝试使用不精确的警报,用户的电池会很高兴:

private void alarmIt() {
    Log.d(TAG, "ALARM PROGRAMMATED at"+HotUtils.formatDate(new Date()));
    Calendar now = Calendar.getInstance();
    now.setTimeInMillis(System.currentTimeMillis());
    now.set(Calendar.MINUTE, now.get(Calendar.MINUTE) + 1);

    Intent intent = new Intent(this, NotificationReaderV2Service.class);
    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
    intent.setAction(REBIND_ACTION);

    PendingIntent pendingIntent = PendingIntent.getService(this, 0,
            intent, 0);

    AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    //The alarms that are repeated are inaccurate by default, use RTC_WAKE_UP at your convenience.
    //Alarm will fire every minute, CHANGE THIS iF DO YOU CAN, you can't use less than 1 minute to repeating alarms.
    manager.setRepeating(AlarmManager.RTC_WAKEUP, now.getTimeInMillis(), 1000 * 60 * 1, pendingIntent);
}

然后阅读重新连接服务绑定的意图:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "Notification service onStartCommandCalled");
    if (intent!=null && !HotUtils.isNullOrEmpty(intent.getAction()) && intent.getAction().equals(REBIND_ACTION)){
        Log.d(TAG, "TRYING REBIND SERVICE at "+HotUtils.formatDate(new Date()));
        tryReconnectService();//switch on/off component and rebind
    }
    //START_STICKY  to order the system to restart your service as soon as possible when it was killed.
    return START_STICKY;
}

Keep in mind that doing all these steps you can sure that your service will be killed anyway by the system but this code will restart the service and make it harder to kill it.

也许,如果你想要更多的确定性(也许这没用)

我想补充一个经常被遵循的常见错误,切勿覆盖 onBind 和 onUnbind 方法或覆盖 INTENT ACTION。 这将导致您的服务无法连接并且永远不会 运行 onListenerConnected 保持 Intent 原样,在大多数情况下您不需要对其进行编辑。

我遇到了同样的问题。以下是我做过的一些事情,现在对我来说效果很好。

  1. 覆盖 onStartCommand,调用 super 和 return START_STICKY;
  2. 重写 onNotificationRemoved,调用 super 并添加一个 toast,这样您就可以在 android 本身知道无论何时您滑动通知,您的服务都还没有结束。
  3. 从省电列表中排除您的应用(设置-> 电池-> 省电排除)

Post 这个服务即使在主应用程序崩溃后也不会停止。我现在不需要重新启动来重新启动它。