android中BroadCastReceiver使用(廣播的接受和發送)

來源:互聯網
上載者:User

一.BroadCastReceiver 簡介 

1.廣播接收者( BroadcastReceiver )用於接收廣播 Intent ,廣播 Intent 的發送是通過調用Context.sendBroadcast() 、 Context.sendOrderedBroadcast() 來實現的。通常一個廣播 Intent 可以被訂閱了此Intent 的多個廣播接收者所接收。

 

2.廣播是一種廣泛運用的在應用程式之間傳輸資訊的機制 。而 BroadcastReceiver 是對發送出來的廣播進行過濾接收並響應的一類組件;

 

3.生命週期只有十秒左右,如果在 onReceive() 內做超過十秒內的事情,就會報錯 

 

每次廣播到來時 , 會重新建立 BroadcastReceiver 對象 , 並且調用 onReceive() 方法 , 執行完以後 , 該對象即被銷毀 . 當 onReceive() 方法在 10 秒內沒有執行完畢, Android 會認為該程式無響應 . 所以在BroadcastReceiver 裡不能做一些比較耗時的操作 , 否側會彈出 ANR(ApplicationNo Response) 的對話方塊 。

 

4.怎麼用好 BroadcastReceiver ?

如果需要完成一項比較耗時的工作 , 應該通過發送 Intent 給 Service, 由 Service 來完成 . 這裡不能使用子線程來解決 , 因為 BroadcastReceiver 的生命週期很短 , 子線程可能還沒有結束BroadcastReceiver 就先結束了 .BroadcastReceiver 一旦結束 , 此時 BroadcastReceiver 的所在進程很容易在系統需要記憶體時被優先殺死 , 因為它屬於空進程 ( 沒有任何活動組件的進程 ). 如果它的宿主進程被殺死 , 那麼正在工作的子線程也會被殺死 . 所以採用子線程來解決是不可靠的 。如一個代理程式更新其他應用程式某些資料已經下載完畢。BroadcastReceiver 自身並不實現圖形化使用者介面,但是當它收到某個通知後, BroadcastReceiver 可以啟動Activity 作為響應,或者通過 NotificationMananger 提醒使用者,或者啟動 Service 等等。

 

 

 

二.BroadCastReceiver 代碼的實現

用接收簡訊舉例:

第一種方式 :在AndroidManifest.xml中註冊廣播,則全域接受,即在任何的Activity中運行時,如果收到簡訊都會調用改廣播

1.1建立一個SmsReceiver.java,當收到簡訊時調用改廣播

packagecom.yuqiaotech.sms;

importandroid.app.PendingIntent;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import android.telephony.SmsMessage;

import android.util.Log;

import android.widget.Toast;

 

 

 

public
class
SmsReceiver extends BroadcastReceiver{

    public
static final
int
NOTIFICATION_ID= 10001;

 

   @Override

   publicvoidonReceive(Context context, Intent intent) {

           showTost(context,intent);

     }

   

   

   /*

     * 使用toast顯示短訊息

     */

   privatevoidshowTost(Context context, Intent intent) {

    String strRes = "android.provider.Telephony.SMS_RECEIVED";

    if (intent.getAction().equals(strRes)) {

         StringBuilder sb = new StringBuilder();

         Bundle bundle = intent.getExtras();

   

         if (bundle !=null){

             Object[] pdus = (Object[]) bundle.get("pdus");

             SmsMessage[] msg = new SmsMessage[pdus.length];

             for (inti = 0; i < pdus.length;i++) {

                 msg[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);

             }

       

             for (SmsMessage currMsg : msg) {

                 sb.append("您收到了來自:【");

                 sb.append(currMsg.getDisplayOriginatingAddress());

                 sb.append("】\n的資訊,內容:");

                 sb.append(currMsg.getDisplayMessageBody());

             }

       

             Toast toast = Toast.makeText(context,
"收到了短訊息: " + sb.toString(),Toast.LENGTH_LONG); 

             toast.show();  

         }

    } 

   }

 

 

}

1.2在AndroidManifest.xml中註冊廣播

<receiverandroid:name=".SmsReceiver" android:enabled="true">  

            <intent-filter>

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

            </intent-filter>

        </receiver> 

 

第二種方式 :在代碼中註冊廣播,則局部接受,即只有在註冊的activity運行時,如果收到簡訊才會調用該廣播

  2.1隨便建立一個activity,smsTest.java,在onCreate()中添加代碼:

//註冊新的簡訊接收

String SMS_RECEIED="android.provider.Telephony.SMS_RECEIVED ";      

IntentFilter filter = new IntentFilter(SMS_RECEIVED);

         registerReceiver(newSmsReceiver(), filter);

 

 

廣播類型及廣播的收發廣播類型

普通廣播 (Normal broadcasts)

  發送一個廣播,所以監聽該廣播的廣播接收者都可以監聽到改廣播。

非同步廣播 , 當處理完之後的Intent ,依然存在,這時候registerReceiver(BroadcastReceiver, IntentFilter) 還能收到他的值,直到你把它去掉 , 不能將處理結果傳給下一個接收者 , 無法終止廣播 .

有序廣播 (Ordered broadcasts)

按照接收者的優先順序順序接收廣播 , 優先順序別在 intent-filter 中的 priority 中聲明 ,-1000 到

1000 之間 , 值越大 , 優先順序越高 . 可以終止廣播意圖的繼續傳播 . 接收者可以篡改內容 .

 

 

 

廣播的收發

該組件接收被廣播的 intent,Context 可以通過 sendBroadcast() 和 sendOrderedBroadcast()

方法實現廣播的發送 。首先在需要發送資訊的地方 ,把要發送的資訊和用於過濾的資訊 ( 如 Action 、 Category) 裝入一個 Intent 對象,然後通過調用 Context.sendBroadcast() 、 sendOrderBroadcast() 或 sendStickyBroadcast() 方法,把 Intent對象以廣播方式發送出去。

 

使用 sendBroadcast() 或 sendStickyBroadcast() 方法發出去的 Intent ,所有滿足條件的 BroadcastReceiver 都會隨機地執行其 onReceive() 方法

 普通廣播的發送和接收:

sendBroadcast(intent);

 

Intent intent = new Intent( "cn.lenovo.yangguangf " );

        sendBroadcast(intent);

priority :這個是 AndroidManifest.xml 中 intent-filter 的參數。

 

< receiver android:name = ".MyBroadcastReceiver" >

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

             

< action android:name = "cn.lenovo.yangguangfu" />

</ intent-filter >

</ receiver >

 

   

有序廣播的發送和接收:

sendOrderedBroadcast(intent, receiverPermission);

sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData,initialExtras)意圖,廣播,所有匹配的這一意圖將接收機接收廣播。

receiverPermission 這是許可權,一個接收器必須持以接收您的廣播。如果為 null ,不經許可的要求。 resultReceiver 您自己 BroadcastReceiver 來當作最後的廣播接收器。 
調度自訂處理常式,用以安排 resultReceiver 回調 ; 如果為 null 將語境中的主線程舉行。 
initialCode 一種結果代碼的初始值。通常為 Activity.RESULT_OK 。這個值是 -1 ;為其他 int 型 也可以,如 0,1,2; 
initialData 一種結果資料的初始值。通常情況下為空白 , 是 String 類型 ;
initialExtras 一種結果額外的初始值。通常情況下為空白 , 是 Bundle;

 

1,  該廣播的層級有層級之分,層級數值是在 -1000 到 1000 之間 , 值越大 , 優先順序越高;

2,  同層級接收是先後是隨機的,再到層級低的收到廣播;

3,  同層級接收是先後是隨機的,如果先接收到的把廣播截斷了,同層級的例外的接收者是無法收到該廣播的。(abortBroadcast() )

 

4 ,能截斷廣播的繼續傳播,進階別的廣播收到該廣播後,可以決定把該鐘廣播是否截斷掉。

5 ,實驗現象,在這個方法發來的廣播中,代碼註冊方式中,收到廣播先後次序為:註明優先順序的、代碼註冊的、沒有優先順序的;如果都沒有優先順序,代碼註冊收到為最先。

 

 

非同步廣播的發送和接收:

sendStickyBroadcast(intent);

當處理完之後的Intent ,依然存在,直到你把它去掉。發這個廣播需要許可權<uses-permissionandroid:name="android.permission.BROADCAST_STICKY" />去掉是用這個方法removeStickyBroadcast(intent); 但別忘了在執行這個方法的應用裡面 AndroidManifest.xml同樣要加上面的許可權;

 

sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, initialData,initialExtras)

這個方法具有有序廣播的特性也有非同步廣播的特性;

 

發送這個廣播要: <uses-permission android:name="android.permission.BROADCAST_STICKY" /> 這個許可權。才能使用這個方法。如果您並不擁有該許可權,將拋出 SecurityException 的。

 

實驗現象( sendStickyOrderedBroadcast ()中),在這個方法發來的廣播中,代碼註冊方式中,收到廣播先後次序為:註明優先順序的、代碼註冊的、沒有優先順序的;如果都沒有優先順序,代碼註冊收到為最先。

 

廣播註冊與登出代碼中註冊廣播:

註冊廣播方法一: registerReceiver(BroadcastReceiverreceiver, IntentFilter filter) ,第一個參數是我們要處理廣播的 BroadcastReceiver (廣播接收者,可以是系統的,也可以是自訂的);第二個參數是意圖過濾器。

 

註冊廣播方法二: registerReceiver(receiver,filter, broadcastPermission, scheduler) ,第一個參數是BroadcastReceiver (廣播接收者,可以是系統的,也可以是自訂的);第二個參數是意圖過濾器;第三個參數是廣播許可權;第四個參數是 Hander ;

 

注意:許可權重複現象,如果功能資訊清單檔裡註冊了許可權,在該方法再註冊,則 receiver 無法收到廣播,如果 功能資訊清單檔裡沒有註冊了許可權,該方法註冊也無法收到。當該方法沒有註冊許可權,功能清單裡註冊的時候, receiver 能收到廣播。

 

系統中註冊廣播:(在 AndroidManifest.xml 中 )

< receiver android:name = ".MyBroadcastReceiver" >

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

             

              < action android:name = "cn.lenovo.yangguangfu" />

           </ intent-filter >

</ receiver >

有時候還要根據發送廣播是否指定許可權,來決定是否要許可權;

 

廣播登出

 

// 代碼中登出廣播

unregisterReceiver(mBatteryInfoReceiver);

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.