Android四大组件之- BroadcastReceiver的创建与应用


前言

我学习东西都是先学怎么做,再学为什么这么做,所以我的学习笔记也是代码居多,直接复制代码运行,通过观察代码的运行流程来理解它。


一、广播接收器的两种注册方法

动态注册

动态注册广播接收器方法:
    1.新建一个类继承BroadcastReceiver重写onReceive方法,方法中的内容为接收到广播后要做的事务
    2.  MainActivity中初始化新建的广播类
    3.初始化一个广播过滤器,使用addAction方法指定要接收的广播
    4.注册广播接收器,设置接收指定的广播
    5.动态注册的需要调用unregisterReceiver()关闭


以下5个系统广播只能动态注册接收,不能静态注册
    android.intent.action.SCREEN_ON     亮屏广播
    android.intent.action.SCREEN_OFF    灭屏广播
    android.intent.action.BATTERY_CHANGED   电池状态广播
    android.intent.action.CONFIGURATION_CHANGED     设备当前设置被改变时发出的广播,包括的改变:界面语言,设备方向,等
    android.intent.action.TIME_TICK     广播:当前时间已经变化(正常的时间流逝),当前时间改变,每分钟都发送

Myrecive.java

public class Myrecive extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,"动态广播", Toast.LENGTH_SHORT).show();
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {
    Myrecive bt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化广播
        Myrecive bt = new Myrecive();
        //建立广播过滤器
        IntentFilter itFilter = new IntentFilter();
        itFilter.addAction("android.intent.action.SCREEN_ON");    //亮屏时接收广播
        //注册广播接收器,设置接收指定的广播
        registerReceiver(bt, itFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(bt);
    }
}

静态注册

静态广播接收器注册步骤:
    1.两种方法注册
        a.鼠标右键new一个BroadcastReceiver,重写onReceive方法
        b.新建一个类extends BroadcastReceiver,重写onReceive方法,然后在Mainfest文件中添加receiver的代码
    2.在Mainfest文件中的receiver里面添加以下代码,name是要接收的广播
        <intent-filter>
            <action android:name="android.intent.action.AIRPLANE_MODE" />
        </intent-filter>
    3.添加对应的广播接收权限,部分广播需要系统权限才能接收

备注:
安卓8.0后大部分隐式广播无法静态注册接收,详情参考:
https://developer.android.google.cn/guide/components/broadcast-exceptions?hl=zh-cn

MyReceiver.java

public class MyReceiver extends BroadcastReceiver {
	**// AIRPLANE_MODE为飞行模式变化广播,此广播安卓8.0以后只能动态注册接收**
    private final String ACTION_BOOT = "android.intent.action.AIRPLANE_MODE";   

    @Override
    public void onReceive(Context context, Intent intent) {
        if (ACTION_BOOT.equals(intent.getAction())) {
            boolean status = intent.getExtras().getBoolean("state");
            if (status) {
                Toast.makeText(context, "飞行模式开启!", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(context, "飞行模式关闭!", Toast.LENGTH_LONG).show();
            }
        }

    }
}

AndroidManifest.xml
大部分广播是需要接收权限才能接收的,一定不能忘!

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcastreceiver1">

    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.BroadcastReceiver1">
        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.READ_SYNC_SETTINGS">
            <intent-filter>
                <action android:name="android.intent.action.AIRPLANE_MODE" />
            </intent-filter>
        </receiver>

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

二、发送广播的应用

sendBroadcast发送本地标准广播,app内自发自收

MainActivity.java

public class MainActivity extends AppCompatActivity {
    MyReceiver bt;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //注册广播接收器
        bt = new MyReceiver();
        IntentFilter itFilter = new IntentFilter();
        itFilter.addAction("asfgjg");
        registerReceiver(bt, itFilter);

        Button btn_send = (Button) findViewById(R.id.bt);
        btn_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //发送广播
                sendBroadcast(new Intent("asfgjg"));
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(bt);
    }
}

MyReceiver.java

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String actins = "asfgjg";
        if(actins.equals(intent.getAction())){
            Log.d("broadcastreceiver4","接收到本地标准广播!");
        }
    }
}

localBroadcastManager.sendBroadcast发送本地标准广播,app内自发自收

发送本地广播的方法:
1.注册一个广播接收器
2.使用localBroadcastManager.sendBroadcast发送广播
备注:
发送广播时,intent可带参数
发送的本地广播只能通过动态注册的接收器来接收

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private MyReceiver mr;
    private LocalBroadcastManager localBroadcastManager;
    private IntentFilter intentFilter;

 /*
   
*/
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button bt = (Button) findViewById(R.id.bt);

        //注册动态广播接收器
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        mr = new MyReceiver();
        intentFilter = new IntentFilter();
        intentFilter.addAction("aABBD");
        localBroadcastManager.registerReceiver(mr, intentFilter);

        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //发送广播
                Intent intent = new Intent("aABBD");
                localBroadcastManager.sendBroadcast(intent);

            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(mr);
    }
}

MyReceiver.java

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String actins = "aABBD";
        if(actins.equals(intent.getAction())){
            Log.d("broadcastreceiver3","接收到本地标准广播!");
        }
    }
}

发送本地有序广播

首先注册三个广播接收器

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String actins = "aABBD";
        if(actins.equals(intent.getAction())){
            Log.d("MyReceiver","接收到本地发送的有序广播!");
        }
    }
}
public class MyReceiver2 extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String actins = "aABBD";
        if(actins.equals(intent.getAction())){
            Log.d("MyReceiver2","接收到本地发送的有序广播!");
            //截断广播
            abortBroadcast();
        }
    }
}
public class MyReceiver3 extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String actins = "aABBD";
        if(actins.equals(intent.getAction())){
            Log.d("MyReceiver3","接收到本地发送的有序广播!");
        }
    }
}

解析:
1.有多个广播接收器接收同一个广播时,通过setPriority方法设置广播接收器的优先级调整广播接收的顺序,值越大优先级越高
2.使用sendBroadcast和sendOrderedBroadcast都可以发送有序广播
sendBroadcast和sendOrderedBroadcast的区别
sendBroadcast:无法截断
sendOrderedBroadcast:可以在任意一个广播接收器中使用abortBroadcast()方法截断广播,使优先级低的广播接收器无法接收到广播

MainActivity.java
以下代码中可以分别使用sendBroadcast和sendOrderedBroadcast发送广播测试,通过三个广播接收器打印的log来观察它们接收广播的顺序

public class MainActivity extends AppCompatActivity {

    MyReceiver bt;
    MyReceiver3 bt3;
    MyReceiver2 bt2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //注册广播接收器
        bt = new MyReceiver();
        bt2 = new MyReceiver2();
        bt3 = new MyReceiver3();
        IntentFilter itFilter = new IntentFilter();
        IntentFilter itFilter2 = new IntentFilter();
        IntentFilter itFilter3 = new IntentFilter();
        itFilter.addAction("aABBD");
        itFilter2.addAction("aABBD");
        itFilter3.addAction("aABBD");

        itFilter.setPriority(9997);
        itFilter2.setPriority(9998);
        itFilter3.setPriority(9999);

        registerReceiver(bt, itFilter);
        registerReceiver(bt2, itFilter2);
        registerReceiver(bt3, itFilter3);


        Button bt = (Button) findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //发送广播
                Intent intent = new Intent("aABBD");
            //    sendBroadcast(intent);
                sendOrderedBroadcast(intent, null);

            }
        });
    }
}

接收三方应用发送的广播

首先新建一个项目发送一个全局标准广播
很简单,就两行代码发送

Intent intent = new Intent("aABBD");
sendBroadcast(intent);

然后再新建一个项目注册广播接收器来接收广播
注:静态注册仅安卓8.0之前能接收到,安卓8.0之后只能动态注册才能接收到

动态注册:
还是新建一个类继承BroadcastReceiver
MyReceiver.java

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String actins = "aABBD";
        if(actins.equals(intent.getAction())){
            Log.d("MyReceiver","接收到全局广播");
        }
    }
}

然后MainActivity中

MyReceiver bt = new MyReceiver();
IntentFilter itFilter = new IntentFilter();
itFilter.addAction("aABBD");
registerReceiver(bt, itFilter);

静态注册:
第一步仍然是新建一个类继承BroadcastReceiver,代码与动态一样
第二步AndroidManifest.xml文件中注册

<receiver
     android:name=".MyReceiver"
     android:enabled="true"
     android:exported="true">
        <intent-filter>
           <action android:name="aABBD" />
        </intent-filter>
 </receiver>

以上代码就完成了,运行两个项目即可看到效果,再一个项目里面发广播,另一个项目里面接收广播

三、其他应用

通过广播打开activity和AlertDialog

广播打开activity和AlertDialog主要是在接收广播之后执行的事务里面,非常简单,所以我直接贴MyReceiver的代码

打开Activity :

public class MyReceiver extends BroadcastReceiver {
    String actions = "aABBD";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(actions)) {
            Intent splashIntent = new Intent(context, MainActivity2.class);
            splashIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);   //新建一个栈存放新打开的activity,否则打不开activity
            context.startActivity(splashIntent);
        }
    }
}

打开AlertDialog:

public class MyReceiver2 extends BroadcastReceiver {
    String actions = "aABBD";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("asdg","adsgdasg");
        if (intent.getAction().equals(actions)) {

            AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);

            dialogBuilder.setTitle("提示:");
            dialogBuilder.setMessage("这是通过广播打开的AlertDialog");
            dialogBuilder.setCancelable(false);
            dialogBuilder.setPositiveButton("确定",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    });
            AlertDialog alertDialog = dialogBuilder.create();
            // 设置对话框类型为TYPE_APPLICATION_OVERLAY,否则无法弹出
            alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
            alertDialog.show();
        }
    }

}

总结

这里主要是以自己理解的方式写了一些示例代码来加深理解

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值