2

Je développe une application qui doit exécuter du code (Networking) à chaque fois qu'un SMS est reçu.
Dans l'API 25 et inférieur c'est bien, j'inscris un receiver implicite dans le fichier manifeste et démarre mon service dans la classe spécifiée qui a étendu BroadcastReceiver. Dans l'API 26, cependant, vous ne pouvez pas enregistrer android.provider.Telephony.SMS_RECEIVED dans un receiver car cela ne fonctionnera pas.Exécuter le service sur les SMS entrants dans android Oreo

De la documentation Android:

Remarque: Si votre application cible niveau de l'API 26 ou plus, vous ne pouvez pas utiliser le manifeste de déclarer un récepteur pour les émissions implicites (émissions qui ne ciblent pas votre application spécifique), à ​​l'exception pour quelques émissions implicites qui sont exemptées de cette restriction. Dans la plupart des cas, vous pouvez utiliser des tâches planifiées à la place.

J'ai lu plusieurs articles comme this one on medium. Il existe des solutions comme JobScheduler ou Explicit Receiver, mais la première est utilisée pour les changements d'état du réseau et je n'ai pas trouvé de moyen de déclencher le travail sur l'événement SMS_RECEIVED et le second est valide jusqu'à ce que votre activité soit opérationnelle.

En raison de la nature de mon application, j'ai besoin d'écouter les SMS entrants, que l'application soit en cours d'exécution ou non. Comment faire cela dans API 26+?

Modifier

Peut-être que le code in JobInfoBuilder doc on android website pourrait aider. Il surveille les changements dans les photos sur un appareil et démarre le travail sur le changement. Cependant, je ne peux pas trouver un bon Uri faire la même chose avec le SMS (même pas sûr s'il est possible de surveiller SMS via ContentObserver)

+0

Je pense que le planificateur de travaux avec la méthode de vérification périodique peut être la bonne solution. – VVB

+0

@VVB Je suis en train de développer une application TTS qui devrait jouer le son quand le SMS est reçu, mais il semble que baisser le délai pour détecter les SMS reçus a un impact négatif sur les performances et ce n'est pas une bonne solution. – szamani20

+2

L'action 'SMS_RECEIVED' est exemptée des nouvelles restrictions de diffusion implicites. https://developer.android.com/guide/components/broadcast-exceptions.html –

Répondre

2

Puisqu'il ya beaucoup de façons de faire le travail dans Android O, je poste cette réponse et mentionne mon approche pour résoudre le problème. Évidemment, par problème, je veux dire le problème général pas le récepteur SMS_RECEIVED lui-même.

Je commence un service de premier plan et là j'enregistrer un récepteur dynamique ou explicite d'écouter les appels entrants (par exemple):

En MainActivity.java:

String action = "START" 
final Intent intent = new Intent(this, CallMonitorService.class); 
intent.setAction(action); 
startService(intent); 

Dans CallMonitorService.java méthode onCreate() où Je BroadcastReceiver callExplicitReceiver comme un champ:

final IntentFilter intentFilter = new IntentFilter(); 
    intentFilter.setPriority(2147483647); 
    intentFilter.addAction("android.intent.action.PHONE_STATE"); 
    this.callExplicitReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { 
       // do the stuff here 
      } 
     } 
    }; 
    registerReceiver(callExplicitReceiver, intentFilter); 

puis à onStartCommand():

if (intent.getAction().equals("START")) { 
     Intent callServiceNotificationIntent = new Intent(this, MainActivity.class); 
     callServiceNotificationIntent.setFlags(
      Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
     PendingIntent pendingIntent = PendingIntent 
      .getActivity(this, CALL_SERVICE_REQUEST_CODE, 
        callServiceNotificationIntent, CALL_SERVICE_FLAG); 

     Notification notification = new NotificationCompat.Builder(this) 
      .setContentTitle(CALL_NOTIFICATION_CONTENT_TITLE) 
      .setTicker(CALL_NOTIFICATION_TICKER) 
      .setContentText(CALL_NOTIFICATION_CONTENT_TEXT) 
      .setSmallIcon(R.drawable.ic_info_outline_black_24dp) 
      .setContentIntent(pendingIntent) 
      .setOngoing(true) 
      .build(); 
     startForeground(CALL_NOTIFICATION_ID, notification); 
    } 

et enfin:

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    unregisterReceiver(callExplicitReceiver); 
} 

Je pense à cela comme une bonne approche car l'utilisateur est informé du service en cours d'exécution en raison de la notification undismissable et c'est ce que Android Oreo veut cependant par un bouton de l'utilisateur de l'application pouvait arrêter le service et le récepteur de surveillance en conséquence directe de la destruction du service (j'ai effacé cette partie du code).

1

Je pense que vous êtes sûr que SMS_RECEIVED_ACTION est présent dans la exempté actuelle émission implicite list. De plus, en recevant la diffusion du système, vous pouvez soit démarrer un service de premier plan, soit planifier un travail (pour effectuer le fonctionnement du réseau dans votre cas). De plus, j'utilise également la même action et lors des tests, cela semble fonctionner.

+1

Merci pour votre réponse. J'ai aussi besoin de quelques autres récepteurs qui ne sont pas dans cette liste. Mon approche consistait à démarrer un service de premier plan et à y enregistrer un récepteur dynamique (explicite) et à redémarrer le service au démarrage du système. Je posterai mon approche en réponse. – szamani20