Android電話攔截實現以及TelephonyManager監聽的取消

jopen 8年前發布 | 39K 次閱讀 Android開發 移動開發

本篇博客目的:實現電話的攔截

會遇到的問題:android studio下AIDL的使用,TelephonyManager.Listen()的監聽取消。

首先,電話狀態監聽需要涉及到系統服務TelephonyManager,我們需要獲取到他的實例

mTelephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);

之后我們就可以向他添加狀態改變的監聽,需要重寫監聽器PhoneStateListener

他的state值有如下幾種

TelephonyManager.CALL_STATE_IDLE:  空閑狀態
TelephonyManager.CALL_STATE_RINGING:  響鈴狀態
TelephonyManager.CALL_STATE_OFFHOOK:  掛掉電話

class MyPhoneListener extends PhoneStateListener{

            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                if(state==TelephonyManager.CALL_STATE_RINGING){
                    endCall();
                    super.onCallStateChanged(state,incomingNumber);
                }
            }
        }
這里我給他加了個模式來設置監聽與取消。

我們需要用一個FLAG : PhoneStateListener.LISTEN_NONE來取消監聽。如果新加監聽器,會同時監聽

private void setTelephonyListener(int mode){
        if(mode==INTERRUPTED){
            mTelephonyManager.listen(mMyPhoneListener,PhoneStateListener.LISTEN_CALL_STATE);
        }else{
            mTelephonyManager.listen(mMyPhoneListener,PhoneStateListener.LISTEN_NONE);
        }
    }
好了,以上就是狀態監聽的步驟。

那么如何實現電話的攔截呢?由于安卓隱藏了PHONE類的API,所以我們需要用AIDL將它的方法反射出來。

1,新建AIDL文件,ITelephony.aidl。注意包名為com.android.internal.telephony,不可更改,此時需要rebuild project才能正常使用。

內容如下:

package com.android.internal.telephony;  

 /**  

  * Interface used to interact with the phone.  Mostly this is used by the  

  * TelephonyManager class.  A few places are still using this directly.  

  * Please clean them up if possible and use TelephonyManager instead.  

  * {@hide}  

  */ 



interface ITelephony {      

 /**      

  * End call or go to the Home screen

  * @return whether it hung up     

  */    

 boolean endCall();      



   /**      

    * Answer the currently-ringing call.      

    *      

    * If there's already a current active call, that call will be      

    * automatically put on hold.  If both lines are currently in use, the     

    * current active call will be ended.      

    *    

    * TODO: provide a flag to let the caller specify what policy to use     

    * if both lines are in use.  (The current behavior is hardwired to     

    * "answer incoming, end ongoing", which is how the CALL button      

    * is specced to behave.)      

    *      

    * TODO: this should be a oneway call (especially since it's called     

    * directly from the key queue thread).      

    */     

    void answerRingingCall(); 



    /**

     * Allow mobile data connections.

     */

    boolean enableDataConnectivity();



    /**

     * Disallow mobile data connections.

     */

    boolean disableDataConnectivity();



    /**

     * Report whether data connectivity is possible.

     */

    boolean isDataConnectivityPossible();

}
之后來反射出來endcall方法,當來電的時候 即可對電話進行攔截

private void endCall()
    {
        Class<TelephonyManager> c = TelephonyManager.class;
        try
        {
            Method getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[]) null);
            getITelephonyMethod.setAccessible(true);
            ITelephony iTelephony = null;
            iTelephony = (ITelephony) getITelephonyMethod.invoke(mTelephonyManager, (Object[]) null);
            iTelephony.endCall();

            Log.i("wing", "iTelePhony endcall");
        }
        catch (Exception e)
        {

            Log.i("wing", "iTelePhony endcall failed"+e.getMessage()    );
        }
    }
以上就是我的經驗和總結,歡迎大家討論。



來自: http://blog.csdn.net/wingichoy/article/details/48555809

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!