有序广播
package com.example.broadcast;
import androidx.appcompat.app.AppCompatActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import com.example.broadcast.util.DateUtil;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private CheckBox ckStop;
private TextView tvOrder;
private final static String TAG = "MainActivity";
private final static String ORDER_ACTION = "com.example.broadcast.order";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ckStop = findViewById(R.id.ck_stop);
tvOrder = findViewById(R.id.tv_order);
findViewById(R.id.bt_send).setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId() == R.id.bt_send) {
tvOrder.setText("");
Intent intent = new Intent(ORDER_ACTION);
sendOrderedBroadcast(intent,null);
}
}
@Override
protected void onStart() {
super.onStart();
//优先级越大的接收器越早接受到广播
//优先级相同的接收器,先注册的先接收到广播
orderAReceiver = new OrderAReceiver(); // 创建一个有序广播的接收器A
// 创建一个意图过滤器A,只处理ORDER_ACTION的广播
IntentFilter filterA = new IntentFilter(ORDER_ACTION);
filterA.setPriority(12); // 设置过滤器A的优先级,数值越大优先级越高
registerReceiver(orderAReceiver, filterA); // 注册接收器A,注册之后才能正常接收广播
orderBReceiver = new OrderBReceiver(); // 创建一个有序广播的接收器B
// 创建一个意图过滤器B,只处理ORDER_ACTION的广播
IntentFilter filterB = new IntentFilter(ORDER_ACTION);
filterB.setPriority(8); // 设置过滤器B的优先级,数值越大优先级越高
registerReceiver(orderBReceiver, filterB); // 注册接收器B,注册之后才能正常接收广播
orderDReceiver = new OrderDReceiver(); // 创建一个有序广播的接收器D
// 创建一个意图过滤器D,只处理ORDER_ACTION的广播
IntentFilter filterD = new IntentFilter(ORDER_ACTION);
filterD.setPriority(6); // 设置过滤器D的优先级,数值越大优先级越高
registerReceiver(orderDReceiver, filterD); // 注册接收器D,注册之后才能正常接收广播
orderCReceiver = new OrderCReceiver(); // 创建一个有序广播的接收器C
// 创建一个意图过滤器C,只处理ORDER_ACTION的广播
IntentFilter filterC = new IntentFilter(ORDER_ACTION);
filterC.setPriority(6); // 设置过滤器C的优先级,数值越大优先级越高
registerReceiver(orderCReceiver, filterC); // 注册接收器C,注册之后才能正常接收广播
}
@Override
protected void onStop() {
super.onStop();
unregisterReceiver(orderAReceiver); // 注销接收器A,注销之后就不再接收广播
unregisterReceiver(orderBReceiver); // 注销接收器B,注销之后就不再接收广播
unregisterReceiver(orderCReceiver); // 注销接收器C,注销之后就不再接收广播
unregisterReceiver(orderDReceiver); // 注销接收器D,注销之后就不再接收广播
}
private OrderAReceiver orderAReceiver; // 声明有序广播接收器A的实例
private class OrderAReceiver extends BroadcastReceiver {
// 一旦接收到有序广播,马上触发接收器的onReceive方法
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction().equals(ORDER_ACTION)) {
String desc = String.format("%s%s 接收器A收到一个有序广播\n",
tvOrder.getText().toString(), DateUtil.getNowTime());
tvOrder.setText(desc);
if (ckStop.isChecked()) {
abortBroadcast(); // 中断广播,此时后面的接收器无法收到该广播
}
}
}
}
private OrderBReceiver orderBReceiver; // 声明有序广播接收器B的实例
// 定义一个有序广播的接收器B
private class OrderBReceiver extends BroadcastReceiver {
// 一旦接收到有序广播B,马上触发接收器的onReceive方法
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction().equals(ORDER_ACTION)) {
String desc = String.format("%s%s 接收器B收到一个有序广播\n",
tvOrder.getText().toString(), DateUtil.getNowTime());
tvOrder.setText(desc);
if (ckStop.isChecked()) {
abortBroadcast(); // 中断广播,此时后面的接收器无法收到该广播
}
}
}
}
private OrderCReceiver orderCReceiver; // 声明有序广播接收器C的实例
// 定义一个有序广播的接收器C
private class OrderCReceiver extends BroadcastReceiver {
// 一旦接收到有序广播C,马上触发接收器的onReceive方法
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction().equals(ORDER_ACTION)) {
String desc = String.format("%s%s 接收器C收到一个有序广播\n",
tvOrder.getText().toString(), DateUtil.getNowTime());
tvOrder.setText(desc);
if (ckStop.isChecked()) {
abortBroadcast(); // 中断广播,此时后面的接收器无法收到该广播
}
}
}
}
private OrderDReceiver orderDReceiver; // 声明有序广播接收器D的实例
// 定义一个有序广播的接收器D
private class OrderDReceiver extends BroadcastReceiver {
// 一旦接收到有序广播D,马上触发接收器的onReceive方法
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction().equals(ORDER_ACTION)) {
String desc = String.format("%s%s 接收器D收到一个有序广播\n",
tvOrder.getText().toString(), DateUtil.getNowTime());
tvOrder.setText(desc);
if (ckStop.isChecked()) {
abortBroadcast(); // 中断广播,此时后面的接收器无法收到该广播
}
}
}
}
public void jumpToNetworkActivity (View view){
Intent intent = new Intent(this, networkActivity.class);
startActivity(intent);
}
public void jumpToReturnDesktopActivity (View view){
Intent intent = new Intent(this, ReturnDesktopActivity.class);
startActivity(intent);
}
}
监听网络变更的广播
package com.example.broadcast;
import androidx.appcompat.app.AppCompatActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.widget.TextView;
import com.example.broadcast.util.DateUtil;
import com.example.broadcast.util.NetworkUtil;
public class networkActivity extends AppCompatActivity {
private TextView tvNetwork;
private String desc = "开始侦听网络变更广播,请开关WLAN或者数据连接,再观察广播结果";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_network);
tvNetwork = findViewById(R.id.tv_network);
tvNetwork.setText(desc);
}
@Override
protected void onStart() {
super.onStart();
networkReceiver = new NetworkReceiver(); // 创建一个网络变更的广播接收器
// 创建一个意图过滤器,只处理网络状态变化的广播
IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(networkReceiver, filter); // 注册接收器,注册之后才能正常接收广播
}
@Override
protected void onStop() {
super.onStop();
unregisterReceiver(networkReceiver); // 注销接收器,注销之后就不再接收广播
}
private NetworkReceiver networkReceiver; // 声明一个网络变更的广播接收器实例
// 定义一个网络变更的广播接收器
private class NetworkReceiver extends BroadcastReceiver {
// 一旦接收到网络变更的广播,马上触发接收器的onReceive方法
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
NetworkInfo networkInfo = intent.getParcelableExtra("networkInfo");
String networkClass = NetworkUtil.getNetworkClass(networkInfo.getSubtype());
desc = String.format("%s\n%s 收到一个网络变更广播,网络大类为%s," +
"网络小类为%s,网络制式为%s,网络状态为%s",
desc, DateUtil.getNowTime(), networkInfo.getTypeName(),
networkInfo.getSubtypeName(), networkClass,
networkInfo.getState().toString());
tvNetwork.setText(desc);
}
}
}
}
监听回到桌面的广播
package com.example.broadcast;
import androidx.appcompat.app.AppCompatActivity;
import android.app.PictureInPictureParams;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Rational;
import android.widget.TextView;
import com.example.broadcast.util.DateUtil;
public class returnDesktopActivity extends AppCompatActivity {
private final static String TAG = "returnDesktopActivity";
private TextView tv_monitor;
private String mDesc = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_return_desktop);
tv_monitor = findViewById(R.id.tv_monitor);
initDesktopRecevier(); // 初始化桌面广播
}
// 显示变更的状态
private void showChangeStatus(String reason) {
mDesc = String.format("%s%s 按下了%s键\n", mDesc, DateUtil.getNowTime(), reason);
tv_monitor.setText(mDesc);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
&& !isInPictureInPictureMode()) { // 当前未开启画中画,则开启画中画模式
// 创建画中画模式的参数构建器
PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder();
// 设置宽高比例值,第一个参数表示分子,第二个参数表示分母
// 下面的10/5=2,表示画中画窗口的宽度是高度的两倍
Rational aspectRatio = new Rational(10,5);
builder.setAspectRatio(aspectRatio); // 设置画中画窗口的宽高比例
// 进入画中画模式,注意enterPictureInPictureMode是Android8.0之后新增的方法
enterPictureInPictureMode(builder.build());
}
}
// 在进入画中画模式或退出画中画模式时触发
@Override
public void onPictureInPictureModeChanged(boolean isInPicInPicMode, Configuration newConfig) {
Log.d(TAG, "onPictureInPictureModeChanged isInPicInPicMode="+isInPicInPicMode);
super.onPictureInPictureModeChanged(isInPicInPicMode, newConfig);
if (isInPicInPicMode) { // 进入画中画模式
} else { // 退出画中画模式
}
}
// 初始化桌面广播
private void initDesktopRecevier() {
desktopRecevier = new DesktopRecevier(); // 创建一个返回桌面的广播接收器
// 创建一个意图过滤器,只接收关闭系统对话框(即返回桌面)的广播
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
registerReceiver(desktopRecevier, intentFilter); // 注册接收器,注册之后才能正常接收广播
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(desktopRecevier); // 注销接收器,注销之后就不再接收广播
}
private DesktopRecevier desktopRecevier; // 声明一个返回桌面的广播接收器对象
// 定义一个返回到桌面的广播接收器
private class DesktopRecevier extends BroadcastReceiver {
// 在收到返回桌面广播时触发
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra("reason"); // 获取变更原因
// 按下了主页键或者任务键
if (!TextUtils.isEmpty(reason) && (reason.equals("homekey")
|| reason.equals("recentapps"))) {
showChangeStatus(reason); // 显示变更的状态
}
}
}
}
}



本文深入探讨了Android中的BroadcastReceiver组件,重点讲解如何实现有序广播以及如何监听网络状态变化和返回桌面的广播事件。通过实例解析,帮助开发者更好地理解和应用广播机制。

4954

被折叠的 条评论
为什么被折叠?



