安卓四大组件之一:BroadcastRecevier的使用——初学者
- 发送无序广播——静态和动态方法注册
- 发送有序广播——静态和动态方法注册
- 接收一个系统广播——得到手机状态的变化
在现实生活中我们的的广播电台,每天都在为大家发送着各种各样的信息,有音乐广播,说书广播,咨询广播等等,收听电台的人只要 调好电台的频道就可以接收电台所广播的内容。安卓的广播也是这样,发送广播的界面相当于电台,接收广播的界面相当于收听者,接收者需要注册电台频率,然后接收电台发送来的广播(信号),接受到信号以后开始实行方法
先说一下 静态注册广播和动态的区别
静态广播可以进行不同进程的传播(不同APP可以互相发送广播,互相接收对方的广播)
动态广播只能在当前APP中传递广播
下面在Activity中有4个按钮点击之后用四种不同的方式发送自定义的广播
1.发送一个无序广播:发送一个广播接收的人可以同时接收到这个广播
①静态注册:就是在Manifests文件中注册
首先我们要先创建一个接收广播的页面,也就是电台的收听者
//接收者要继承BroadcastReceiver类,实现onReceive方法
public class MyBroadcast1 extends BroadcastReceiver {
//在onReceive中要写当接受到信号后执行的操作(当前界面,发送这个广播的intent)
@Override
public void onReceive(Context context, Intent intent) {
//接受到广播电台发送的信号,会用吐司打印一句话
Toast.makeText(context,"1号接收到了广播",Toast.LENGTH_SHORT).show();
}
要在Manifests中去注册这个广播接收者
<receiver android:name=".MyBroadcast1"><!--接收者的类名-->
<intent-filter>
<action android:name="com.xbl.b1"/><!--接收的频道号-->
</intent-filter>
</receiver>
因为我用的是AndroidStudio所以receiver的名字直接为类名,但是ecclipse要把接收者所在的包名也写上;频道号自定义一个即可
记下来就要在Activity中去点击按钮发送广播了
case R.id.static_disorder_broadcast:
//发送一个广播,广播接收者接收到广播弹出吐司
Intent intent =new Intent();
//用这个频道号去发送广播(与接收者接收的频道号要一样)
intent.setAction("com.xbl.b1");
//发送这个静态广播
sendBroadcast(intent);
break;
这样一个静态的无序广播就完成了,点击按钮发送广播,接收此频道号的接收者接收到广播,实行onReceive中的方法
②动态注册:动态注册就是在JAVA文件中注册接收者
同样先创建一个接收广播的继承类实现方法(弹出一个吐司)
public class MyBroadcast2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//getStringExtra("from")得到发送广播的人传来的信息
Toast.makeText(context,"二号接收到了广播"+intent.getStringExtra("from"),Toast.LENGTH_SHORT).show();
}
在JAVA文件中注册这个接收者
case R.id.activity_disorder_broadcast:
//发送一个广播,是动态注册的,最后也要取消注册,动态注册不可以跨Activity发送广播
myBroadcast2 =new MyBroadcast2();//实例化接收者
IntentFilter intentFilter=new IntentFilter();//实例化一个过滤器
intentFilter.addAction("com.xbl.b2");//设置接收的频道号
registerReceiver(myBroadcast2,intentFilter);//注册
//下面是发送广播
Intent intent2=new Intent();
intent2.putExtra("from","我来自BroadcastActivity");//通过putExtra方法向接收者传入数值
intent2.setAction("com.xbl.b2");//发送的频道号
sendBroadcast(intent2);//发送
break;
既然注册了就要取消注册 ,要不在退出程序的时候会报一个安全性能的错误,我是在onDestroy() 方法中取消注册的
静态注册是不用取消注册的
if (myBroadcast1!=null){
//程序退出时取消注册
unregisterReceiver(myBroadcast2);
}
2.有序广播:发送一个广播,根据接收者的优先级一层一层发送,优先级高的有权停止广播的继续发送,优先级为-1000-1000数越大优先级越高
①静态注册:
同理无序广播的静态注册,但是在注册时要将优先级写入priority=**在intent-filter中,这里有两个接收这个广播的人,但是优先级不一样,优先级高的会先执行onReceive方法
这里的频道是com.xbl.b3
<receiver android:name=".MyOrderlyReceive3">
<intent-filter android:priority="1">
<action android:name="com.xbl.b3"/>
</intent-filter>
</receiver>
<receiver android:name=".MyOrderlyReceive4">
<intent-filter android:priority="10">
<action android:name="com.xbl.b3"/>
</intent-filter>
</receiver>
创建两个接收者3,4
public class MyOrderlyReceive3 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"接收者3收到广播",Toast.LENGTH_SHORT).show();
}
public class MyOrderlyReceive4 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"接收者4收到广播",Toast.LENGTH_SHORT).show();
}
在Activity中发送这个有序的广播
case R.id.static_orderly_broadcast:
Intent intent3=new Intent();
intent3.setAction("com.xbl.b3");
//发送一个有序广播的方法多了一个Ordered
//第二个参数是权限名称,就是要想接收这个广播必须要加什么权限,现在传入的是null,不需要权限
sendOrderedBroadcast(intent3,null);
break;
通过执行代码便可知道会先弹出接听者4接听广播然后是接听者3
②动态注册:
同理无序广播在注册时需要在JAVA文件中进行注册,我们先实例化两个接收者吧
public class MyOrderlyReceive5 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"接收者5收到广播",Toast.LENGTH_SHORT).show();
}
}
public class MyOrderlyReceive6 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"接收者6收到广播",Toast.LENGTH_SHORT).show();
//截断广播的方法,如果接收者优先级高的话后面的接收者就接收不到广播了
abortBroadcast();
}
}
注册接收者:
case R.id.activity_orderly_broadcast:
//注册广播
myOrderlyReceive5=new MyOrderlyReceive5();
myOrderlyReceive6=new MyOrderlyReceive6();
IntentFilter intentFilter5=new IntentFilter();
intentFilter5.setPriority(1);
intentFilter5.addAction("com.xbl.b4");
IntentFilter intentFilter6=new IntentFilter();
intentFilter6.setPriority(10);
intentFilter6.addAction("com.xbl.b4");
registerReceiver(myOrderlyReceive5,intentFilter5);
registerReceiver(myOrderlyReceive6,intentFilter6);
//发送广播,发送一条广播就创建一个Intent send一次
//如果因为有两个接收者而Intent send两次 会相当于发送两次广播 每个接收者的onReceive会执行两次
Intent intent4=new Intent();
intent4.setAction("com.xbl.b4");
sendOrderedBroadcast(intent4,null);
break;
因为是动态 注册所以最后要取消注册
if (myOrderlyReceive5!=null){
unregisterReceiver(myBroadcast1);
}
if (myOrderlyReceive6!=null){
unregisterReceiver(myOrderlyReceive6);
}
最后结果:
因为6的优先级高所以会先将广播发送给6,但是6又把广播给终止了,所以优先级小的5接收不到广播,只打印6这一个吐司
3.截取系统发送的广播
静态注册,因为这是两个不同的进程之间进行的信息传递
接收者接收网络变化的信息,当网络变化的时候会给接收者发送一个广播,接收者接受到广播弹出网络状态的吐司
<receiver android:name=".MyReceive7">
<intent-filter>
<!--这不是自定义的广播所以name 要写系统广播的频道名称 -->
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
别忘了增加一个监听网络变化的权限
接收者接收到广播弹出吐司
public class MyReceive7 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//得到当前网络状态改变的一个类
ConnectivityManager manager= (ConnectivityManager) context.getSystemService(Service.CONNECTIVITY_SERVICE);
NetworkInfo info=manager.getActiveNetworkInfo();
//得到当前网络状态info.getTypeName(),3G 4G WIFI
if (info!=null){
Toast.makeText(context,"当前网络"+info.getTypeName(),Toast.LENGTH_SHORT).show();
}else {
//飞行模式的时候会弹出
Toast.makeText(context,"无网络",Toast.LENGTH_SHORT).show();
}
}
}
因为不是自己发送广播所以不用在Activity中调用Intent 和send去发送这个广播 ,只接受就可以了
退出程序(在后台运行) 调整网络状态,会在当前界面弹出 吐司(不一定在程序界面)
最后是布局文件代码
<Button
android:id="@+id/static_disorder_broadcast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送一个无序广播(静态注册)"
/>
<Button
android:id="@+id/activity_disorder_broadcast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送一个无序广播(动态注册)"
/>
<Button
android:id="@+id/static_orderly_broadcast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送一个有序广播(静态注册)"
/>
<Button
android:id="@+id/activity_orderly_broadcast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送一个有序广播(动态注册)"
/>
下面是常用的一些系统广播频道
http://blog.sina.com.cn/s/blog_7dbac1250101mt5h.html
谢谢大家