The system broadcasts messages. You can also broadcast messages within your app and to other apps. Use filters to choose which broadcasts you receive
Let them know you’re around: Register your receiver
Broadcast messages notify apps of events that have occurred inside an app or within the system. These Broadcast messages make it possible for your app to react to device changes and events in other apps.
You can register a Broadcast Receiver in your app to listen for and respond to these messages. There are two ways of registering a receiver:
- Register it dynamically in code – You’d do it this way if the receiver is used to update your app’s User Interface. These receivers won’t receive broadcasts if the app is not running
- Register it statically in the AndroidManifest.xml file – These are known as manifest receivers. App’s with manifest receiver’s don’t have to be running to receive broadcasts
Choose your friends: Creating intent filters and broadcast receivers
We use intents to broadcast the messages and intent filters to make sure that we receive the correct messages.
Intent filters specify which intents our broadcast receiver is interested in receiving. We must include an intent filter when we register our receiver:
- Include a filter in the manifest file - Use the
element when you register the receiver - Include a filter in code - Create and include an IntentFilter object when you register the receiver
There are three characteristics of the intent that you can filter:
- action – you must include this string. It identifies the event being broadcast. It should be unique. The best practice is to use the Java package name format
- category – optional. Include this to give more information about the action
- data – optional. The Uri of data to use with the action
Let the world know: Broadcasting a message
What’s the system up to? Native broadcast intents
The system broadcasts intents signalling changes within the device’s system. These are native broadcast intents. You can register receivers in your app to receive these broadcasts. Here are two examples:
- ACTION_BOOT_COMPLETED – indicates that the device has completed its start-up sequence
- ACTION_TIMEZONE_CHANGED – indicates that the device’s timezone has changed
There are other native broadcasts that you can receive.
The system broadcasts Native broadcast messages that your app can receive. You can broadcast Local messages within your app as well as Globally to other apps. Your app can also receive Global messages from other apps
It’s in the intent: Your broadcast intents
Use intents to broadcast your own messages.
You can provide information for three characteristics when you create your broadcast intent:
- action – you must include this string. It identifies the event being broadcast. It should be unique so the best practice is to use the Java package name format
- category – optional. Include this to give more information about the action
- data – optional. The Uri of data to use
You can also include primitive data in the intent as key/value pairs using the putExtra() methods.
Once you have created your message intent, you pass it to one of the Context API’s broadcast methods to broadcast.
Tip. If your broadcasts are only meant for your app’s components then you should use the LocalBroadcastmanager class. The advantages to this are:
- broadcasted data won’t leave your app
- other apps can’t send these broadcasts to your app
- it’s more efficient than global broadcasts
You’ve got two choices: The two Broadcast classes
2 classes of broadcasts:
- Normal broadcasts – Broadcasts are sent to all interested receivers at the same time. Any receiver can receive the broadcasts in no particular order. These receivers can’t return a result and can’t abort the broadcast. However, the system may decide to deliver them one at a time
- Ordered broadcasts – delivered to one receiver at a time. The receiver’s priority determines the order in which the intent is received. Receivers can then modify the intent. The last receiver receives the latest broadcast intent. Receivers can abort the broadcast so that lower priority receivers won’t receive it
And it lingers on: Broadcasting sticky intents
Sticky broadcast intents remain valid after the broadcast has finished. Any future registration of a receiver with the correct filter will receive this intent as if it had just been broadcast.
Many of the systems broadcast messages use sticky intents. You can also broadcast your own sticky intents.
You shouldn’t use sticky broadcast intents for local broadcasts. Any app can watch your sticky broadcast and send their own values back to you – as can happen when using any broadcast within your app.
Broadcasts are really meant for cross-app communication. Rather use the local broadcast manager for broadcasting intents within your app.
Don’t get hacked! Security
Broadcasts are meant to be used across applications. This makes them open to abuse.
Keep the following in mind when using the global broadcast receivers (when using the Context API’s):
- The intent namespace is global – make sure that your action names and strings use a unique namespace which you own. Else it could conflict with other apps
- When using registerReceiver(receiver, filter) – any app can send broadcasts to that receiver. You can control who can send broadcasts to it by using permissions as described below
- When you publish a receiver in the manifest file with filters – other apps can send broadcasts to it regardless of the filters. You can make the receiver unavailable to them by using the android:exported attribute set to false
- When you use sendBroadcast(intent) – other apps can receive the broadcast. You can control who receives the broadcast by using permissions. (from Ice Cream Sandwich and up you can restrict the broadcast to a single app with Intent.setpackage)
If you only want to broadcast intents within your app then use the local broadcast manager and you won’t have these security problems.
Have you got permission? Access permissions
Access permissions can be enforced by either the receiver or the sender of a broadcast:
- When broadcasting – include a permission parameter to sendBroadcast() or sendOrderedBroadcast(). Only receivers with this permission will be able to receive these broadcasts
- When receiving a broadcast – include a permission parameter when registering the receiver. Only broadcasters with this permission will be able to send an intent to this receiver
From cradle to grave: The Receiver lifecycle
The BroadcastReceiver object is no longer valid after onReceive() has executed so you can’t execute any asynchronous operations. The receiver would probably have been killed before the async operation completes.
Neither can you show a dialog or bind to a service. You can, however start a service and send a notification.
How long will the host be around? The Process lifecycle
The process running the broadcast receiver’s onReceive() method is considered to be a foreground process. The system will only destroy it in exceptional circumstances if its resources are needed elsewhere.
Once onReceive() has finished executing, the broadcast receiver is considered to be no longer active. Its hosting process is now the same as any of the other components running in it. If the process is only hosting the broadcast receiver then the system considers the process to be empty and will kill it for its resources.
If you need to keep the process alive then let the receiver start a service.
Have a look at our tutorial, Android BroadcastReceivers: A Tutorial where we show you how you can use Broadcast Receivers in your apps.
I hope that you have found this tutorial helpful.