前面我们讲过四大组件中的活动,本文讲解四大组件中的广播机制,通过本文了解广播机制的作用以及基本用法。
如该章标题,广播就像你村里的大喇叭,通过广播可以接收手机中其它软件的信息,也可以将自己的信息发送给你别的软件。广播与广播接收器是一对,广播用于发送信息,广播接收器用于接收广播发送的信息。
Android中广播主要有两种类型:
Android内置了很多系统级别的广播,比如开机完成后,网络发生变化后,电量变化后等都会发出一条广播,我们可以在程序中有选择的接收我们需要的广播。
接收系统发出的广播有两个步骤:
注册广播有两种方法:
如当网络状态发送变化时,系统会发送一条广播,我们采用动态注册广播的方式接收该广播信息的流程如下:
//创建广播接收器,用于指定action的广播
class NetworkChangeReceiver extends BroadcastReceiver{
//系统发出的广播信息会在这个方法中接收到
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
if (activeNetworkInfo!=null && activeNetworkInfo.isAvailable())
Toast.makeText(context, "网络已连接", Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, "网络已断开", Toast.LENGTH_SHORT).show();
}
}
//动态注册广播接收器,接收网络状态广播
IntentFilter intentFilter=new IntentFilter();
//指定我们想要接收的系统广播
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver = new NetworkChangeReceiver();
//将广播注册到广播接收器
registerReceiver(networkChangeReceiver,intentFilter);
注意:
a. 动态注册的广播接收器,不用的时候记得取消注册。
unregisterReceiver(networkChangeReceiver);
b. 注册相应广播需要一定的权限,如注册网络状态广播需要在AndroidManifest.xml中添加网络权限。
<!-- 添加访问网络状态的权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
可以利用Android studio工具完成静态注册广播,操作流程如下图。
如注册开机时系统发出的广播。
<receiver
android:name=".BootCompleteReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
intent-filter>
receiver>
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context, "开机完成", Toast.LENGTH_SHORT).show();
}
}
注意,注册开机启动广播,同样需要在AndroidManifest.xml中添加相应权限
<!-- 添加访问开机状态的权限 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
通过发送自定义广播,那么注册了这个自定义广播的所有软件就能收到该广播。所谓自定义广播其实就是自定义一个action字符串。
//从SDK26开始,通过静态注册的广播接收器失效!
Intent intent=new Intent("com.xiaomi.broadcasttest.MY_BROADCAST");
//sendBroadcast(intent);//以标准广播方法发送自定义的广播
sendOrderedBroadcast(intent,null);//以顺序广播方法发送自定义的广播
//创建广播接收器,用于指定action的广播
class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "收到自定义发送的广播", Toast.LENGTH_SHORT).show();
//abortBroadcast();//发送顺序广播的情况下,通过这个方法,使得广播传播到此处就中断,未接收到广播的信息的就接收不到了
}
}
2.2 静态注册上面的自定义广播
从SDK26开始,通过静态注册的自定义广播接收器失效!,因此,应该采用动态注册自定义广播接收器
<receiver android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.xiaomi.broadcasttest.MY_BROADCAST" />
intent-filter>
receiver>
2.3 动态注册上面的自定义广播
//动态注册广播接收器,接收自定义发送的标准广播
intentFilter=new IntentFilter();
intentFilter.addAction("com.xiaomi.broadcasttest.MY_BROADCAST");
intentFilter.setPriority(100);//采用顺序广播方法发送广播,设置广播接收器的优先级,优先级越高,越先收到广播
myBroadcastReceiver = new MyBroadcastReceiver();
registerReceiver(myBroadcastReceiver,intentFilter);
前面我们发送和接收的广播全部属于系统全局广播,即发出的广播可以被其它任何应用程序接收到,并且我们也可以接收来自于其他任何应用程序的广播。这样就很容易引起安全性的问题,比如说我们发送的一些携带关键性数据的广播有可能被其他的应用程序截获,或者其他的程序不停地向我们的广播接收器里发送各种垃圾广播。
为了解决这个问题,Android引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全性问题就都不存在了。
本地广播实现非常简单,与常规广播实现类似,只是Android提供了一个LocalBroadcastManager类来管理广播的发送,注册,取消注册等。
本地广播只能采用动态方式注册,这个也很容易理解,因此是在程序内部使用的,没有必要采用让程序在未启动情况下接收广播的静态注册方式。
LocalBroadcastManager mLocalBroadcastManager;
mLocalBroadcastManager=LocalBroadcastManager.getInstance(this);
Intent intent=new Intent("com.xiaomi.LOCAL_BROADCAST");
mLocalBroadcastManager.sendBroadcast(intent);
参考书籍:第一行代码
链接:https://pan.baidu.com/s/1aXtOQCXL6qzxEFLBlqXs1Q?pwd=n5ag
提取码:n5ag2. 注册本地广播核心代码
链接:https://pan.baidu.com/s/1aXtOQCXL6qzxEFLBlqXs1Q?pwd=n5ag
提取码:n5ag
LocalBroadcastReceiver mLocalBroadcastReceiver;
//注册本地广播
intentFilter=new IntentFilter();
intentFilter.addAction("com.xiaomi.LOCAL_BROADCAST");
mLocalBroadcastReceiver=new LocalBroadcastReceiver();
mLocalBroadcastManager.registerReceiver(mLocalBroadcastReceiver,intentFilter);
//取消注册本地广播
//mLocalBroadcastManager.unregisterReceiver(mLocalBroadcastReceiver);
//创建广播接收器
class LocalBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "本地广播接收器", Toast.LENGTH_SHORT).show();
}
}
链接:https://pan.baidu.com/s/1aXtOQCXL6qzxEFLBlqXs1Q?pwd=n5ag
提取码:n5ag