Android之Broadcast(廣播)

我叫阿狸貓發表於2014-02-10

注意:Android3.2版本之後,廣播不能直接啟用從來沒有在手機上使用過的應用程式,所以如果要寫一個打電話的廣播接收者,必須要帶一個Activity。

BroadcastReceiver

       1.什麼是BroadcastReceiver
                     Android手機在一些事件發生的時候會傳送廣播, 例如: 開機成功, 收到簡訊, 撥打電話, SD卡狀態改變, 電池狀態改變
                     我們在程式中可以建立一個接收者, 接收這些廣播, 處理對應的事件
       2.定義廣播接收者
                     定義類繼承BroadcastReceiver, 重寫onReceive()方法
                     在清單檔案中宣告<receiver>節點, 定義name屬性, 定義<intent-filter>和<action>指定要接收的廣播型別
                     <receiver>標籤中可以指定一個permission屬性, 要求傳送者必須持有指定許可權, 否則不接收.
       3.廣播的型別
              無序廣播:
                     所有接收者都可以收到, 不能中斷, 不能使用結果資料.
                     sendBroadcast()
                     在傳送時, 可以指定接收者許可權, 也可以不指定許可權. 如果指定了許可權, 那麼接收者必須持有這個許可權才能收到廣播.
              有序廣播:
                     多個接收者是逐個接收, 可以中斷, 可以使用結果資料.
                     sendOrderedBroadcast()
                     在傳送時和無序廣播一樣可以指定許可權.
                     另外在傳送有序廣播時, 可以指定一些結果資料, 這些資料會被傳遞到接收者中. 每個接收者可以接收這些資料, 也可以修改這些資料
                     有序廣播在接收者中可以呼叫abortBroadcast()中斷, 中斷之後, 後面的接收者就不能再收到廣播
                     有序廣播可以自定義一個接收者用來在廣播序列的最後一個接收廣播, 可以得到所有接收者修改之後的結果資料
              注意: 無論有序廣播還是無序廣播, 都可以使用Intent物件傳遞資料. 和Activity中相同.
       4.生命週期
              廣播接收者的生命週期非常短暫, 在收到廣播時建立, onReceive()方法結束後就銷燬
              廣播接收者onReceive()方法執行超過6秒就會ANR異常, 所以不要在主執行緒中做耗時的操作

              如果在onReceive()方法中開新執行緒操作, 不會ANR, 但是由於生命週期結束, 很容易被殺死


一.無序廣播和廣播接收者:

【定義無序廣播】

1.建立廣播意圖物件

2.傳送無序廣播

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    
    public void normal(View view){
    	Intent intent = new Intent("com.xxc.action.TEST");//建立廣播的意圖物件,指定廣播的動作
    	//sendBroadcast(intent,"android.permission.INTERNET");//傳送無序廣播,第二個參數列示接收廣播者必須擁有此許可權,否則接收不到
    	sendBroadcast(intent,"com.xxc.permission.MYPERMISSION");//傳送無序廣播,第二個引數也可以是自定義許可權
    	/*
    	 * 在發廣播應用的清單檔案中配置自定義許可權
    	 * <permission android:name="com.xxc.permission.MYPERMISSION"></permission>
    	 * 其他應用就可以使用此許可權
    	 * 
    	 * 同理:在接收方也可以定義傳送方必須擁有某許可權,接收方才接收
    	 * <receiver android:name=".YourReceiver" android:permission="android.permission.INTERNET">
    	 */
    }
}

清單檔案

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xxc.sender"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <!-- 在傳送方自定義一個許可權 -->
    <permission android:name="com.xxc.permission.MYPERMISSION"></permission>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

定義廣播接收者

1.繼承BroadcastReceiver類

2.在清單檔案中配置廣播接收者

public class MyReceiver extends BroadcastReceiver {

	public void onReceive(Context context, Intent intent) {
		System.out.println("MyReceiver收到廣播");
	}

}
廣播接收者的清單檔案

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xxc.myreceiver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
	<uses-permission android:name="com.xxc.permission.MYPERMISSION"/>
    
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        
        <receiver android:name=".MyReceiver"><!-- 廣播接收者類 android:permission=""可以指定擁有某許可權的傳送方,此接收方才接收 -->
		<intent-filter><!-- 意圖過濾器 -->
		    <action android:name="com.xxc.action.TEST"/><!-- 配置接收廣播的哪種動作 和建立廣播意圖時指定的動作一樣  -->
		</intent-filter>            
        </receiver>
    </application>

</manifest>



【定義有序廣播】

public class MainActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    
    public void ordered(View view){
		//第二個參數列示接收廣播者必須擁有此許可權,否則接收不到    不需要則設定為null
    	//sendOrderedBroadcast(new Intent("com.xxc.action.TEST"), null);
    	/**
    	 * 引數一:廣播動作
    	 * 引數二:許可權
    	 * 引數三:定義一個廣播接收者,作為最後執行的接收者,無需在清單檔案中註冊  並且無論前面的廣播接收者是否進行中斷操作,此廣播接收者都能接收到
    	 * 第四個引數:指定一個handle,這個handle在哪個執行緒中建立,第三個引數定義的接收者的onReceive方法就在哪個執行緒中執行
    	 */
    	Bundle bundle = new Bundle();
    	bundle.putString("name", "張三");
    	bundle.putInt("age",10);
    	sendOrderedBroadcast(new Intent("com.xxc.action.TEST"), null, new FinalReceiver(), new Handler(), 100, "xxc", bundle);
    }
}

廣播接收者

public class MyReceiver extends BroadcastReceiver {

	public void onReceive(Context context, Intent intent) {
		System.out.println("MyReceiver收到廣播");
		//獲取結果資料
		System.out.println("ResultCode "+getResultCode());
		System.out.println("ResultData "+getResultData());
		/*
		 * getResultExtras(true)
		 * true:如果sendOrderedBroadcast(new Intent("com.xxc.action.TEST"), null, null, null, 100, "xxc", bundle);
		 * 		有序廣播的最後個引數為null,getResultExtras(true)獲取的並不是null,而是一個空的map
		 * false:如果sendOrderedBroadcast(new Intent("com.xxc.action.TEST"), null, null, null, 100, "xxc", bundle);
		 * 		有序廣播的最後個引數為null,getResultExtras(false)獲取的就是null
		 */
		System.out.println("ResultExtras "+getResultExtras(true).getString("name")+", "+getResultExtras(true).getInt("age"));
		
		/*
		 * 修改結果資料,在後面執行的廣播接收者接收到的就是修改後的結果資料了
		 */
		
		Bundle bundle = new Bundle();
		bundle.putString("name", "pkq");
		bundle.putInt("age", 99);
		
		setResultCode(000);
		setResultData("ddd");
		setResultExtras(bundle);
		
		//setResult(000, "ddd", bundle); //這句話和上面3句一樣
	}
}





相關文章