BroadcastReceiver广播接收者
1.简单介绍:
android四大组件之一,本质上是一个全局的监听器,用来监听全局的广播信息,可以方便的实现系统的不同组件的通信。
2.流程分析
首先要明确发送的信息,然后明确发送广播的地方,把过滤的信息和发送的信息都放入到intent的对象当中,然后
sendBroadcast的方法,发送广播。
当把广播信息发送出去之后,已经注册的广播接收者都会检测自己的过滤信息,看看是否符合条件,如果符合条件就
接受广播,如果不符合条件,就不接收。
3.定义:
广播接收者可以接收某个频道(action)发来的广播,发送者可能是activity也可能是service
4.作用:
(1).监听系统的广播,并且做出相应的处理,比如电量过低可以保存应用中重要的数据,向用户发出警告。
系统常用的广播:
1.电池电量:电量过低可以保存应用中重要的数据
2.可以通过广播获得用户拨打的电话号码。
3.检测联网情况
4.检测收到的短信
5.耳机的插入和拨出
6.开机收到启动广播(6.0失效了)
(2).后台运行的服务在完成耗时操作后,比如网络下载文件,获取数据成功后,会通知activity进行更新。
5.用法:
1.创建一个类,让这个类继承于BroadcastReceiver。
2.必须要重写onReceive(Context context, Intent intent)方法。
3.注册广播
静态注册: 在清单文件中注册 (全局的)
<receiver android:name="全类名">
<!--意图过滤器标签-->
<intent-fileter>
<!--过滤器,name对应的过滤的内容-->
<action android:name=""/>
</intent-fileter>
</receiver>
动态注册:(局部的)
IntentFilter filter = new IntentFilter ();
filter.setAction("");
context.registerReceiver (receiver,filter);
静态注册和动态注册的区别:
动态注册会比静态注册使用更加灵活。
当使用静态方法注册广播时,不管程序是否开启,都能够接受到发送来的广播,
静态注册每次有消息都会由系统new一个处理器,进行处理,然后销毁。
动态注册的广播,程序执行后能收到对应的广播,如果没有执行unregisterReceiver方法
去取消注册,和静态注册就差不多了,动态生成的广播接受者必须用代码去销毁,
每次处理消息也会生成新的处理器
广播的发送:
广播的分类:
1.普通广播 :依次传递给各个接受者去处理:
发送广播的步骤:
Intent intent = new Intent();
intent.setAction("消息的描述");
// intent.putString("","");
context.sendBroadcast(intent);
2.有序广播:这种广播的处理顺序是按照广播接受者的优先级进行排序的,高优先级就会优先接受到这条广播。
一般发送这种广播,高优先级的接受器会先接收到并且拦截广播,那么低优先级的接收者就接受不到了。
3.粘性广播:发送之后会一致存在于系统的消息容器当中,直到处理他的接受这出现为止。(api21过时)
发送粘性广播需要权限: BROADCAST_STICKY
发送粘性广播的方法: sendStickyBroadcast (Intent intent)
关于广播的注意事项
1.广播接受者的生命周期是非常短暂的,在接收到广播时被创建,在onReceive方法结束之后被销毁。
2.广播接收者中不要做耗时操作,等待时间超过10秒就会弹出Application Not Responding的错误对话框。
3.最好也不要在广播接收者中创建子线程,然后在子线程中做耗时操作,因为在广播接收者被销毁之后,
就拿不到这个线程的引用了,那么子线程就会编程空线程,很容易会被系统杀死。
实例二:
1.简单介绍:
android四大组件之一,本质上是一个全局的监听器,用来监听全局的广播信息,可以方便的实现系统的不同组件的通信。
2.流程分析
首先要明确发送的信息,然后明确发送广播的地方,把过滤的信息和发送的信息都放入到intent的对象当中,然后
sendBroadcast的方法,发送广播。
当把广播信息发送出去之后,已经注册的广播接收者都会检测自己的过滤信息,看看是否符合条件,如果符合条件就
接受广播,如果不符合条件,就不接收。
3.定义:
广播接收者可以接收某个频道(action)发来的广播,发送者可能是activity也可能是service
4.作用:
(1).监听系统的广播,并且做出相应的处理,比如电量过低可以保存应用中重要的数据,向用户发出警告。
系统常用的广播:
1.电池电量:电量过低可以保存应用中重要的数据
2.可以通过广播获得用户拨打的电话号码。
3.检测联网情况
4.检测收到的短信
5.耳机的插入和拨出
6.开机收到启动广播(6.0失效了)
(2).后台运行的服务在完成耗时操作后,比如网络下载文件,获取数据成功后,会通知activity进行更新。
5.用法:
1.创建一个类,让这个类继承于BroadcastReceiver。
2.必须要重写onReceive(Context context, Intent intent)方法。
3.注册广播
静态注册: 在清单文件中注册 (全局的)
<receiver android:name="全类名">
<!--意图过滤器标签-->
<intent-fileter>
<!--过滤器,name对应的过滤的内容-->
<action android:name=""/>
</intent-fileter>
</receiver>
动态注册:(局部的)
IntentFilter filter = new IntentFilter ();
filter.setAction("");
context.registerReceiver (receiver,filter);
静态注册和动态注册的区别:
动态注册会比静态注册使用更加灵活。
当使用静态方法注册广播时,不管程序是否开启,都能够接受到发送来的广播,
静态注册每次有消息都会由系统new一个处理器,进行处理,然后销毁。
动态注册的广播,程序执行后能收到对应的广播,如果没有执行unregisterReceiver方法
去取消注册,和静态注册就差不多了,动态生成的广播接受者必须用代码去销毁,
每次处理消息也会生成新的处理器
广播的发送:
广播的分类:
1.普通广播 :依次传递给各个接受者去处理:
发送广播的步骤:
Intent intent = new Intent();
intent.setAction("消息的描述");
// intent.putString("","");
context.sendBroadcast(intent);
2.有序广播:这种广播的处理顺序是按照广播接受者的优先级进行排序的,高优先级就会优先接受到这条广播。
一般发送这种广播,高优先级的接受器会先接收到并且拦截广播,那么低优先级的接收者就接受不到了。
3.粘性广播:发送之后会一致存在于系统的消息容器当中,直到处理他的接受这出现为止。(api21过时)
发送粘性广播需要权限: BROADCAST_STICKY
发送粘性广播的方法: sendStickyBroadcast (Intent intent)
关于广播的注意事项
1.广播接受者的生命周期是非常短暂的,在接收到广播时被创建,在onReceive方法结束之后被销毁。
2.广播接收者中不要做耗时操作,等待时间超过10秒就会弹出Application Not Responding的错误对话框。
3.最好也不要在广播接收者中创建子线程,然后在子线程中做耗时操作,因为在广播接收者被销毁之后,
就拿不到这个线程的引用了,那么子线程就会编程空线程,很容易会被系统杀死。
4.耗时操作在服务当中完成。
实例:获得系统广播:
public class MainActivity extends Activity {
private BatteryReceiver batteryReceiver;
private HeadSetPlugReceiver headSetPlugReceiver;
private NetStateChangeReceiver netStateChangeReceiver;
private ScreenOnOffReceiver screenOnOffReceiver;
private SMSReceiver smsReceiver;
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv =(TextView)findViewById(R.id.tv);
registerBatteryChangedReceiver();
registerNetStateReceiver();
registerSmsReceiver();
}
// 注册电池电量变化
private void registerBatteryChangedReceiver() {
batteryReceiver = new BatteryReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryReceiver, filter);
}
//注册网络状态的变化
private void registerNetStateReceiver(){
netStateChangeReceiver = new NetStateChangeReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(netStateChangeReceiver, filter);
}
//注册接受短信的广播
private void registerSmsReceiver(){
smsReceiver = new SMSReceiver(new MessageListener() {
@Override
public void sendMessage(String msg) {
tv.setText(msg);
}
});
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smsReceiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (batteryReceiver != null) {
unregisterReceiver(batteryReceiver);
}
if (headSetPlugReceiver!=null) {
unregisterReceiver(headSetPlugReceiver);
}
if (netStateChangeReceiver!=null) {
unregisterReceiver(netStateChangeReceiver);
}
if (screenOnOffReceiver!=null) {
unregisterReceiver(screenOnOffReceiver);
}
if (smsReceiver!=null) {
unregisterReceiver(smsReceiver);
}
}
}
public class BatteryReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
//获得电池电量的等级
int level = intent.getIntExtra("level", 0);
//获取总电量信息
int total = intent.getIntExtra("scale", 100);
//计算当前电量
int current = (level*100)/total;
Log.i("tag", "当前电量为:"+current+"%");
}
}
}
public class NetStateChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//判断网络连接状态的广播过滤
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
//得到网络连接管理器的实例
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
//通过manager来获取当前的网络信息
NetworkInfo info = manager.getActiveNetworkInfo();
//判断当前网络信息不为null而且是可用的
if (info!=null&&info.isAvailable()) {
if (info.getType()==ConnectivityManager.TYPE_MOBILE) {
Log.i("tag", "当前使用的网络是移动网络");
}else if (info.getType()==ConnectivityManager.TYPE_WIFI) {
Log.i("tag", "当前使用的网络是wifi提供的");
}
}
}
}
}
public class SMSReceiver extends BroadcastReceiver {
private MessageListener listener;
public SMSReceiver(MessageListener listener) {
super();
this.listener = listener;
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction()
.equals("android.provider.Telephony.SMS_RECEIVED")) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for (Object pdu : pdus) {
SmsMessage message = SmsMessage.createFromPdu((byte[])pdu);
//获取发送者信息
String sender = message.getDisplayOriginatingAddress();
//获取收到的信息的内容
String body = message.getMessageBody();
//获取接受到的时间
long time = message.getTimestampMillis();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = sdf.format(new Date(time));
Log.i("tag", "发送者为:"+sender);
Log.i("tag", "发送的信息为:"+body);
Log.i("tag", "接收到的时间为:"+date);
this.listener.sendMessage(sender+":"+body+":"+date);
if (sender.equals("15555215556")) {
abortBroadcast(); //拦截广播
}
}
}
}
public interface MessageListener{
public void sendMessage(String msg);
}
}
实例二:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//动态注册 设置优先级的方法
FirstReceiver receiver = new FirstReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.aa.data");
filter.setPriority(2);
registerReceiver(receiver, filter);
}
public void send(View view) {
Intent intent = new Intent();
intent.setAction("com.aa.data");
intent.putExtra("data", "今天的天气好晴朗~~~");
//发送普通广播
//sendBroadcast(intent);
//发送有序广播
sendOrderedBroadcast(intent, null);
}
}
public class FirstReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.aa.data")) {
String data = intent.getStringExtra("data");
Log.i("tag", "FirstReceiver=========="+data);
}
}
}
public class SecondReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.aa.data")) {
String key = intent.getStringExtra("data");
Log.i("tag", "SecondReceiver----------"+key);
//abortBroadcast();
}
}
}
<receiver
android:name="com.aa.sendbroad_demo01.SecondReceiver">
<intent-filter android:priority="50">
<action android:name="com.aa.data"/>
</intent-filter>
</receiver>