Android Development: broadcast receiver

Posted by macleo on Sun, 16 Jan 2022 03:13:18 +0100

Personal notes sorting

Broadcast receiver

Introduction to broadcasting mechanism

  • Standard broadcast( Normal broadcasts)It is a completely asynchronous broadcast. After the broadcast is sent, all broadcast receivers will receive the broadcast message at almost the same time, so there is no order between them. This kind of broadcast will be more efficient, but it also means that it cannot be truncated.
    
  • Orderly broadcasting( Ordered broadcasts)It is a synchronously executed broadcast. After the broadcast is sent, only one broadcast receiver can receive the broadcast message at the same time. The broadcast will continue to deliver only after the logic in the broadcast receiver is executed. Therefore, the broadcast receivers at this time are in order. The broadcast receiver with high priority can receive the broadcast message first, and the previous broadcast receiver can also cut off the broadcast being transmitted, so that the subsequent broadcast receiver cannot receive the broadcast message.
    

Receiving system broadcast

Dynamically register to monitor network changes

Create a new class, let it inherit from BroadcastReceiver, and override the onReceive() method of the parent class. When a broadcast arrives, the onReceive() method is executed

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);
        // Create an intent filter
        intentFilter = new IntentFilter();
        // Add the intent request you want to receive
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        // Instantiate the Receiver class
        networkChangeReceiver = new NetworkChangeReceiver();
        // Dynamically register broadcast recipients
        registerReceiver(networkChangeReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Unregister broadcast recipients
        unregisterReceiver(networkChangeReceiver);
    }
    class NetworkChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // When the broadcast is received, a pop-up window will prompt the network state to change
            Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();
        }
    }
}

Or when the network state changes, it will prompt whether there is a network or not

public class MainActivity extends AppCompatActivity {
    ...
    class NetworkChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            // Get the connectivity manager instance (a system service class dedicated to managing network connections)
            ConnectivityManager connectionManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
            // Get an instance of NetworkInfo
            NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
            // Determine whether there is a network by calling the isAvailable() method of NetworkInfo
            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();
            }
        }
    }

}

At the same time, access to network status needs to be in androidmanifest Declare permissions in XML

Static registration to realize startup reminder

Need to be in androidmanifest Register receiver in XML

<receiver
    android:name=".BootCompleteReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <!-- Boot event broadcast -->
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

At the same time, you need to add corresponding permissions to monitor startup

Then you can add a receiver Java, and write the corresponding control logic in onReceive()

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

Do not add too much logic or perform any time-consuming operations in the onReceive() method, because it is not allowed to start threads in the broadcast receiver. When the onReceive() method runs for a long time without ending, the program will report an error.

Send custom broadcast

Send standard broadcast
Define your own broadcast receiver
public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_
            SHORT).show();
    }
}
<receiver
    android:name=".MyBroadcastReceiver"
    android:enabled="true"
    android:exported="true">

    <intent-filter>
        <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
    </intent-filter>
</receiver>

Receive a value of com example. broadcasttest. MY_ Broadcast of broadcast

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

// with
public void onClick(View v) {
    Intent intent = new Intent();
    intent.setAction("com.example.broadcasttest.MY_BROADCAST");
    intent.setPackage("com.example.broadcasttest");
    sendBroadcast(intent);
}

Since the broadcast is delivered using Intent, you can also carry some data in Intent to the broadcast receiver.

Send ordered broadcast

When sending

public void onClick(View v) {
    Intent intent = new
        Intent("com.example.broadcasttest.MY_BROADCAST");
    sendOrderedBroadcast(intent, null);
}

When receiving, via Android Priority property to set the priority

<receiver
    android:name=".MyBroadcastReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter android:priority="100">
        <action android:name="com.example.broadcasttest.MY_BROADCAST" />
    </intent-filter>
</receiver>

At the same time, the broadcast is truncated through the abortBroadcast() method (the subsequent broadcast receiver cannot receive it)

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

Use local broadcast

public class MainActivity extends AppCompatActivity {
    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager = LocalBroadcastManager.getInstance(this); // Get instance
        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.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent); // Send local broadcast
            }
        });
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
        localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver, intentFilter); // notes
        Local broadcast listener
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }
    class LocalReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).

               show();
        }
    }
}

It is the same as dynamically registering a broadcast receiver, but now an instance of it is obtained through the getInstance() method of LocalBroadcastManager. When registering a broadcast receiver, the registerReceiver() method of LocalBroadcastManager is called, and when sending a broadcast, the sendBroadcast() method of LocalBroadcastManager is called

Local broadcasting cannot be received through static registration

Use the broadcast to realize the forced offline function

@TODO

Topics: Java Android Apache