廣播BroadcastReceiver(2)
阿新 • • 發佈:2017-06-18
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()進行傳遞。處理程序接收到該廣播後運行呼叫。
在AndroidMainfest.xml中加入權限跟receiver:
對呼入的電話進行攔截:
攔截呼入電話的實現原理:
當存在呼入電話時,系統發出例如以下廣播:
android.intent.action.PHONE_STATE
TeleohyManager是電話管理器,為其配置PhoneStateListener就可以監聽相關狀態(響鈴、通話、空暇),且
該監聽器的會調方法中可獲取來電號碼;
調用ITelephony接口定義的boolean endCall()方法就可以掛斷電話。通過TelephonyManager的getTelephony()
註意包名要使用這裏邊的包名,
發送有序廣播的方法有:
public void sendOrderedBroadcast(Intent intent,String receiverPermission)
在接收有序廣播時,能夠自己為接收者指定優先級:
靜態註冊廣播接收者時,在AndroidMainfest.xml文件裏為<receiver>的<intent-filter>節點配置
android:priority屬性;
動態註冊廣播接收者時。調用IntentFilter對象的setPriority()方法;
優先級屬性值越大,則優先級越高;
優先級屬性同樣時,動態註冊的廣播接收者優先級高於靜態註冊的廣播接收者。
同為靜態/動態註冊的廣播接收者。且優先級同樣時,越早註冊的優先級越高。
同為靜態註冊的廣播接收者。且優先級同樣,但歸屬於不同的應用程序時,
按系統載入應用程序的先後順序確定優先級(通常表現為按應用程序的包名排序);
始終接收廣播的方法:
某些應用程序可能須要始終接收特定的廣播。比如手機管理類軟件,則須要始終接收主叫、
來電、短信等廣播,為了正常接收到這些廣播。且讓自己的應用程序處於高優先級,一般會:
接收到開機廣播後,啟動一個Service在後臺執行;
在後臺執行的Service中,動態的廣播接收者,接收業務所需的廣播。
有序廣播的傳遞
中止有序廣播
在廣播接收者中,調用abortBroadcast()則能夠中止有序廣播的繼續傳遞。
即優先級更低的BroadcastReceiver將不會收到該廣播;
須要註意的是:使用該方法僅能用於接收有序廣播,假設接收普通廣播時調用
該方法則會導致程序異常。
在廣播接收者們之間傳遞數據:
比如: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)