知识点:
1、BroadcastReceiver广播概述;
2、BroadcastReceiver的静态注册和动态注册;
3、BroadcastReceiver权限;
4、普通广播和有序广播;
5、本地广播;
6、监听系统广播;
BroadcastReceiver概述:
BroadcastReceiver也就是“广播接收者”的意思,BroadcastReceiver是Android四大组件之一,本质是一种全局的监听器,用于监听系统全局的广播消息。
在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度,等等。
继承系统的BroadcastReceiver类,重写onReceive方法:
public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String msg = intent.getStringExtra("msg");
Log.i(TAG, "FirstReceiver: " + msg);
}
}
然后进行注册
注册BroadcastReceiver的方式有两种:
BroadcastReceiver静态注册需要在androidmanifest.xml文件里面进行注册,代码如下:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.myBroadcast"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
android:name是用来设置广播动作action,只要监听到系统里面传播的android.intent.action.MY_BROADCAST动作的广播,我们注册的这个BroadcastReceiver就会相应这个广播,MyBroadcastReceiver会被调用,然后产生相应的动作相应。
动态注册
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();//过滤器
filter.addAction(“android.intent.action.myBroadcast”);//添加广播动作监听
registerReceiver(receiver, filter);//注册广播
我们发送广播的代码如下:
Intent intent = new Intent("android.intent.action.myBroadcast");
intent.putExtra("msg", "hello receiver.");
sendOrderedBroadcast(intent, null);
解除广播注册
静态注册的广播没有说解除广播一说,因为它已经注册好了,然后接收到匹配的广播,都会无条件的响应。所以我们不用管它。也没有办法管。
动态注册的广播,我们必须在退出程序或者与之关联的activity销毁之前,必须要解除注册。一般情况下,我们会在ondestoryed方法里面进行解除注册。
广播分类:
普通广播
普通广播的发送方式为:
Intent intent = new Intent("android.intent.action.myBroadcast");
intent.putExtra("msg", "hello receiver.");
sendBroadcast(intent);//发送普通广播
这样,对于我们上面注册了的接收器,就可以根据这里发出的广播动作:android.intent.action.myBroadcast进行监听。对于动作如何命名,个人觉得还是要和系统的前缀保持一致,后面的动作名字就可以根据自己的情况进行命名。
普通广播对于多个接收者来说是完全异步的,通常每个接收者都无需等待即可以接收到广播,接收者相互之间不会有影响。对于这种广播,接收者无法调用abortBroadcast()方法终止广播,即无法阻止其他接收者的接收动作。比如我在action后面加上自己的动作myBroadcast。
有序广播
有序广播每次只发送到优先级较高的接收者那里,然后由优先级高的接受者再传播到优先级低的接收者那里,优先级高的接收者有能力终止这个广播。
静态注册在intent-filter里面,有一个设置接收者优先级高低的属性,android:priority=“1000”。此属性接收一个int类型的参数,参数数值介于-1000-1000之间,数值越大说明优先级越高。
<receiver android:name=".FirstReceiver">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.myBroadcast"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
动态注册广播:
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();//过滤器
filter.setPriority(“1000”);//这里我们给我们的接收器设定一个优先级
filter.addAction(“android.intent.action.myBroadcast”);//添加广播
我们发送广播的代码如下:
Intent intent = new Intent("android.intent.action.MY_BROADCAST");
intent.putExtra("msg", "hello receiver.”);
sendOrderedBroadcast(intent, yaojt.com.permission.permission);
注意,使用sendOrderedBroadcast方法发送有序广播时,需要一个权限参数,如果为null则表示不要求接收者声明指定的权限,如果不为null,则表示接收者若要接收此广播,需声明指定权限。这样做是从安全角度考虑的,例如系统的短信就是有序广播的形式,一个应用可能是具有拦截垃圾短信的功能,当短信到来时它可以先接受到短信广播,必要时终止广播传递,这样的软件就必须声明接收短信的权限。
这里我们设定一个权限,只有设定了权限的接收器才能够响应广播。
本地广播:
我们还有一个本地广播的管理器。就是这个管理器指定我们的广播接收器和发送的广播,都在我们的程序内,而不会被其他程序监听到。基本用法和普通广播一样,只是作用域不同而已。
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getApplicationContext());
注册:
lbm.registerReceiver(receiver, intentFilter);
发送广播:
lbm.sendBroadcast(intent);
这样的好处就是广播作用域小了,其他应用收不到我们发出的广播,所以更佳安全。
监听系统广播:
系统会发出很多的广播,例如,网络状态改变,电量改变,sms短信和来电等等,系统都会发出相应的广播。而我们要做的就是注册我们需要监听的广播,即是各取所需,然后作出相应的动作即可。
在这里我们做一个监听网络状态变化的广播,因为现在的程序基本上都是需要联网完成相应的操作的。
首先我们需要网络权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
写我们需要的网络状态监听的类
public class NetworkStateReceiver extends BroadcastReceiver {
private static final String TAG = "NetworkStateReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "network state changed.");
if (!isNetworkAvailable(context)) {
Toast.makeText(context, "network disconnected!", 0).show();
}
}
/**
* 网络是否可用
*
* @param context
* @return
*/
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] info = mgr.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
return false;
}
}
最后在配置文件里面注册监听即可,也可以进行动态注册,但是网络监听一般是是进入程序就需要进行监听的。