Broadcast Receiver within a Service
Asked Answered
C

2

93

I am trying to start up a BroadcastReceiver within a Service. What I am trying to do is have a background running service going that collects incoming text messages, and logs incoming phone calls. I figured the best way to go about this is to have a service running that incorporates a broadcast receiver that can catalog either.

How do i go about doing this? I already have my service up and running.

Colpin answered 1/2, 2012 at 7:10 Comment(0)
B
132

as your service is already setup, simply add a broadcast receiver in your 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
      }     
   }
};

in your service's onCreate do this:

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

and in your service's onDestroy:

unregisterReceiver(receiver);

and you are good to go to receive broadcast for what ever filters you mention in onCreate. Make sure to add any permission if required. for e.g.

<uses-permission android:name="android.permission.RECEIVE_SMS" />
Balneology answered 1/2, 2012 at 7:23 Comment(11)
Ive noticed I cannot pass data by intent.setData(myUri) while sending sendBroadcas(intent) and braoadcastReceiver doesn't work in that case, is it right?Rumpf
I am little confuse about the service life-cycle when it has BroadcastReceiver (in my case download BroadcastReceiver)Phalansterian
@Balneology Did you set this BroadcastReceiver in your Manifest?Leftwards
@Leftwards No, you don't need to register such receivers in manifest.Balneology
@Balneology Your code uses an IntentFilter in the Service's onCreate() and registers the receiver. Further below though you mention filtering in "onStartCommand" Did you mean to say in "onCreate" or am I missing something?Hurff
@Hurff Thanks for pointing out. It was a mistake which is fixed now :)Balneology
@Balneology I have a similar question listed here: #50520719 Any thoughts on how to fix?Hurff
Hey i wanna ask if i define BroadcastReceiver in Service not in mainactivity, will it will consume more battery , because there are two process are running for single app.. Or it will be ok my app will consume same amount of battery and ram in a device..Edema
@SayyedRizwan Your service and BroadcastReceiver will run under same process and most probably same thread (unless you create a new one). Battery consumption depends on how you have defined your thread (background/Foreground) and the amount of broadcasts coming in.Balneology
@Balneology can you solve this question? https://mcmap.net/q/375186/-can-39-t-do-heavy-work-on-broadcast-receiver-which-is-inside-the-service/5359340Obstruct
I am not receiving any(!) intents in my broacast receiver. What could be the reason for this?Atronna
E
26

The better pattern is to create a standalone BroadcastReceiver. This insures that your app can respond to the broadcast, whether or not the Service is running. In fact, using this pattern may remove the need for a constant-running Service altogether.

Register the BroadcastReceiver in your Manifest, and create a separate class/file for it.

Eg:

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

When the receiver runs, you simply pass an Intent (Bundle) to the Service, and respond to it in onStartCommand().

Eg:

public class FooReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // do your work quickly!
        // then call context.startService();
    }   
}
Emmetropia answered 1/2, 2012 at 7:29 Comment(6)
I want the broadcast to be within the life cycle of the service, so that the app is only querying messages/phone calls according to the service time line. Does this method enable that? it looks like you have set it up so the reception of the broadcast sets off the service.Colpin
This implementation would start the Service if it was not already running, or pass a new Intent if it is (for retrieval in onStartCommand). If you only want it to run when the Service is live, you could programmatically enable/disable the Receiver component through the PackageManager's setComponentEnabledSetting().Emmetropia
Waqas's answer may your best option, if you only want the Receiver alive when the Service is running.Emmetropia
If you don't have an Activity, it won't work for API 3.1 and higher: ashimita.blogspot.com.tr/2012/04/…Sines
As of Android 3.1 the Android system excludes all receiver from receiving intents by default if the corresponding application has never been started by the user or if the user explicitly stopped the application via the Android menu. vogella.com/tutorials/AndroidBroadcastReceiver/article.htmlFichte
The problem is when you kill the application broadcast receiver will auto stop and app will not work after this.Quilting

© 2022 - 2024 — McMap. All rights reserved.