Récepteur de diffusion dans un service

90

J'essaye de démarrer un BroadcastReceiverdans un Service. Ce que j'essaie de faire, c'est d'avoir un arrière-plan en cours d'exécution servicequi collecte les messages texte entrants et enregistre les appels téléphoniques entrants. J'ai pensé que la meilleure façon de procéder est d'avoir un servicefonctionnement qui incorpore un récepteur de diffusion qui peut cataloguer l'un ou l'autre.

Comment procéder? J'ai déjà mon service opérationnel.

Utopia025
la source

Réponses:

127

comme votre service est déjà configuré, ajoutez simplement un récepteur de diffusion dans votre service:

private final BroadcastReceiver receiver = new BroadcastReceiver() {
   @Override
   public void onReceive(Context context, Intent intent) {
      String action = intent.getAction();
      if(action.equals("android.provider.Telephony.SMS_RECEIVED")){
        //action for sms received
      }
      else if(action.equals(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED)){
           //action for phone state changed
      }     
   }
};

dans votre service, onCreatefaites ceci:

IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
filter.addAction("your_action_strings"); //further more
filter.addAction("your_action_strings"); //further more

registerReceiver(receiver, filter);

et à votre service onDestroy:

unregisterReceiver(receiver);

et vous êtes prêt à recevoir des émissions pour tous les filtres que vous mentionnez onCreate. Assurez-vous d'ajouter une autorisation si nécessaire. par exemple

<uses-permission android:name="android.permission.RECEIVE_SMS" />
waqaslam
la source
J'ai remarqué que je ne peux pas transmettre de données par intent.setData (myUri) lors de l'envoi de sendBroadcas (intent) et braoadcastReceiver ne fonctionne pas dans ce cas, n'est-ce pas?
deadfish
Je suis un peu confus quant au cycle de vie du service lorsqu'il a BroadcastReceiver (dans mon cas, téléchargez BroadcastReceiver)
Android Man
1
@waqaslam Avez-vous défini ce BroadcastReceiver dans votre manifeste?
IgorGanapolsky
2
@IgorGanapolsky Non, vous n'avez pas besoin d'enregistrer de tels récepteurs dans le manifeste.
waqaslam
2
@SayyedRizwan Votre service et BroadcastReceiver fonctionneront sous le même processus et très probablement le même thread (sauf si vous en créez un nouveau). La consommation de la batterie dépend de la façon dont vous avez défini votre fil de discussion (arrière-plan / premier plan) et de la quantité de diffusions
entrantes
24

Le meilleur modèle est de créer un modèle autonome BroadcastReceiver. Cela garantit que votre application peut répondre à la diffusion, qu'elle soit en Servicecours d'exécution ou non . En fait, l'utilisation de ce modèle peut supprimer Servicecomplètement le besoin d'un fonctionnement constant .

Enregistrez le BroadcastReceiverdans votre manifeste et créez une classe / un fichier distinct pour celui-ci.

Par exemple:

<receiver android:name=".FooReceiver" >
    <intent-filter >
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

Lorsque le récepteur s'exécute, il vous suffit de passer un Intent( Bundle) au Service, et d'y répondre onStartCommand().

Par exemple:

public class FooReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // do your work quickly!
        // then call context.startService();
    }   
}
Paul Burke
la source
6
Je souhaite que la diffusion s'inscrive dans le cycle de vie du service, de sorte que l'application n'interroge que les messages / appels téléphoniques en fonction de la chronologie du service. Cette méthode permet-elle cela? il semble que vous l'avez configuré pour que la réception de l'émission déclenche le service.
Utopia025
Cette implémentation démarrerait le Servicesi elle n'était pas déjà en cours d'exécution, ou transmettrait un nouveau Intentsi tel est le cas (pour la récupération dans onStartCommand). Si vous voulez seulement à courir lorsque le Serviceest en direct, vous pouvez activer programme / désactiver le Receivercomposant à travers les PackageManager« s setComponentEnabledSetting().
Paul Burke
4
La réponse de Waqas est peut-être votre meilleure option, si vous ne voulez que le Receivervivant lorsque le Serviceest en cours d'exécution.
Paul Burke
3
Si vous n'avez pas d'activité, cela ne fonctionnera pas pour l'API 3.1 et versions
elif
1
À partir d'Android 3.1, le système Android exclut par défaut tous les récepteurs de recevoir des intentions si l'application correspondante n'a jamais été démarrée par l'utilisateur ou si l'utilisateur a explicitement arrêté l'application via le menu Android. vogella.com/tutorials/AndroidBroadcastReceiver/article.html
Juraj Petrik