Using Broadcast receivers is good practice if you want to send and receive data between different applications. However its not good at all if you are using them for communication internal to application.
There are many reasons for NOT using broadcast:
Read more about security issues and configuration of broadcast at developer.android
Instead of using normal broadcast we should use Local broadcast for sending and receiving in-app messages between activities and services. Local broadcast is included in android 3.0 and is provided as support package v4 for early release development. For setting up support library read developer.android
ResultReceiver can be used to return data back to activity. Here is a simple IntentService: Providing data back to Activity #android .However by ResultRceiver, we can only return data to that specific activity which started the service.
To send data/intent application-wide, LocalBroadcasts should be used. LocalBroadcastManager is used to send and receive local broadcast. Lets start with a simple example. We have a simple IntentService say MyIntentService:
You just need to define service in AndroidManifest.xml:
Browse and download source MyLocalbroadcastManager.
There are many reasons for NOT using broadcast:
- A broadcast is sent system-wide, so this is not performance efficient.
- When we use broadcast receiver and sender, any other application can send and receives broadcast messages to and from our application. This can be a serious security thread for our application.
Read more about security issues and configuration of broadcast at developer.android
Instead of using normal broadcast we should use Local broadcast for sending and receiving in-app messages between activities and services. Local broadcast is included in android 3.0 and is provided as support package v4 for early release development. For setting up support library read developer.android
ResultReceiver can be used to return data back to activity. Here is a simple IntentService: Providing data back to Activity #android .However by ResultRceiver, we can only return data to that specific activity which started the service.
To send data/intent application-wide, LocalBroadcasts should be used. LocalBroadcastManager is used to send and receive local broadcast. Lets start with a simple example. We have a simple IntentService say MyIntentService:
package sohail.aziz.mylocalbroadcast; import android.app.IntentService; import android.content.Intent; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; public class MyIntentService extends IntentService{ //ACTION should include application package convention, just to show that this can //be any string public static final String ACTION="mycustomactionstring"; public MyIntentService() { super("MyIntentService"); // TODO Auto-generated constructor stub Log.d("sohail","service started"); } @Override protected void onHandleIntent(Intent arg0) { // TODO Auto-generated method stub Log.d("sohail","onHandleIntent called"); Intent in=new Intent(ACTION); //you can put anything in it with putExtra Log.d("sohail","sending broadcast"); LocalBroadcastManager.getInstance(this).sendBroadcast(in); } }A simple IntentService which sends local broadcast application-wide. Lets receive this in activity.
package sohail.aziz.mylocalbroadcast; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MylocalbroadcastExampleActivity extends Activity implements OnClickListener{ /** Called when the activity is first created. */ TextView tv; Button bt; @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); IntentFilter iff= new IntentFilter(MyIntentService.ACTION); LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, iff); } private BroadcastReceiver onNotice= new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // intent can contain anydata Log.d("sohail","onReceive called"); tv.setText("Broadcast received !"); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tv=(TextView)findViewById(R.id.tvResults); bt= (Button)findViewById(R.id.btStart); bt.setOnClickListener(this); } @Override public void onClick(View v) { if(v.getId()==R.id.btStart){ Log.d("sohail","starting service"); Intent i= new Intent(this, MyIntentService.class); startService(i); } } }Here we are registering broadcast receiver onNotice as LocalBroadcast Receiver. Intent-filter is defined with ACTION defined in MyIntentService.
You just need to define service in AndroidManifest.xml:
<service android:name=".MyIntentService" ></service>and thats it !
Browse and download source MyLocalbroadcastManager.
hi,
ReplyDeleteI didn't get the following: is LocalBroadcastManager available for Android 2.3.3?
thanks in advance for your answer
No, its not. But you can use it in 2.3.3 with support library as explained above.
DeleteThank you for this. After looking at no less than about 30 examples and none of them working, including the pieces on the android developer site, or not having any flaws/bugs/deprecations, yours works and is a complete example... whoohooo!
ReplyDeleteAre the broadcasts sticky?
ReplyDeleteIf not the callback could be lost during an orientation change.
FYI, If you use a static receiver LocalBroadCastManager won't work.
ReplyDeleteIs it possible to send broadcasts from Service class (not an IntentService)? How do I get a hold of LocalBroadcastManager then? Thank you.
ReplyDeleteHello
ReplyDeleteIm trying to use your example in my application service, however
LocalBroadcastManager.getInstance(this).sendBroadcast(msg);
always produces the error
getinstance(android.content.context) in LocalBroadcastManager cannot be applied to (NAME OF MY SERVICE)
Do you have any suggestions as to why ?
Thank you