Broadcast mechanism developed by Android

Posted by php4geek on Thu, 10 Feb 2022 22:55:28 +0100

1. Introduction to broadcasting mechanism

  • normal broadcasts: fully asynchronous execution. After the broadcast is sent, all broadcast receivers will receive the broadcast message at the same time
  • Ordered broadcasts: synchronous execution. Only one broadcast receiver receives it at the same time, and then continues to deliver it after execution. The broadcast receiver with high priority can receive the message first, and can also truncate the broadcast receiver.

2. Receiving system broadcast

Dynamically register to monitor network changes

Registering in the code is called dynamic registration, which is in androidmanifest XML registration is called static registration.

1. Create a new BroadcastTest project and modify the code in MainActivity

public class MainActivity extends AppCompatActivity {
    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetworkChangeReceiver();
        registerReceiver(networkChangeReceiver, intentFilter);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
    }
    class NetworkChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager connectionManager = (ConnectivityManager)
                getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
            if (networkInfo != null && networkInfo.isAvailable()) {
                Toast.makeText(context, "network is available",
                    Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "network is unavailable",
                    Toast.LENGTH_SHORT).show();
            }
        }
    }
}
  • Defines an internal class NetworkChangeReceiver, which inherits from BroadcastReceiver and rewrites the onReceive() method of the parent class. In this way, whenever the network state changes, the onReceive() method will be executed. Here, you simply use Toast to prompt a text message

  • Observe the onCreate() method. First, we create an instance of IntentFilter and add a value of Android net. conn.CONNECTIVITY_ Why add this value to the action of change? Because when the network state changes, the system sends a message with the value of Android net. conn.CONNECTIVITY_ Change broadcast, that is to say, if our broadcast receiver wants to listen for any broadcast, add the corresponding action here

  • Next, we create an instance of NetworkChangeReceiver, then call the registerReceiver() method to register, pass the instance of NetworkChangeReceiver and the instance of IntentFilter, so that NetworkChangeReceiver will receive all values android.. net. conn.CONNECTIVITY_ The broadcast of change realizes the function of monitoring network changes.

  • All dynamically registered broadcast receivers must be unregistered. Here, we call unregisterReceiver() method in onDestroy() method

  • In the onReceive() method, first get the instance of ConnectivityManager through the getSystemService() method, which is a system service class specially used to manage network connections. Then we call the getActiveNetworkInfo() method to get an instance of NetworkInfo, and then call the isAvailable() method of NetworkInfo to determine whether there is a network. Finally, we can prompt users through Toast.

  • If the program needs to perform some operations that are more sensitive to the user, the permission must be declared in the configuration file, otherwise the program will crash directly. For example, it is necessary to declare the permission to access the network state of the system here. Open androidmanifest XML file

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.broadcasttest">
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        ...
    </manifest>
    

Static registration enables startup

1. You can use the shortcut provided by Android Studio to create a Broadcast Receiver. Right click com example. Broadcastest package → New → Other → Broadcast Receiver

2. Modify the code in BootCompleteReceiver

public class BootCompleteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
    }
}

3. The static broadcast receiver must be in Android manifest The BootCompleteReceiver cannot receive the boot broadcast until it is registered in the XML file. A new tag appears in the tag. At present, BootCompleteReceiver cannot receive the boot broadcast. After the Android system is started, it will send out a message with the value of Android intent. action. BOOT_ Complete broadcast, so we added the corresponding action in the tag. In addition, the monitoring system also needs to declare permission to start broadcasting. You can see that we have added an android. Com tag permission. RECEIVE_ BOOT_ Completed permission.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcasttest">
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
        <receiver
            android:name=".BootCompleteReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

3. Send custom broadcast

Send standard broadcast

1. Before sending a broadcast, we still need to define a broadcast receiver to prepare to receive the broadcast, otherwise it will be white hair. So create a new MyBroadcastReceiver

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_
            SHORT).show();
    }
}

2.AndroidManifest. Modify this broadcast receiver in XML

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcasttest">
    ...
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        ...
        <receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

3. Here, let MyBroadcastReceiver receive a message with the value of com example. broadcasttest. MY_ Broadcast of broadcast, so we need to send such a broadcast when sending the broadcast later. Next, modify the activity_ main. Code in XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send Broadcast"
        />
</LinearLayout>

4. A button is defined in the layout file as the trigger point for sending broadcast. Then modify the code in MainActivity

public class MainActivity extends AppCompatActivity {
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new 
                Intent("com.example.broadcasttest.MY_BROADCAST");
                sendBroadcast(intent);
            }
        });
        ...
    }
    ...
}

Send ordered broadcast

Changing from standard broadcast to ordered broadcast only needs

  • @Override
    public void onClick(View v) {
        Intent intent = new Intent("com.example.firstdemo.MY_BROADCAST");
        sendBroadcast(intent);
    }
    

    Change to

    @Override
    public void onClick(View v) {
        Intent intent = new Intent("com.example.firstdemo.MY_BROADCAST");
        sendOrderedBroadcast(intent,null);
    }
    
  • Priority can also be set

    <intent-filter android:priority="100">
                    <action android:name="com.example.broadcasttest.MY_BROADCAST" />
    </intent-filter>
    
  • Truncation can also be set

    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "received in MyBroadcastReceiver",
                Toast.LENGTH_SHORT).show();
            abortBroadcast();
        }
    }
    

Topics: Android