一、广播接收者
使用BroadcastReceiver来实现广播接收者查看短信
原理:当系统收到短信时,会发出一个action 名称为:android.provider.Telephony.SMS_RECEIVED的Intent,使用名称"pdus"可以从Intent中获取到系统接收到的短信内容。
二、广播接收者的两种注册方式:
1、在AndroidManifest.xml文件中通过receiver标签静态注册,例子:
<receiver android:name=".SmsBroadcastReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
public class MainActivity extends Activity {
private final static String ACTION_SEND = "android.provider.Telephony.SMS_RECEIVED";
private SmsBroadcastReceiver receiver;
@Override
protected void onResume() {
registerReceiver(receiver, new IntentFilter(ACTION_SEND));
}
@Override
protected void onPause() {
unregisterReceiver(receiver);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
receiver = new SmsBroadcastReceiver();
}
}
三、关于registerReceiver动态注册和通过receiver标签静态注册广播的区别如下:
1.对bindService的调用,receiver注册的广播,在onReceive结束后广播即不存在,所以不能在其中给自己异步传递结果,如bindService而只能使用startService,如果想跟service交互可使用peekService。
2. 手动控制。registerReceiver为动态注册,自己可以手动注册或是取消注册;receiver标签为静态注册,由系统开机时自动扫描注册,所以无法手动控制,开机一直运行中。
3. 资源消耗不同。registerReceiver可以手动控制,所以适当的注册和取消注册能节省系统资源,receiver标签系统开机后一直有效。
4. 有效期不同。通过registerReceiver注册的BroadcastReceiver在对其进行注册的Context对象"销毁"了或者调用了unregisterReceiver方法时也就失效了,而通过receiver标签注册的BroadcastReceiver只要应用程序没有被删除就一直有效。
5. 对registerReceiver函数的调用许可不同。通过registerReceiver注册的BroadcastReceiver在其onReceive函数中可以再次调用某个Context的registerReceiver函数,而通过receiver标签注册的BroadcastReceiver不允许再调用某个Context的registerReceiver函数 。
6. 使用情况不同。对于自己发送和接受的广播可以通过registerReceiver注册,对于系统常用广播的接收通常用receiver标签注册。
四、广播接收者 实现代码:
public class SmsBroadcastReceiver extends BroadcastReceiver {
private final static String Tag = "SmsBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.i(Tag, "onReceive");
//pdus表示短信意图
Object[] pdus = (Object[])intent.getExtras().get("pdus");
for(Object p : pdus){
byte[] pdu = (byte[]) p;
SmsMessage message = SmsMessage.createFromPdu(pdu);
//短信内容
String content = message.getMessageBody();
Date date = new Date(message.getTimestampMillis());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String receiveTime = format.format(date);
//短信发送地址
String senderNumber = message.getOriginatingAddress();
sendSms(content,receiveTime,senderNumber);
//onReceive在10秒内没有执行完毕,android会认为程序没有相应,所以不要使用子线程,以免被中断
//new Thread(new sendSms(content,receiveTime,senderNumber)).start();
}
}
private boolean sendSms(String content, String receiveTime, String senderNumber){
//web服务地址
String path = "http://192.168.23.51:8080/SmsListener/SmsReceive";
try {
String params = "content="+URLEncoder.encode(content,"UTF-8")
+"&receiveTime="+receiveTime+"&senderNumber="+senderNumber;
byte[] entity = params.getBytes();
HttpURLConnection conn = (HttpURLConnection)new URL(path).openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-length", String.valueOf(entity.length));
conn.getOutputStream().write(entity);
if(conn.getResponseCode()==200){
Log.i(Tag, "receive sms success");
return true;
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i(Tag, e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i(Tag, e.getMessage());
}
Log.i(Tag, "receive sms failure");
return false;
}
}
web服务端代码如下:
/**
* Servlet implementation class SmsReceive
*/
public class SmsReceive extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String content = request.getParameter("content");
String receiveTime = request.getParameter("receiveTime");
String senderNumber = request.getParameter("senderNumber");
System.out.println("content:"+content);
System.out.println("receiveTime:"+receiveTime);
System.out.println("senderNumber:"+senderNumber);
}
}