Tech tip of this week

Understanding Android Broadcast Receivers

A broadcast receiver is an Android component which allows you to register for system or application events. All registered receivers for an event are notified by the Android run time once this event happens.

Create Broadcast Receiver:

Create Receiver class by extending BroadcastReceiver class.
Below onReceive() method will execute whenever your receiver gets notifications whenever the system event, for which it is registered, occurs.

public class MyReceiver extends BroadcastReceiver 
{
     @Override
     public void onReceive(Context context, Intent intent) 
     {
        // Implement code here to be performed when broadcast is detected
     }
}

The Broadcast Receiver object is active only for the duration of onReceive (Context, Intent). Once your code returns from this function, 
the system considers the object to be finished and no longer active.

When a matching broadcast is detected, the onReceive() method of the broadcast receiver is called, at which point the method has 10 seconds time within which to perform any necessary tasks before returning. So, Don't perform any long operations on onReceive() method. To perform long running operations inside onReceive() method, always start Services or use goAsync() method.

you can use goAsync() method to create another thread to perform long operations. This can be called by an application in onReceive(Context, Intent) to allow it to keep the broadcast active after returning from that function. This does not change the expectation of being relatively responsive to the broadcast (finishing it within 10s), but does allow the implementation to move work related to it over to another thread to avoid glitching the main UI thread due to disk IO.

You cannot launch a popup dialog in your implementation of onReceive() and also you can not bind to existing service.For the former, you should instead use the NotificationManager API. For the latter, you can use Context.startService() to send a command to the service.

Register Broadcast Receiver:

Broadcast receivers can be registered in two ways.
  • Static: With this approach, your receiver will be active to listen for events even if your application is not launched.
       Use <receiver> tag to register broadcasts in manifest file.
       <receiver
               android:name="com.example.techchai
               android:exported="true" >
               <intent-filter>
                     <action android:name="com.example.broadcast" />
               </intent-filter>
       </receiver>

  • Dynamic: Receivers are tightly coupled with Activity or Fragment life cycles. This receiver will listen for events only when your application is active only.
       IntentFilter filter = new IntentFilter("com.example.Broadcast");
       MyReceiver receiver = new MyReceiver();
       registerReceiver(receiver, filter);

    • When a broadcast receiver registered in code is no longer required, it may be unregistered via a call to the unregisterReceiver(receiver) method of the activity class. 
    • Dynamically registered receivers are called on the UI thread. Dynamically registered receivers blocks any UI handling and thus the onReceive() method should be as fast as possible.

Types of Broadcast Receivers:
  • Normal BroadcastReceiver: (sent with Context.sendBroadcast) are completely asynchronous. All receivers of the broadcast are run in an undefined order, often at the same time.This is more efficient, but means that receivers cannot get the results.
  • Ordered BroadcastReceiver: (sent with Context.sendOrderedBroadcast) are delivered to one receiver at a time..are completely synchronous. These will follow a specific order.The order is defined using android:priority attribute in Manifest file. The receivers with greater priority would receive the broadcast first. In case there are receivers with same priority levels, the broadcast would not follow an order. Sometimes to avoid system overload, run time system delivers the broadcasts one at a time, even in case of normal broadcasts. However, the receivers still cannot use the results.
  • Sticky BroadcastReceiver: This method is deprecated in API level 21 due to security concerns.

Security:

As the broadcast receivers have a global work-space, security is very important concern here. If you do not define the limitations and filters for the registered receivers, other applications can abuse them.
  • When you use registerReceiver(BroadcastReceiver, IntentFilter), any application may send broadcasts to that registered receiver. You can control who can send broadcasts to it through permissions.
  • When you use sendBroadcast(Intent) normally any other application can receive these broadcasts. You can control who can receive such broadcasts through permissions. Alternatively, you can also safely restrict the broadcast to a single application with Intent.setPackage.
  • Whenever you publish a receiver in your application’s manifest, make it unavailable to external applications by using android: exported=”false”. 

Conclusion:

If you don't need to send broadcasts across applications, consider using LocalBroadcastManager. This will give you a much more efficient implementation (no cross-process communication needed) and allow you to avoid thinking about any security issues related to other applications being able to receive or send your broadcasts.

Refer usage of LocalBroadcastManager.

No comments:

Post a Comment