Android初級教程反射+AIDL+內容觀察者監控黑名單號碼程式碼模板
阿新 • • 發佈:2019-02-14
對於想要攔截一些莫名的陌生號碼,就需要電話攔截功能與刪除其電話記錄功能。攔截的主要業務邏輯,分別是在一個服務裡面進行:1、註冊電話監聽;2、取消註冊電話監聽(當然註冊於取消是在服務裡面建立一個廣播接收者)。刪除電話日誌的功能,是靠內容觀察者和內容提供者。
下面給出實現電話監聽,取消註冊監聽,內容觀察者監聽電話資料庫狀態的主要程式碼。對於以後開發此類產品,不需要去檢視系統原始碼,複製貼上這段程式碼就行了。下面給出程式碼:
一、註冊電話監聽與內容觀察者監控電話資料庫狀態:
因為是在服務裡面,因此,註冊寫在onCreate方法裡面
因為用到AIDL因此,要把在相應應用中加入兩個檔案:截圖:<span style="font-size:12px;">@Override public void onCreate() { // 註冊電話監聽 // 通過電話管理類TelephoneManager tm = (TelephoneManager</span><span style="font-size:12px;">) getSystemService(TELEPHONY_SERVICE); // 監聽電話的狀態 listener = new PhoneStateListener() { /* * (non-Javadoc) 該方法用來監聽電話的狀態 * * @see android.telephony.PhoneStateListener#onCallStateChanged(int, * java.lang.String) */ @Override public void onCallStateChanged(int state, final String incomingNumber) { // TODO Auto-generated method stub // state 電話的狀態 incomingNumber 打進來的號碼 switch (state) { case TelephonyManager.CALL_STATE_IDLE:// 結束通話的狀態,空閒的狀態 System.out.println("CALL_STATE_IDLE"); break; case TelephonyManager.CALL_STATE_RINGING://響鈴狀態 System.out.println("CALL_STATE_RINGING"); //判斷是否是黑名單號碼 //獲取電話的模式 int mode = dao.getMode(incomingNumber); //如果是攔截號碼 if ((mode & BlackTable.TEL) != 0) { //電話攔截 System.out.println("結束通話電話"); //結束通話電話之前先註冊內容觀察者,新生成的日誌之後(資料庫發生改變) getContentResolver().registerContentObserver(Uri.parse("content://call_log/calls"), true, new ContentObserver(new Handler()) { @Override public void onChange(boolean selfChange) { //電話日誌變化 觸發此方法呼叫 deleteCalllog(incomingNumber);//刪除電話日誌 super.onChange(selfChange); } }); endCall(); } break; case TelephonyManager.CALL_STATE_OFFHOOK:// 通話的狀態 System.out.println("CALL_STATE_OFFHOOK"); break; default: break; } super.onCallStateChanged(state, incomingNumber); } }; // 註冊電話的監聽 tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE); super.onCreate(); } /** * 刪除電話日誌 * @param incomingNumber * 要刪除日誌的號碼 */ protected void deleteCalllog(String incomingNumber) { //只能內容提供者來刪除電話日誌 Uri uri = Uri.parse("content://call_log/calls"); //刪除指定號碼(黑名單號碼)日誌 getContentResolver().delete(uri, "number=?", new String[]{incomingNumber}); } /** * 結束通話電話:反射+AIDL */ protected void endCall() { //tm.endCall(); 1.5版本後,把該方法閹割掉了 //想用該功能,實現方法 //ServiceManager.getService(); //反射呼叫 //1.class try { Class clazz = Class.forName("android.os.ServiceManager"); //2. method Method method = clazz.getDeclaredMethod("getService", String.class); //3.obj 不需要 因為是靜態方法 //4. 呼叫 IBinder binder = (IBinder) method.invoke(null, Context.TELEPHONY_SERVICE); //5.aidl ITelephony iTelephony = ITelephony.Stub.asInterface(binder); iTelephony.endCall();//結束通話電話 } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } }</span>
若用到了相應的功能,直接複製核心程式碼就行了