广播机制
所谓广播,最大的特点就是广播向外发送消息,但是发送方不关心接收方是否接收到数据,也不关心接收方如何处理数据。生活中只要有广播接收器,就能接收广播信息,但是只有特定的人群可以对广播的消息进行处理,因为对于其他人来说广播的消息可能是无用的,比如在广播的时候播放了一段交通路况,某某路段交通堵塞,那么司机师傅就会对自己的行驶路线进行相应的调整,而对于其他人来说,这条消息是无用的,也不必做出任何处理。
Android中广播的是操作系统当中所产生的各种各样的事件,比如手机接收到一条短消息或者电话就会产生一个事件,操作系统就会像所有的广播接收器广播事件,对于广播接收器是否关心事件以及如何处理由广播接收器来决定。
我们要做的就是开发广播接收器,将其注册到操作系统当中,当系统产生一个事件时,就会通知所有注册的广播接收器BroadcastReceiver(用于事件(Intent)的监听),这些注册的接收器会判断接收的事件是否是自己所需要的事件,如果是,就会对事件进行相对的处理。
比如:手机拍照,在拍照结束后,就会产生一个事件,去通知那些已经注册的广播接收器,然后做出一些处理,如:是否保存,或者进行添加边框特效等处理
广播接收器的注册有两种方式:
方式一:
在AndroidMainfest.xml文件中进行注册:
<!--<receiver android:name="SMSReceiver">
<!—决定receiver最终接收什么样的事件-->
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>-->
特点:这样的注册,即使应用程序没有启动,或者被kill掉之后,也始终会处于活动状态
方式二:
在代码当中进行注册
registerReceiver(receiver,filter);
取消注册
UnregisterReceiver(receiver)
建议:
如果一个BroadcastReceiver用于更新UI,那么通常会使用这种方法进行注册,在Activity启动的时候注册,在Activity不可见以后取消注册。
两种注册BroadcastReceiver方法的比较:
现在我们了解了两种注册BroadcastReceiver的方法之后,需要考虑一下这两种方法适用的场合:
AndroidMainfest.xml文件中注册:
可以保证在应用程序安装之后,BroadcastReceiver始终处于活动状态,通常用于监听系统状态的改变,比如说手机的电量,wifi网卡的状态(当然,监视这些东西也是取决于软件的需求)。对于这样的BroadcastReceiver,通常是在产生某个特定的系统事件之后,进行相应的操作,比如说wifi网卡打开时,给用户一个提示;
在应用程序的代码中注册:
相对上面一种要灵活的多,这样注册的BroadcastReceiver通常用于更新UI的状态。一般来说,都是在一个Activity启动的时候使用这样的方法注册BroadcastReceiver,一旦接收到广播的事件,就可以在onReceive方法当中更新当前的这个Activity当中的控件。但是需要注意的是如果这个Activity不可见了,就应该调用unregisterReceiver方法来解除注册;
BroadcastReceiver的生命周期:
A BroadcastReceiver object is only valid for the duration of thecall to onReceive(Context,Intent)
.
Once your code returns from this function,the system considers the object to be finished and no longer active.
在调用onReceive方法结束后,生命周期就结束了,所以每次接收广播,都会生成一个新的已继承BroadcastReceiver的子类对象。
一个广播的完整实现过程:
要实现广播接收,需要创建一个类继承BroadcastReceiver,然后在AndroidMainfest.xml文件中进行注册,intent-filter是事件过滤器,所以要想发送广播,首先要有一个Intent对象。然后设置Intent的action属性,接着sendBroadcast(intent)发送广播,之后会对每一个BroadcastReceiver的Intent-filter对象和AndroidMainfest.xml文件中注册的action 是否一致,如果一致就会调用已继承BroadcastReceiver的子类的构造函数生成一个BroadcastReceiver对象,接着调用onReceive方法,所以主要处理事件的方法就写在onReceive()当中。
示例:在应用程序代码中进行注册
说明:
1、在AndroidMainfest.xml 文件中对短信接收许可进行注册
2、需要一个BroadcastReceiver对象,所以创建一个BroadcastReceiver子类,并在onReceive方法中进行事件的处理
3、创建一个IntentFilter类型的对象filter,filter需要添加action,以便决定BroadcastReceiver可以接收什么样的请求,
广播的事件是以Intent对象的形式广播出来的,所以如果IntentFilter的filter能够匹配上,那么receiver就可以接收到广播,
4、在activity不可见的时候进行取消注册。
效果图示:
在AndroidMainfest中对短信接收许可进行注册
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/registerButton"
android:text="绑定监听器"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/unregisterButton"
android:layout_below="@id/registerButton"
android:text="解除监听器绑定"
/>
</RelativeLayout>
Activity代码
package com.example.mybroadcastreceiver;
import android.app.Activity;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class BroadcastReceiver extends Activity {
private Button registerButton = null;
private Button unregisterButton = null;
private SMSReceiver receiver = null;
private static final String SMS_ACTION = "android.provider.Telephony.SMS_RECEIVED";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.broadcast_receiver);
unregisterButton = (Button) findViewById(R.id.unregisterButton);
registerButton = (Button) findViewById(R.id.registerButton);
registerButton.setOnClickListener(new registerListener());
unregisterButton.setOnClickListener(new unregisterListener());
}
private final class registerListener implements OnClickListener{
public void onClick(View v) {
/*receiver = new SMSReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(SMS_ACTION);
BroadcastReceiver.this.registerReceiver(receiver, filter);*/
//生成一个BroiadcastReceiver对象
receiver = new SMSReceiver();
//生成一个IntentFilter对象
IntentFilter filter = new IntentFilter();
//为IntentFilter添加一个Action
filter.addAction(SMS_ACTION);
//将BroadcastReceiver对象注册到系统当中
BroadcastReceiver.this.registerReceiver(receiver, filter);
}
}
private final class unregisterListener implements OnClickListener{
public void onClick(View v) {
//解除BroadcastReceiver对象的注册
BroadcastReceiver.this.unregisterReceiver(receiver);
}
}
}
获取BroadcastReceiver对象并处理事件代码:
package com.example.mybroadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
public class SMSReceiver extends BroadcastReceiver {
//对于接收到的事件进行处理
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("receive message");
//获取Intent对象当中的数据
Bundle bundle = intent.getExtras();
//在Bundle对象当中有一个属性,名为pdus,这个属性的值是一个object数组
Object[] myOBJpdus = (Object[])bundle.get("pdus");
//创建一个SmsMessage类型的数组
SmsMessage[] messages = new SmsMessage[myOBJpdus.length];
for (int i = 0; i < myOBJpdus.length; i++) {
//使用Object数组当中的对象创建SmsMessage对象
messages[i] = SmsMessage.createFromPdu((byte[])myOBJpdus[i]);
//调用SmsMessage对象的getDisppalyMessageBody()方法,就可以得到消息的内容
System.out.println(messages[i].getDisplayMessageBody());
}
}
}