1. 程式人生 > >廣播BroadcastReceiver(2)

廣播BroadcastReceiver(2)

clas dsm 先後 roi amp abort red 不能 ole

有序廣播的優先級:
發送有序廣播的方法有:
public void sendOrderedBroadcast(Intent intent,String receiverPermission)


在接收有序廣播時,能夠自己為接收者指定優先級:
靜態註冊廣播接收者時,在AndroidMainfest.xml文件裏為<receiver>的<intent-filter>節點配置
android:priority屬性;
動態註冊廣播接收者時。調用IntentFilter對象的setPriority()方法;
有序廣播的優先級:
優先級屬性值越大,則優先級越高;
優先級屬性同樣時,動態註冊的廣播接收者優先級高於靜態註冊的廣播接收者。
同為靜態/動態註冊的廣播接收者。且優先級同樣時,越早註冊的優先級越高。
同為靜態註冊的廣播接收者。且優先級同樣,但歸屬於不同的應用程序時,
按系統載入應用程序的先後順序確定優先級(通常表現為按應用程序的包名排序);
始終接收廣播的方法:
某些應用程序可能須要始終接收特定的廣播。比如手機管理類軟件,則須要始終接收主叫、
來電、短信等廣播,為了正常接收到這些廣播。且讓自己的應用程序處於高優先級,一般會:
使用一個靜態註冊的廣播接收者。接收開機廣播;
接收到開機廣播後,啟動一個Service在後臺執行;
在後臺執行的Service中,動態的廣播接收者,接收業務所需的廣播。

有序廣播的傳遞
中止有序廣播
在廣播接收者中,調用abortBroadcast()則能夠中止有序廣播的繼續傳遞。
即優先級更低的BroadcastReceiver將不會收到該廣播;
須要註意的是:使用該方法僅能用於接收有序廣播,假設接收普通廣播時調用
該方法則會導致程序異常。
在廣播接收者們之間傳遞數據:
在有序廣播的傳遞過程中,能夠調用setResultXXX()系列方法設置數據,
比如:setResultData()、setResultExtras()等,並使用getResultXXX()系列方法獲取這些數據。
管理呼出電話
呼出電話的廣播為:
android.intent.action.NEW_OUTGOING_CALL
對呼出電話的管理的原理:
呼出電話是從撥號到呼叫的過程,當呼出電話時,系統會發出呼叫電話的有序廣播,而且將須要呼叫的電話號碼
使用setResultData()進行傳遞。處理程序接收到該廣播後運行呼叫。


處理呼叫的程序接收該廣播的優先級較低,因此,自己定義廣播接收者。

在接收到呼出電話的廣播後,改動setResult()傳遞的電話號碼。就可以實現對呼出電話的管理。

對呼出的電話進行操作的實例:

Activity不用改動。默認狀態就可以。

這裏僅僅給出廣播:

package com.example.chargecall;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class OutReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		// 改動呼出的電話號碼:
		/*能夠對電話號碼進行多種操作。假設想要禁止呼出的電話號碼,能夠直接設置為空值
		 * 
		 * */
		String number = getResultData();
		number = "12345" + number;
		setResultData(number);
		
	}

}

在AndroidMainfest.xml中加入權限跟receiver:

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

<receiver android:name="com.example.chargecall.OutReceiver" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>


對呼入的電話進行攔截:
攔截呼入電話的實現原理:
當存在呼入電話時,系統發出例如以下廣播:
android.intent.action.PHONE_STATE
TeleohyManager是電話管理器,為其配置PhoneStateListener就可以監聽相關狀態(響鈴、通話、空暇),且
該監聽器的會調方法中可獲取來電號碼;
調用ITelephony接口定義的boolean endCall()方法就可以掛斷電話。通過TelephonyManager的getTelephony()

方法就可以獲得ITelephony接口的對象。

對呼入的電話進行操作的實例:

相同的。主界面使用默認的就可以,

給出廣播:

package com.example.interceptcall;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.android.internal.telephony.ITelephony;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;


public class PhoneStateReceiver extends BroadcastReceiver {
	TelephonyManager manager;

	@Override
	public void onReceive(Context context, Intent intent) {
		manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		PhoneStateListener listener = new InnerPhoneStateListener();
		int events = PhoneStateListener.LISTEN_CALL_STATE;
		manager.listen(listener, events);

	}
 
	private ITelephony getITelephony(){
		ITelephony iTelephony = null;
		Method method = null;
		try {
			method = TelephonyManager.class.getDeclaredMethod("getITelephony", (Class[])null);
		    method.setAccessible(true);
		    iTelephony =  (ITelephony) method.invoke(manager, null);
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return iTelephony;
	}
	private class InnerPhoneStateListener extends PhoneStateListener{

		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			// TODO Auto-generated method stub
			switch (state) {
			case TelephonyManager.CALL_STATE_IDLE://空暇狀態
				
				break;
			case TelephonyManager.CALL_STATE_OFFHOOK://通話狀態
				
				break;
			case TelephonyManager.CALL_STATE_RINGING://響鈴狀態
				   if("15539187816".equals(incomingNumber)){//掛斷電話
					   try {
						getITelephony().endCall();
					} catch (RemoteException e) {
						e.printStackTrace();
					}
				   }
				break;

			}
			super.onCallStateChanged(state, incomingNumber);
		}
		
	}
}
因為不能識別ITelephony,還須要自己定義aidl接口,這樣才幹夠,

ITelephony:

package com.android.internal.telephony;

interface ITelephony {
      boolean endCall();
}

註意包名要使用這裏邊的包名,

相同,要把權限加到AndroidMainfest.xml中,還要把寫好的廣播加入到這裏邊。

廣播BroadcastReceiver(2)