Notification listener service not working after application crashed

I have a problem with my application and would like to report this error.

I am developing an application that can bypass notifications using a NotificationListenerService.

Works well.

But the NotificationListenerService class has a problem I think.

Because if the application crashed, the application cannot bypass the notification at all, ADDITIONALLY restart the phone.

Who can solve this problem?

Please help me.

Bug fixed! But finding a solution isn't easy.

+4


source to share


3 answers


If you already have permissions, follow these steps:

In your service class or other service / activity, you can switch the "hability of the component" to listen for notifications :

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

      

Your notification listener is a SERVICE, it can be killed with System , you can make your service like FOREGROUND to drastically reduce the chances of the system killing your service.

@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();
}

      

If you like "safe" more, you can program bad battery alarms, try using inaccurate alarms, please, the user's battery will be happy:



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

      

and then read the intent to re-attach the binding to the service:

@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 by following all these steps, you can be sure that your service will be killed anyway by the system, but this code will restart the service and make it difficult to kill it.

You might want to consider using PARTIAL_WAKE_LOCK with your service and execute it in process independently (: remote) if you want even more confidence (it might be useless)

I would like to add a frequently recurring error , NEVER override onBind and onUnbind method or overwrite INTENT ACTION. This will result in your service not being connected and never running onListenerConnected. Keep the intent as is, in most cases you don't need to edit it.

+8


source


I see exactly the same thing. The only "solution" I found was to have the notification listener run in a separate process. Then if the rest of the application crashes, it won't stop the listener. Thus, only after that does the Notification Emergency Recovery Service trigger a restart.



This seems to be a terrible and difficult decision.

0


source


I have the same problem. Here are a few things I've done and now it works great for me.

  1. Override onStartCommand, call super and return START_STICKY;
  2. Override onNotificationRemoved, call super, and add a toast to let you know in Android itself that your service hasn't died yet when you swipe the notification.
  3. Exclude your app from the battery saver list (Settings-> Battery-> Power Saver Exclude)

After that, the service never dies even after the main application crashes. I don't need to reboot now to restart it.

0


source







All Articles