2017-07-16 5 views
3

J'ai un problème avec mon application et je souhaite signaler ce problème.Le service d'écoute de notification ne fonctionne pas après le plantage de l'application

Je développe l'application qui peut analyser les notifications en utilisant NotificationListenerService.

Cela fonctionne bien.

Mais la classe NotificationListenerService a le problème je pense. Parce que, si l'application est plantée, l'application ne peut pas explorer la notification du tout, jusqu'à ce que le téléphone redémarre.

Est-ce que quelqu'un peut résoudre ce problème?

S'il vous plaît aidez-moi.

Le bug est très clair !! Mais il n'est pas facile de trouver la solution ....

Répondre

0

Je vois exactement la même chose à ce sujet. La seule "solution" que j'ai trouvée était de faire fonctionner l'écouteur de notification dans un processus séparé. Ensuite, si le reste de l'application plante, cela n'arrête pas l'auditeur. Donc, ce n'est que dans ce cas précis que le service d'écoute de notification se bloque et nécessite le redémarrage.

Semble une solution terrible et plus compliquée cependant.

4

Si vous avez déjà des autorisations alors:

Dans votre classe de service ou un autre service/activité que vous pouvez changer le "composant hability" pour écouter les 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); 
    } 

Votre écoute de notification , est un service, il peut être tué par le système, vous pouvez faire votre service en tant que FOREGROUND pour réduire considérablement la probabilité que le système va tuer votre 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(); 
} 

Si vous aimez donc plus « sûr », vous pouvez pour programmer les alarmes de batterie sans amis, essayez d'utiliser des alarmes inexactes s'il vous plaît, la batterie de l'utilisateur sera heureux:

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

et ensuite lire l'intention de se reconnecter liaison de 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; 
} 

Gardez à l'esprit que faire toutes ces étapes Vous pouvez être sûr que votre système sera tué par le système, mais ce code va redémarrer le service et le rendre plus difficile à tuer.

Peut-être, vous devriez envisager d'utiliser PARTIAL_WAKE_LOCK avec votre service et l'exécuter dans un processus indépendamment (: à distance) si vous voulez encore plus de certitude (Peut-être que cela est inutile)

Je voudrais ajouter une erreur commune qui est souvent suivie, NE JAMAIS remplacer la méthode onBind et onUnbind ou remplacer l'ACTION INTENTION. Votre service ne sera pas connecté et ne fonctionnera jamais sur onListenerConnected Conserver l'intention telle quelle, dans la plupart des cas vous n'avez pas besoin de la modifier.

+0

Terminé sur cette réponse issuetracker.google.com. Est-ce que ça fonctionne encore? –

+0

Mon service s'exécute 37 jours et survit aux mises à jour du Playstore et à des événements similaires. –

+0

Il survit aussi pour moi. C'est une excellente réponse :) –