BroadcastReceiver of four Android Components
Introduction to BroadcastReceiver
BroadcastReceiver broadcast is a kind of subscription-Notification event. The broadcast receiver sends a broadcast to the Android system register (subscription broadcast), and the Broadcast Sender sends a broadcast to the Adnroid system sendBroadCast (send broadcast ), then, the Android system notifies all the recipients who have registered the broadcast. After receiving the broadcast, the broadcast Receiver realizes what he wants to do (this generally does not exceed 10 s, otherwise, ANR will appear in the application ).
BroadCast classification:
Unordered Broadcast: That is, normal broadcast, as long as the broadcast receiver registered with the action can receive the broadcast, there is no order.
Ordered Broadcast: The broadcast receiver receives the broadcast based on its priority. In addition, the broadcast receiver can transmit the processed result to the next broadcast receiver through the setResultExtras (Bundle) method.
Viscous Broadcast: SendStickyBroadcast (Intent) method for sending broadcast calls, which is different from sendBroadcast (Intent.
Sticky broadcasts are retained in the memory until a broadcast receiver registers for the broadcast. It is not easy to explain. I will take a look at the example later.
Use of BroadCase: 1. Normal broadcast:
Depending on the registration method, static registration broadcast and Dynamic Registration broadcast can be divided.
1. Static registration of broadcast use instances
AndroidManifest. xml is as follows:
2. Broadcast receiver implementation:
Package com. xjp. mybroadcast; import android. content. broadcastReceiver; import android. content. context; import android. content. intent;/*** Description: static broadcast receiver * User: xjp * Date: 2015/5/14 * Time: */public class BroadCastReceive1 extends BroadcastReceiver {@ Override public void onReceive (Context context, intent intent) {// After TODO receives the broadcast, it processes its own tasks. String action = intent. getAction (); String result = intent. getStringExtra ("key"); MyLog. d ("the BroadCast action is" + action + "the BroadCast receive result is" + result );}}
3. Implement broadcast senders as follows:
Package com. xjp. mybroadcast; import android. content. intent; import android. OS. bundle; import android. support. v7.app. actionBarActivity; import android. view. view; import android. widget. button; public class MainActivity extends ActionBarActivity implements View. onClickListener {private Button btnSend; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); btnSend = (Button) findViewById (R. id. button); btnSend. setOnClickListener (this) ;}@ Override public void onClick (View v) {switch (v. getId () {case R. id. button: sendBraodCast (); break;} private void sendBraodCast () {/*** declares the action of static broadcast */String action = "com. xjp. mybroadcast. broadCastReceive1 "; Intent intent = new Intent (action); intent. putExtra ("key", "static broadcast test"); sendBroadcast (intent );}}
The output is as follows:
4. Static registration broadcast features: the registration broadcast is in AndroidManifest. xml. The broadcast receiver must re-inherit the BroadcastReceiver class to implement the onReceive () abstract method. The application exits without canceling the broadcast. Therefore, even if another application sends a broadcast of this action after the broadcast exits, the application can still receive the broadcast, that is, the above results will be printed. Ii. Dynamic broadcasting:
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. support. v7.app. actionBarActivity; import android. view. view; import android. widget. button; public class MainActivity extends ActionBarActivity implements View. onClickListener {private Button btnSend; private BroadCastReceive2 myReceive; private IntentFilter filter; private final static String ACTION = "com. xjp. mybroadcast. broadCastReceive2 "; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); btnSend = (Button) findViewById (R. id. button); btnSend. setOnClickListener (this); myReceive = new BroadCastReceive2 (); filter = new IntentFilter (); filter. addAction (ACTION) ;}@ Override protected void onResume () {/*** register broadcast */LocalBroadcastManager. getInstance (this ). registerReceiver (myReceive, filter); // officially recommended // this. registerReceiver (myReceive, filter); super. onResume () ;}@ Override protected void onPause () {/*** deregister broadcast */LocalBroadcastManager. getInstance (this ). unregisterReceiver (myReceive); // officially recommended // this. unregisterReceiver (myReceive); super. onPause () ;}@ Override public void onClick (View v) {switch (v. getId () {case R. id. button: sendBraodCast (); break;} private void sendBraodCast () {/*** declares the broadcast action */Intent intent = new Intent (ACTION); intent. putExtra ("key", "dynamic broadcast test");/*** the following message is officially recommended for sending broadcasts because it is faster and safer, and will not cause memory leakage */LocalBroadcastManager. getInstance (this ). sendBroadcast (intent); // this. sendBroadcast (intent);}/*** internal class implement broadcast receiver */private class BroadCastReceive2 extends BroadcastReceiver {@ Override public void onReceive (Context context, Intent intent) {// After TODO receives the broadcast, it processes its own tasks. String action = intent. getAction (); String result = intent. getStringExtra ("key"); MyLog. d ("the BroadCast action is" + action + "the BroadCast receive result is" + result );}}}
The dynamic broadcast feature calls the registerReceiver () method in the code to register the broadcast. The broadcast receiver must re-inherit the BroadcastReceiver class to implement the internal class. When an application exits, dynamic broadcast calls the unregisterReceiver () method to cancel the broadcast. If the application is not logged out, the following error is returned:
Therefore, we usually do this by registering a broadcast in onResume () and canceling a broadcast in onPause. After the broadcast is canceled, no broadcast sent by any system is received. 3. Ordered broadcast:
Example:
Package com. xjp. mybroadcast; import android. content. broadcastReceiver; import android. content. context; import android. content. intent; import android. content. intentFilter; import android. OS. bundle; import android. support. v7.app. actionBarActivity; import android. view. view; import android. widget. button; public class MainActivity extends ActionBarActivity implements View. onClickListener {private Butto N btnSend; private BroadCastReceive2 myReceive; private BroadCastReceive3 myReceive3; private IntentFilter filter; private IntentFilter filter3; private final static String ACTION = "com. xjp. mybroadcast. broadCastReceive2 "; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); btnSend = (Button) findViewById (R. id. B Utton); btnSend. setOnClickListener (this); myReceive = new BroadCastReceive2 (); filter = new IntentFilter (); filter. addAction (ACTION); filter. setPriority (2); // sets the broadcast priority,-1000 ~ 1000. The greater the number, the higher the priority. MyReceive3 = new BroadCastReceive3 (); filter3 = new IntentFilter (); filter3.addAction (ACTION); filter3.setPriority (1);} @ Override protected void onResume () {/*** register broadcast */registerReceiver (myReceive, filter); registerReceiver (myReceive3, filter3); super. onResume () ;}@ Override protected void onPause () {/*** deregister broadcast */unregisterReceiver (myReceive); unregisterReceiver (myReceive3); super. onPause ();} @ Override public void onClick (View v) {switch (v. getId () {case R. id. button: sendBraodCast (); break;} private void sendBraodCast () {/*** declares the broadcast action */Intent intent = new Intent (ACTION); intent. putExtra ("key", "ordered broadcast test"); this. sendOrderedBroadcast (intent, null);}/*** internal class implement broadcast receiver */private class BroadCastReceive2 extends BroadcastReceiver {@ Override public void onReceive (Context co Ntext, Intent intent) {// TODO handles its own tasks after receiving the broadcast String action = intent. getAction (); String result = intent. getStringExtra ("key"); MyLog. d ("the BroadCast action is" + action + "the BroadCast receive result is" + result); Bundle bundle = new Bundle (); bundle. putString ("key", "After ordered broadcast processing" + "\ n" + "Send again to the next broadcast receiver"); intent. putExtra ("bundle", bundle); setResultExtras (bundle); // cut off the broadcast and stop sending the broadcast. // AbortBroadcast () ;}}/*** internal class implement broadcast receiver */private class BroadCastReceive3 extends BroadcastReceiver {@ Override public void onReceive (Context context, Intent intent) {// After TODO receives the broadcast, it processes its own tasks. String action = intent. getAction (); // do you want to accept the data Bundle bundle = getResultExtras (true) from receiver2 of the previous broadcast receiver? MyLog. d ("the BroadCast action is" + action + "the BroadCast receive result is" + bundle. getString ("key "));}}}
Ordered broadcast features that the actions of all broadcast recipients are consistent. The sendOrderedBroadcast () method is called for ordered broadcast. The receiver of ordered broadcast needs to call the setPriority () method to set the priority of the broadcast receiver. A larger number gives priority to broadcast. If you need to terminate the broadcast and continue sending the broadcast, you can call the abortBroadcast () method to disable the broadcast. The receiver can pass their processing results to the next receiver through the setResultExtras () method. Then, the receiver can call getResultExtras (true) to determine whether to receive the data transmitted from the previous broadcast. Iv. Viscous broadcast:
For example, you need to add the permission in AndroidManifest. xml:
Send broadcast Activity
Package com. xjp. mybroadcast; import android. content. intent; import android. OS. bundle; import android. support. v7.app. actionBarActivity; import android. view. view; import android. widget. button;/*** send broadcast Activity */public class MainActivity extends ActionBarActivity implements View. onClickListener {private Button btnSend; private final static String ACTION = "com. xjp. mybroadcast. broadCastReceive1 "; private final static String ACTION1 =" com. xjp. mybroadcast. broadCastReceive2 "; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); btnSend = (Button) findViewById (R. id. button); btnSend. setOnClickListener (this) ;}@ Override public void onClick (View v) {switch (v. getId () {case R. id. button: sendBraodCast (); break;} private void sendBraodCast () {/*** declares the broadcast action */Intent intent = new Intent (ACTION); intent. putExtra ("key", "normal broadcast test"); sendBroadcast (intent); Intent intent1 = new Intent (ACTION1); intent1.putExtra ("key", "viscous broadcast test "); sendStickyBroadcast (intent1); startActivity (new Intent (this, RecevieActivity. class ));}}
Activity that receives Broadcast
Package com. xjp. mybroadcast; import android. app. activity; import android. content. broadcastReceiver; import android. content. context; import android. content. intent; import android. content. intentFilter; import android. OS. bundle;/*** Description: Activity that receives broadcast * User: xjp * Date: 2015/5/14 * Time: 17: 03 */public class RecevieActivity extends Activity {private final static String ACTION1 = "com. xjp. mybroadcast. broadCastReceive1 "; private final static String ACTION2 =" com. xjp. mybroadcast. broadCastReceive2 "; private Receive receive; private IntentFilter filter1; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); receive = new Receive (); filter1 = new IntentFilter (); filter1.addAction (ACTION1); filter1.addAction (ACTION2) ;}@ Override protected void onResume. onResume (); registerReceiver (receive, filter1) ;}@ Override protected void onPause () {super. onPause (); unregisterReceiver (receive);} private class Receive extends BroadcastReceiver {@ Override public void onReceive (Context context, Intent intent) {String action = intent. getAction (); String result = intent. getStringExtra ("key"); MyLog. d ("the BroadCast action is" + action + "the BroadCast receive result is" + result );}}}
The output is as follows:
As a result, only the viscous broadcast can receive the broadcast information.
Sticky broadcast features:
You need to add permissions in AndroidManifest. xml.
In addition to calling different sendStickyBroadcast (intent1) methods, stickybroadcast sends the same message.
Generally, a broadcast can only receive the broadcast by registering the broadcast first, while a viscous broadcast can first send the broadcast, register where the broadcast needs to be received, and then register the broadcast to obtain the broadcast result. This is the difference between normal broadcast and viscous broadcast. From the example, we can see that normal broadcasts cannot receive the broadcasts sent by the broadcast senders when they jump to ReceiveActivity. Only viscous broadcasts can receive the broadcasts.
Some people may wonder where to use sticky broadcast ?? In fact, I also saw the detection of battery power in the Android system. Paste the following code:
// Register for the battery changed eventIntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);/ Intent is sticky so using null as receiver works fine// return value contains the statusIntent batteryStatus = this.registerReceiver(null, filter);// Are we charging / charged?int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;boolean isFull = status == BatteryManager.BATTERY_STATUS_FULL;// How are we charging?int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
Broadcast lifecycle:
After the broadcast receiver receives the onReceive () method, the broadcast life cycle ends.
Therefore, the broadcast receiver cannot execute time-consuming tasks of more than 10 s, nor create a Thread in the onReceive () method to execute time-consuming tasks. You can enable a Service to execute time-consuming tasks in the background, for details, refer to the Service lifecycle and usage of four Android components.
The general principle of broadcasting:
We know that only after a broadcast is registered can the broadcast receiver receive the broadcast. One behavior of broadcast registration is to register the IntentFilter you are interested in to the Android system's AMS (ActivityManagerService), which stores a list of intentfilters. Broadcast senders send their IntentFilter action to AMS and traverse the IntentFilter list in AMS to see who subscribed to the broadcast, then send the message traversal to the Activity or Service that has registered the corresponding IntentFilter -- that is, the abstract method onReceive () is called. Among them, AMS serves as an intermediate bridge.
System broadcast:
Android has many broadcast systems, such:
Event |
Description |
Intent. ACTION_AIRPLANE_M |
Disable or enable broadcast in flight mode |
Intent. ACTION_BATTERY_CH |
The charging status, or the battery power changes. // The battery charging status and charge level change. |
Intent. ACTION_BATTERY_LO |
Low battery power |
Intent. ACTION_BATTERY_ OK |
Sufficient battery power |
Intent. ACTION_AIRPLANE_MODE_CHANGED |
Disable or enable broadcast in flight mode |
Intent. ACTION_BATTERY_CHANGED |
The charging status, or the battery power changes. The battery charging status and charge level change cannot receive this broadcast through the formation Declaration, only registered through Context. registerReceiver () |
Intent. ACTION_BATTERY_LOW |
Low battery power |
Intent. ACTION_BATTERY_OKAY |
Indicates that the battery power is sufficient, that is, the broadcast is triggered when the battery power changes from low to full. |
Intent. ACTION_BOOT_COMPLETED |
After the system is started, this action is broadcast once (only once ). |
Intent. ACTION_CAMERA_BUTTON |
Broadcast when you press the camera button (hardware button ). |
Intent. ACTION_CLOSE_SYSTEM_DIALOGS |
When the screen times out to lock the screen, when the user presses the power button, long or short press (no matter whether the dialog box is not displayed), the android system will broadcast this Action message. |
Intent. ACTION_CONFIGURATION_CHANGED |
Broadcast sent when the current device settings are changed (including the interface language, device direction, and so on), refer to Configuration. java) |
Intent. ACTION_DATE_CHANGED |
This broadcast is triggered when the device date changes |
Intent. ACTION_DEVICE_STORAGE_LOW |
Broadcast when the device memory is insufficient. This broadcast can only be used by the system, and other apps are not available. |
Intent. ACTION_DEVICE_STORAGE_ OK |
Broadcast is sent when the device memory is not full enough. This broadcast can only be used by the system, and other apps are not available. |
Intent. ACTION_EXTERNAL_APPLICATIONS_AVAILABLE |
Broadcast sent after the mobile APP is completed (mobile refers to APP2SD) |
Intent. ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE |
Broadcast sent when the APP is being moved (mobile refers to APP2SD) |
Intent. ACTION_GTALK_SERVICE_CONNECTED |
Broadcast sent when a connection is established in Gtalk |
Intent. ACTION_GTALK_SERVICE_DISCONNECTED |
Broadcast sent when Gtalk is disconnected |
Intent. ACTION_HEADSET_PLUG |
Broadcast sent when headphones are inserted in the headphone port |
Intent. ACTION_INPUT_METHOD_CHANGED |
Broadcast sent when the input method is changed |
Intent. ACTION_LOCALE_CHANGED |
Broadcast sent when the current region of the device has been changed |
Intent. ACTION_MANAGE_PACKAGE_STORAGE |
Indicates that the notification of the low memory status recognized by the user and package management should start. |
Intent. ACTION_MEDIA_BAD_REMOVAL |
Incorrect SD card removal (correct method to remove SD card: set-SD card and device memory-uninstall SD card), but broadcast, extended media (expansion card) sent when the SD card is removed) the device has been removed from the SD card slot, but the mount point has not been unmounted) |
Intent. ACTION_MEDIA_BUTTON |
Press the "Media Button" Button to broadcast the message. If there is a "Media Button" Button (hardware Button) |
Intent. ACTION_MEDIA_CHECKING |
When an external storage device is inserted, such as the SD card, the system will check the SD card. What is the broadcast? |
Intent. ACTION_MEDIA_EJECT |
A broadcast (such as an SD card or mobile hard disk) sent by an external large-capacity storage device has been unmounted. This broadcast is sent no matter whether it is correctly uninstalled. You want to remove the extended media (unplug the expansion card ). |
Intent. ACTION_MEDIA_MOUNTED |
When an SD card is inserted and properly installed (identified), the extended media is inserted and mounted. |
Intent. ACTION_MEDIA_NOFS |
The extended media exists, but it is included in the Intent. mData field by using a path installation point that is not compatible with FS (or is empty. |
Intent. ACTION_MEDIA_REMOVED |
The external storage device has been removed. This broadcast is sent no matter whether it is correctly uninstalled, and the extended media is removed. |
Intent. ACTION_MEDIA_SCANNER_FINISHED |
Broadcast: a directory of the scanned Media |
Intent. ACTION_MEDIA_SCANNER_SCAN_FILE |
Request the media scanner to scan the file and add it to the media database. |
Intent. ACTION_MEDIA_SCANNER_STARTED; |
Broadcast: Start scanning a directory of Media |
Intent. ACTION_MEDIA_SHARED |
Broadcast: the mounting of the extended media is unmounted because it has been shared as a USB large-capacity storage. |
Intent. ACTION_MEDIA_UNMOUNTED |
Broadcast: Extended media exists, but not mounted) |
Intent. ACTION_PACKAGE_ADDED |
After successful APK installation // broadcast: An application package is installed on the device. // A new application package has been installed on the device, and the data includes the package name (the latest package program cannot receive this broadcast) |
Intent. ACTION_PACKAGE_CHANGED; |
An existing application package has changed, including the package name. |
Intent. ACTION_PACKAGE_DATA_CLEARED |
Broadcast sent when data of an application is cleared (when setting -- Application Management -- select an application and then click "Clear Data ?) // The user has cleared the data of a package, including the package name (the package clearing program cannot receive this broadcast) |
Intent. ACTION_PACKAGE_INSTALL |
A broadcast triggered when a download is triggered and the installation is complete, such as downloading an application in the electronic marketplace? |
Intent. ACTION_PACKAGE_REMOVED |
After an APK is successfully deleted, an existing application package has been removed from the device, including the package name (this broadcast cannot be received by the package program being installed) |
Intent. ACTION_PACKAGE_REPLACED |
Broadcast sent when an existing installation package is replaced (whether the installed APP is newer or older than the previous one ?) |
Intent. ACTION_PACKAGE_RESTARTED |
When a user starts a package again, all processes in the package will be killed, and all running time statuses associated with the package should be removed, including the package name (restarting the package program cannot receive this broadcast) |
Intent. ACTION_POWER_CONNECTED |
Broadcast when an external power supply is plugged in |
Intent. ACTION_POWER_DISCONNECTED |
Broadcast issued when the external power is disconnected |
Intent. ACTION_REBOOT |
Broadcast when the device is restarted |
Intent. ACTION_SCREEN_OFF |
Broadcast after the screen is disabled |
Intent. ACTION_SCREEN_ON |
Broadcast after the screen is opened |
Intent. ACTION_SHUTDOWN |
Broadcast issued when the system is disabled |
Intent. ACTION_TIMEZONE_CHANGED |
Broadcast when the time zone changes |
Intent. ACTION_TIME_CHANGED |
Broadcast sent when the time is set |
Intent. ACTION_TIME_TICK |
Broadcast: the current time has changed (the normal time has elapsed). The current time has changed and is sent every minute. It cannot be received through the component declaration. It is registered only through the Context. registerReceiver () method. |
Intent. ACTION_UID_REMOVED |
A user ID has removed the broadcast from the system. |
Intent. ACTION_UMS_CONNECTED |
Is the broadcast sent when the device is in the USB high-capacity storage status? |
Intent. ACTION_UMS_DISCONNECTED |
Is the broadcast sent when the device has been changed from the USB bulk storage status to the normal status? |
Intent. ACTION_WALLPAPER_CHANGED |
Broadcast when the device wallpaper has changed |