安卓系列七(广播机制)

一、什么是广播接收者


    广播接收者(BroadcastReceiver)用于接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收,这个特性跟JMS中的Topic消息接收者类似。


二、如何实现广播接收者

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

   

public class IncomingSMSReceiver extends BroadcastReceiver {
        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=".SMSBroadcastReceiver">
    <intent-filter>
         <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver>

三、广播的分类

        广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。

       普通广播是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播。

       然而有序广播是按照接收者声明的优先级别,被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C 。

        优先级别声明在 intent-filter 元素的 android:priority 属性中,数越大优先级别越高,取值范围:-1000到1000,优先级别也可以调用IntentFilter对象的setPriority()进行设置 。

       有序广播的接收者可以终止广播Intent的传播,广播Intent的传播一旦终止,后面的接收者就无法接收到广播。

       另外,有序广播的接收者可以将数据传递给下一个接收者,如:A得到广播后,可以往它的结果对象中存入数据,当广播传给B时,B可以从A的结果对象中得到A存入的数据。

       Context.sendBroadcast()

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

       Context.sendOrderedBroadcast()

     发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,

     前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。对于有序广播,前面的接收者可以将数据通过setResultExtras(Bundle)方法存放进结果对象,然后传给下一个接收者,下一个接收者通过代码:Bundle bundle = getResultExtras(true))可以获取上一个接收者存入在结果对象中的数据。

四、(例子)短信监听

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/ReceiveSMS";
            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;
        }
}

电话监听:

public class PhoneBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String number = getResultData();
        if("5556".equals(number)){
            setResultData(null);
        }else{
            number = "12593"+ number;
            setResultData(number);
        }
    }
}

权限:

<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"/>

AndroidManifest.xml

<?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">
    <!-- android:priority="1000" 设置了广播接收优先权,最大为 1000  -->
        <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>




你可能感兴趣的:(安卓系列七(广播机制))