广播接收者其实就是 当 应用产生 发送短信,或者接到电话等的时候,在清单文件中配置action,然后定义一个类继承broadcastreceiver实现里面的onreceive方法(只要已发送广播,就走这个方法,所以逻辑就实现啦)
注意:广播接收的方法中不能直接开启activity。
Intent intent1=new Intent(context,main.class); intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//要设置flag,间接开启。 context.startActivity(intent1);
广播接收分为几种类型:系统自己的。还有自己定义的(无序与有序广播),特殊广播(操作比较平凡的,需要自己在代码中配置,入锁屏,开屏);
有序广播和无序广播的区别:
有序广播:发送方发出后,几乎同时到达多个广播接收者处,某个接收者不能接收到广播后进行一番处理后传给下一个接收者,并且无法终止广播继续传播;Context.sendBroadcast(intent);
有序广播:广播接收者需要提前设置优先级,优先级高的先接收到广播,优先级数值为-1000~1000,在AndroidManifest.xml的<intent-filter android:priority="xxx">设置;比如存在3个广播接收者A、B、C,优先级A>B>C,因此A最先收到广播,当A收到广播后,可以向广播中添加一些数据给下一个接收者(intent.putExtra()),或者终止广播(abortBroadcast());Context.sendOrderedBroadcast(intent);
1. 接收系统的广播步骤(以监听sd卡状态(卸载还是挂起)的广播接收者为例)
public class SdCardBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if("android.intent.action.MEDIA_MOUNTED".equals(action)){
System.out.println("sd卡已挂载");
}else if("android.intent.action.MEDIA_UNMOUNTED".equals(action)){
System.out.println("sd卡已卸载");
}
}
}
在清单文件中注册:
<receiver android:name="com.example.sdbroadcast.SdCardBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED"/>//挂起
<action android:name="android.intent.action.MEDIA_UNMOUNTED"/>//卸载
<data android:scheme="file"/>
</intent-filter>
</receiver>
只要在清单文件中注册了这些,当这些行为发生的时候,如:我把sd卡卸载的时候,就走onreceive方法。
2. 发送自定义的无序广播(有些行为在谷歌工程师是没有些看好的自己弄)
//设置点击事件,发送广播
public void startBroadcast(View view){
//开启广播
//创建一个意图对象
Intent intent = new Intent();//创建意图
//指定发送广播的频道
intent.setAction("com.example.BROADCAST");//自定义action,随便都可以,但是记得在清单文件中配置
//发送广播的数据
intent.putExtra("key", "发送无序广播,顺便传递的数据");//可以在intent放点数据,接受广播的时候就可以取出来
//发送
sendBroadcast(intent); //最重要的方法,声明了是无序的广播
}
public class UnorderedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
String data = intent.getStringExtra("key");
System.out.println("接受到了广播,action:"+ action +",data:"+data);
//接受到了广播,action:com.example.BROADCAST,data:发送无序广播,顺便传递的数据
}
}
//一定记得在清单文件中配置。
<receiver android:name="com.example.selfreceiver.UnorderedReceiver">
<intent-filter>
<action android:name="com.example.BROADCAST"/>
</intent-filter>
</receiver>
3. 发送自定义的有序广播(在无序广播的基础上面定义多个广播接收者,但是他们有优先权,谁先收到广播,然后一级一级往下面传)
// 发送有序广播
public void sendOrderedBroad(View view) {
Intent intent = new Intent();
intent.setAction("com.example.ORDERED");
// 发送无序广播
sendOrderedBroadcast(intent,//意图动作,指定action动作
null, //receiverPermission,接收这条广播具备什么权限
new FinalReceiver(),//resultReceiver,最终的广播接受者,广播一定会传给他(这个是当权限最高的终止广播的时候,对它没有影响,他能接受到广播,而且不用再清单文件中配置,没必要的话也可以设置为null)
null, //scheduler,handler对象处理广播的分发
0,//initialCode,初始代码
"每人发10斤大米,不得有误!", //initialData,初始数据
null//initialExtras,额外的数据,如果觉得初始数据不够,可以通过bundle来指定其他数据
);
}
//这些类在清单文件中定义自己的优先级。
他的优先级是-1000到1000,数字随意。
1) 权限高的广播接收者可以修改广播,甚至可以终止广播
权限高的广播接收者1:
public class ShengReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//获取广播的数据
String data = getResultData();
//修改
setResultData("中央下达福利,每人5斤大米");
System.out.println("省政府收到指示, data : "+data);
}
}
在这里, 这个接收者修改广播为: "中央下达福利,每人5斤大米"
权限低的广播接收者
public class PeopleReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//获取广播的数据
String data = getResultData();
System.out.println("老百姓收到福利,感谢党, data : "+data);
}
}
2) 终止广播
权限高的广播接收者:
public class ShengReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//获取广播的数据
String data = getResultData();
//也可以终止广播,权限小的接收者就接收不到广播了
abortBroadcast(); 但是 new FinalReceiver(),这个对应的类可以收到。
System.out.println("省政府收到指示, data : "+data);
}
}
权限小的就接收不到广播了....后面所有的类。
(3) resultReceiver
可以在广播发送者的应用中建一个resultReceiver, 用于接收最终到达的广播,
无论广播是否终止,都会被resultReceiver接收
//唯一不需要再清单文件中配置
public class FinalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String resultData = getResultData();
System.out.println("人民收到的最终福利是: "+ resultData);
}
}
特殊的广播接收者:(屏幕的锁屏,电池电量的变化,这些在清单文件中就算注册了也没有用)
解决方法:动态注册,在代码中注册
主要类是screenreceiver(),动态添加action,就可以被接受啦。不过这种广播最好走activity的ondestory方法,当界面销毁的时候,注销广播, 用unregisterreceiver不然会出现a'cactivity泄漏的情况。(否则可以开启服务)