Android applications can receive or send messages from the system or other apps via broadcast. Similar to the subscription-publish design pattern. Broadcasts can be made when certain events occur. The system will broadcast when some state changes, such as starting up or charging. The App can also send custom broadcasts. Broadcasting can be used for communication between applications and is a form of IPC.

Type of broadcast

The type of broadcast can also be regarded as the property of the broadcast.

  • Normal Broadcasts

Fully asynchronous broadcast. All broadcast receivers receive the broadcast almost simultaneously. Different apps can register and receive standard broadcasts. Such as system broadcast.

  • Ordered Broadcasts

Synchronous broadcast. Only one broadcast receiver can pick up the broadcast at any one time. The broadcast will not continue until the receiver has finished processing it. An ordered broadcast is a global broadcast.

  • Local Broaddcasts

Only broadcasts sent and received in this App. A receiver registered as a local broadcast cannot receive a standard broadcast.

  • Broadcast with permission

Relevant permissions can be brought when sending the broadcast, and only the App or broadcast receiver that has applied for permissions can receive the corresponding broadcast with permissions. If a permission is applied for in the MANIFEST, the receiver can receive the broadcast without having to apply for permission again.

Receive the broadcast

To create a BroadcastReceiver, call the onReceive() method. You need a class that extends from BroadcastReceiver.

Registration in the broadcast code is called dynamic registration. Registration in androidmanifest.xml is called static registration. Dynamically registered rigid wave receivers must be unregistered. Unregister by calling the unregisterReceiver() method in the onDestroy() method.

Do not add too many logical or time-consuming operations to the onReceive() method. Because threads are not allowed to open in the broadcast receiver, the program will report an error when the onReceive() method runs for a long time without ending. So broadcast receivers are typically used to open other components, such as creating a status bar notification or starting a service.

Create a new MyExampleReceiver that extends from BroadcastReceiver.

public class MyExampleReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context,"Got it",Toast.LENGTH_SHORT).show(); //abortBroadcast(); }}Copy the code

AbortBroadcast () truncates the ordered broadcast

Register a broadcast receiver in androidmanifest.xml; Android :name is the name of the receiver. Broadcast receiver priority can be set:

<intent-filter android:priority="100">

<receiver android:name=".MyExampleReceiver">
    <intent-filter>
        <action android:name="com.rust.broadcasttest.MY_BROADCAST"/>
    </intent-filter>
</receiver>
Copy the code

Let the receiver to receive a “com. Rust. Broadcasttest. MY_BROADCAST” broadcast. This value is passed when sending custom broadcasts (standard broadcasts). Such as:

Intent intent = new Intent("com.rust.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
Copy the code

To send an ordered broadcast, you should call sendOrderedBroadcast()

Intent intent = new Intent("com.rust.broadcasttest.MY_BROADCAST"); SendOrderedBroadcast (intent, null);Copy the code

Send broadcast

The App has three ways to send a broadcast. You use the Intent class to send a broadcast.

sendOrderedBroadcast(Intent, String)

Send an ordered broadcast. Only one broadcast receiver can receive a broadcast at a time. After receiving an ordered broadcast, the receiver can either block the broadcast entirely or pass some information to the next receiver. The order of ordered broadcasts can be affected by the Android: Priority tag. Receivers of the same rank receive broadcasts in random order.

sendBroadcast(Intent)

Broadcasts are sent to all receivers in an undefined order. Also called ordinary broadcasting. This is more efficient, but the receiver cannot pass a message to the next receiver. Such broadcasts cannot be cut off.

* * LocalBroadcastManager sendBroadcast radio can only transfer within the application, and radio receiver can only receives the broadcast from this application. This method is more efficient than global broadcasting (no Interprocess communication, IPC), and you don’t need to worry about other apps receiving your broadcast and other security issues.

Broadcasting and Permissions

Send a broadcast with permissions

When you call sendBroadcast(Intent, String) or sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle), you can specify a permission. A receiver can receive this broadcast only if it has requested the appropriate permissions in the MANIFEST.

For example, send a broadcast with permissions

sendBroadcast(new Intent("com.example.NOTIFY"), Manifest.permission.SEND_SMS);
Copy the code

The app that receives the broadcast must register the corresponding permissions

<uses-permission android:name="android.permission.SEND_SMS"/>
Copy the code

You can also use customization. Use the Permission tag in the manifest

<permission android:name="custom_permission" />
Copy the code

Add it and compile it. You can call the Manifest. Permission. Custom_permission

Receive broadcasts with permissions

If you declare permissions when registering a broadcast receiver, only broadcasts with the permissions will be received.

By declaring permissions in the configuration file, the program can access some key information. For example, the system network status can be queried.

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <! <uses-permission android:name="android.permission.BOOT_COMPLETED">Copy the code

Without permission to apply, the program may be shut down unexpectedly.

Use the sample

Sending and receiving broadcasts. It is divided into two apps: sender and receiver.

Use broadcasts with permissions. System rights and custom rights. Permissions need to be declared in androidmanifest.xml. If you have a custom permission, add a custom permission first.

<! Permission android:name="com.rust.permission_rust_1" /> <uses-permission android:name="com.rust.permission_rust_1" />Copy the code

Send a broadcast with a permission declaration. The recipient (regardless of its own App) needs to apply for permissions in androidmanifest.xml. You also need to declare permissions when registering a receiver.

Sends an ordered broadcast without permission

Intent intent = new Intent(MSG_PHONE); sendOrderedBroadcast(intent, null); Log.d("[rustfisher-app1] "+ intent.getAction());Copy the code

Sender App1 code

private static final String TAG = "rustApp"; public static final String MSG_PHONE = "msg_phone"; public static final String PERMISSION_RUST_1 = "com.rust.permission_rust_1"; // onCreate registerReceiver(mStandardReceiver1, makeIF()); registerReceiver(mStandardReceiver2, makeIF()); registerReceiver(mStandardReceiver3, makeIF()); registerReceiver(mStandardReceiverWithPermission, makeIF(), Manifest.permission.permission_rust_1, null); / / take permissions LocalBroadcastManager. GetInstance (getApplicationContext ()). The registerReceiver (mLocalReceiver1, makeIF ()); LocalBroadcastManager.getInstance(getApplicationContext()) .registerReceiver(mLocalReceiver2, makeIF()); LocalBroadcastManager.getInstance(getApplicationContext()) .registerReceiver(mLocalReceiver3, makeIF()); // unregisterReceiver(mStandardReceiver1); unregisterReceiver(mStandardReceiver2); unregisterReceiver(mStandardReceiver3); unregisterReceiver(mStandardReceiverWithPermission); LocalBroadcastManager.getInstance(getApplicationContext()) .unregisterReceiver(mLocalReceiver1); LocalBroadcastManager.getInstance(getApplicationContext()) .unregisterReceiver(mLocalReceiver2); LocalBroadcastManager.getInstance(getApplicationContext()) .unregisterReceiver(mLocalReceiver3); Private void sendStandardBroadcast() {Intent Intent = new Intent(MSG_PHONE); sendBroadcast(intent); Log.d(TAG, "[rustfisher-app1] Dispatcher Dispatcher "); } / / send broadcast standards with permission private void sendStandardBroadcastWithPermission () {Intent Intent = new Intent (MSG_PHONE); sendBroadcast(intent, PERMISSION_RUST_1); Log.d(TAG, "[rustfisher-app1] Dispatcher Dispatcher standard broadcast with privileges "); } // Send a local broadcast private void sendAppLocalBroadcast() {Intent Intent = new Intent(MSG_PHONE); LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent); Log.d(TAG, "[rustfisher-app1] Dispatcher Dispatcher "); } private IntentFilter makeIF() { IntentFilter intentFilter = new IntentFilter(MSG_PHONE); intentFilter.addAction(Intent.ACTION_TIME_TICK); intentFilter.addAction(Intent.ACTION_TIME_CHANGED); return intentFilter; Private BroadcastReceiver mStandardReceiver1 = new BroadcastReceiver() {@override public void Override OnReceive (Context Context, Intent Intent) {log.d (TAG, "[rustfisher-app1] "); }}; Private BroadcastReceiver mStandardReceiver2 = new BroadcastReceiver() {@override public void Override OnReceive (Context Context, Intent Intent) {log.d (TAG, "[rustfisher-app1] "); if (intent.getAction().endsWith(MSG_PHONE)) { abortBroadcast(); Intent.getaction (); // Intent.getAction (); // Intent.getAction (); }}}; Private BroadcastReceiver mStandardReceiver3 = new BroadcastReceiver() {@override public void Override OnReceive (Context Context, Intent Intent) {log.d (TAG, "[rustfisher-app1] "); }}; / / registered to it with permission standard receiver private BroadcastReceiver mStandardReceiverWithPermission = new BroadcastReceiver () {@ Override Public void onReceive(Context Context, Intent Intent) {log. d(TAG, "[rustfisher-app1]) " + intent.getAction()); }}; Private BroadcastReceiver mLocalReceiver1 = private BroadcastReceiver mLocalReceiver1 = private BroadcastReceiver mLocalReceiver1 = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "[rustfisher-app1] "+ intent.getAction()); }}; private BroadcastReceiver mLocalReceiver2 = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent Intent) {log.d (" + intent.getAction() "); }}; private BroadcastReceiver mLocalReceiver3 = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent Intent) {log.d (" + intent.getAction() "); }};Copy the code

Recipient App2 code

<! Permission android:name="com.rust.permission_rust_1" /> <uses-permission android:name="com.rust.permission_rust_1" />Copy the code
public static final String MSG_PHONE = "msg_phone"; // registerReceiver in onCreate registerReceiver(mDefaultReceiver, makeIF()); LocalBroadcastManager.getInstance(getApplicationContext()) .registerReceiver(mLocalReceiver, makeIF()); unregisterReceiver(mDefaultReceiver); LocalBroadcastManager.getInstance(getApplicationContext()) .unregisterReceiver(mLocalReceiver); private BroadcastReceiver mDefaultReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "[App2] standard receive: " + intent.getAction()); }}; private BroadcastReceiver mLocalReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "[App2] local receive: " + intent.getAction()); }}; private IntentFilter makeIF() { IntentFilter intentFilter = new IntentFilter(MSG_PHONE); intentFilter.addAction(Intent.ACTION_TIME_TICK); intentFilter.addAction(Intent.ACTION_TIME_CHANGED); return intentFilter; }Copy the code

A local broadcast sent by LocalBroadcastManager cannot be received by another App. To receive local broadcasts, you also need LocalBroadcastManager to register receivers.

You can think of local broadcast as a local, in-app broadcast system.

Note that intent.action_time_tick broadcasts can be truncated.

The monitor screen is on and off

Use broadcast monitor device screen on and off status. This is an announcement from the system.

The action used is

  • Intent. ACTION_SCREEN_ON bright screen
  • Intent. ACTION_SCREEN_OFF out the screen
private void registerScreenListener() { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); registerReceiver(mScreenReceiver, filter); } private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context,  Intent intent) { final String action = intent.getAction(); If (intent.action_screen_on.equals (action)) {if (intent.action_screen_off.equals (action)) {if (intent.action_screen_off.equals (action)) {if (intent.action_screen_off.equals (action)) {if (intent.action_screen_off.equals (action))}};Copy the code

Broadcast related interview questions

1. Are there any restrictions on the data transmitted by broadcast? How much and why?

  • Broadcasts carry data that needs to be delivered in an Intent
  • Intents are implemented through Binder mechanisms
  • Binder has limits on data size, which varies with room, generally 1M

2. What is the classification of broadcasting?

  • SendBroadcast: sent to all registered recipients in the current system via context. sendBroadcast or context. sendBroadcastAsUser. The application is used in situations where each broadcast receiver needs to be notified, such as boot up.
  • Orderly broadcast: Radio receiver according to the priority processing, and processing in front of the radio receiver can suspend broadcast transmission, usually by the context. SendOrderedBroadcast or context. SendOrderedBroadcastAsUser, in need to have specific scenarios using intercept, Such as blacklist SMS, telephone interception.
  • Sticky broadcast: Can be sent to the recipient of subsequent registration, meaning that the system will save the previous sticky broadcast in AMS, once registered with the saved sticky broadcast, immediately after the registration will receive the broadcast. Usually by the context. SendStickyBroadcast or context. SendStickyOrderedBroadcast to send, literally, can be divided into ordinary viscous see sticky broadcast also broadcast and orderly sticky broadcast.
  • Local broadcast: Outgoing broadcasts can only be transmitted within the application, and broadcast receivers can only receive broadcasts from the application.
  • Global broadcast: Systems and broadcasts that emit broadcasts that can be received by any other application and can also receive broadcasts from any other application.

Broadcast is a widely used mechanism for transmitting information between applications. It is mainly used to monitor broadcast information sent by the system or application, and then process the broadcast information as the corresponding logic. It can also be used to transmit a small amount of low-frequency data.

In the realization of boot service and network state change, power change, SMS and call through receiving system broadcast so that the application to make the corresponding processing.

Use:

// Static registration in AndroidManifest <receiver Android :name=".MyBroadcastReceiver" Android :enabled="true" Android :exported="true"> <intent-filter android:priority="100"> <action android:name="com.example.hp.broadcasttest.MY_BROADCAST"/> </intent-filter> </receiver> Override protected void onCreate(Bundle savedInstanceState) {super.oncreate (savedInstanceState); setContentView(R.layout.activity_main); mIntentFilter = new IntentFilter(); / / add radio want to monitor type, whether to monitor network status changes mIntentFilter. AddAction (" android.net.conn.CONNECTIVITY_CHANGE "); mNetworkChangeReceiver = new NetworkChangeReceiver(); // Register the broadcast registerReceiver(mNetworkChangeReceiver, mIntentFilter); } @Override protected void onDestroy() { super.onDestroy(); // Unregister the broadcast receiver unregisterReceiver(mNetworkChangeReceiver); } / / broadcast, as well as through Intent Intent Intent = new Intent (" com. Example. HP. Broadcasttest. MY_BROADCAST "); // sendBroadcast(intent); Public class MyBroadcastReceiver extends BroadcastReceiver {public MyBroadcastReceiver() {} @override public void onReceive(Context context, Intent intent) { // TODO: This method is called when the BroadcastReceiver is receiving // an Intent broadcast. Toast.makeText(context, "received", Toast.LENGTH_SHORT).show(); // abortBroadcast(); }}Copy the code

4. BroadcastReceiver, LocalBroadcastReceiver

(1) It is used to transfer messages between applications. (2) There are security problems due to cross-applicationCopy the code

Local Broadcast Receivers:

(1) Broadcast data is transmitted within the application scope. (2) Don't worry about other applications forgery broadcasts. (3) More efficient and safe than sending global broadcast. (4) Static registration cannot be usedCopy the code

5. How to register and use BroadcastReceiver in manifest and code

  • Register statically in AndroidManifest and use it directly.
  • In the code, register via registerReceiver.
  • After registering for transmission, broadcast is received and processed in onReceive of BroadcastReceiver (a custom receiver inherits from BroadcastReceiver).

6. Time limit of anR caused by broadcast

  • BROADCAST_FG_TIMEOUT = 10s
  • BROADCAST_BG_TIMEOUT = 60s