Android之TelephonyManager


  在Android平台中,通過TelephonyManager可以訪問與手機通訊相關的信息,比如設備信息、網絡信息及SIM卡信息,同時還可以監聽電話的相關狀態。下面我們通過幾個方面來說明Android平台中如何使用電話技術。

1、獲取TelephonyManager對象

    TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

  2、通過TelephonyManager獲取設備信息

String phoneTypeStr = "未知";
int phoneType = telephonyManager.getPhoneType();
switch (phoneType){
    case TelephonyManager.PHONE_TYPE_CDMA:
        phoneTypeStr="CDMA";
        break;
    case TelephonyManager.PHONE_TYPE_GSM:
        phoneTypeStr="GSM";
        break;
    case TelephonyManager.PHONE_TYPE_SIP:
        phoneTypeStr="SIP";
        break;
    case TelephonyManager.PHONE_TYPE_NONE:
        phoneTypeStr="None";
        break;
}
addTelephoneView("電話類型",phoneTypeStr);
//GSM--IMEI  CDMA--MEID
String deviceId = telephonyManager.getDeviceId();
addTelephoneView("設備編號",deviceId);
//軟件版本編號
String softVersion = telephonyManager.getDeviceSoftwareVersion();
addTelephoneView("軟件版本",softVersion);
//手機號碼(不一定能獲取到)
String phoneNumber = telephonyManager.getLine1Number();
addTelephoneView("手機號碼",phoneNumber);
3、通過TelephonyManager獲取網絡信息 
              
//網絡信息:連接到一個網絡時有效,如果是CDMA則不一定有效
//國家ISO代碼
String networkCountry = telephonyManager.getNetworkCountryIso();
addTelephoneView("國家ISO代碼",networkCountry);
//運營商信息
String networkOperatorId = telephonyManager.getNetworkOperator();
addTelephoneView("運營商編號",networkOperatorId);
String networkOperatorName=telephonyManager.getNetworkOperatorName();
addTelephoneView("運營商名稱",networkOperatorName);
//網絡連接狀態
int  networktype = telephonyManager.getNetworkType();
addTelephoneView("網絡類型",networktype+"");
4、通過TelephonyManager獲取SIM卡信息 
                
//SIM卡的狀態
int simState = telephonyManager.getSimState();
switch (simState){
    case TelephonyManager.SIM_STATE_READY:
        //SIM卡的ISO國家代碼
        String simISO = telephonyManager.getSimCountryIso();
        addTelephoneView("SIM國家ISO",simISO);
        //SIM卡的運營商代碼
        String simOperator = telephonyManager.getSimOperator();
        addTelephoneView("SIM運營商編號",simOperator);
        //SIM的運營商名稱
        String simOperatorName = telephonyManager.getSimOperatorName();
        addTelephoneView("SIM運營商名稱",simOperatorName);
        //SIM的序列號‘
        String number = telephonyManager.getSimSerialNumber();
        addTelephoneView("SIM序列號",number);
        break;
}
  注意獲取信息的時候需要添加如下權限:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

運行結果如下:

5、通過繼承PhoneStateListener,使用TelephonyManager注冊后進行監聽電話狀態。

  PhoneStateListener可以通過重寫方法onCallStateChanged、onDataConnectionStateChanged、onDataActivity等方法對來電狀態、數據連接狀態、數據傳輸狀態進行監聽。 通過TelephonyManager.listen方法進行注冊,該方法有兩個參數,一個參數為PhoneStateListener,第二個參數為監聽標志,決定了監聽哪些狀態。 PhoneStateListener的之類代碼如下:

//定義電話狀態監聽器
private PhoneStateListener listener = new PhoneStateListener(){
    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        super.onCallStateChanged(state, incomingNumber);
        String msg = "未知";
        switch (state){
            case TelephonyManager.CALL_STATE_IDLE:
                msg="電話空閑";
                break;
            case TelephonyManager.CALL_STATE_RINGING:
                msg = incomingNumber+"來電話了,響鈴中……";
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                msg = "電話中……";
                break;
        }
        Toast.makeText(TelephonyActivity.this,msg,Toast.LENGTH_LONG).show();
    }

    @Override
    public void onDataConnectionStateChanged(int state) {
        super.onDataConnectionStateChanged(state);
        String msg = "未知";
        switch (state){
            case TelephonyManager.DATA_CONNECTED:
                msg="數據已連接";
                break;
            case TelephonyManager.DATA_CONNECTING:
                msg = "數據正在連接中……";
                break;
            case TelephonyManager.DATA_DISCONNECTED:
                msg = "數據已關閉!";
                break;
        }
        show.setText(msg);
    }

    @Override
    public void onDataActivity(int direction) {
        super.onDataActivity(direction);
        String msg = "未知";
        switch (direction){
            case TelephonyManager.DATA_ACTIVITY_IN:
                msg = "下載";
                break;
            case TelephonyManager.DATA_ACTIVITY_OUT:
                msg = "上傳";
                break;
            case TelephonyManager.DATA_ACTIVITY_INOUT:
                msg = "下載/上傳";
                break;
            case TelephonyManager.DATA_ACTIVITY_NONE:
                msg = "未知";
                break;
        }
        show.setText(msg);
    }
};

注冊代碼:

telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE
            |PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
            |PhoneStateListener.LISTEN_DATA_ACTIVITY);

注銷代碼:

telephonyManager.listen(listener,PhoneStateListener.LISTEN_NONE);

6、通過BroadcastReceiver接收廣播監聽電話的狀態。

  當撥打電話時系統會發送Intent.ACTION_NEW_OUTGOING_CALL廣播,當電話狀態發生變化的時候,系統會發送TelephonyManager.ACTION_PHONE_STATE_CHANGED廣播,我們通過接收這兩個廣播來監聽電話的相關狀態

  BroadcastReceiver的關鍵代碼如下:

    if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){
        //去電
        String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
    }else if(intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)){
        //來電
        String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
        if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
            //有來電,響鈴中
            //TelephonyManager.EXTRA_STATE_IDLE;
            //TelephonyManager.EXTRA_STATE_OFFHOOK
            String phoneNumber=
                    intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            //比對電話號碼
            if(null !=backNumber &&
                    null != phoneNumber &&
                    backNumber.endsWith(phoneNumber)){
                //掛掉電話
                //AIDL  Android接口定義語言
                //IPC
                ITelephony iTelephony = getITelephony(context);
                try {
                    iTelephony.endCall();

                } catch (RemoteException e) {
                    e.printStackTrace();
                } finally {
                }
            }
        }else if(state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
            //
        }else if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){

        }
    }
}

在清單文件中注冊:

<receiver android:name=".receiver.PhoneStateChanagedReceiver">
    <intent-filter>
        <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
        <action android:name="android.intent.action.PHONE_STATE"/>
    </intent-filter>
</receiver>

注意此處需要如下權限:

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

7、電話攔截,在6的基礎上,完成電話攔截操作,這里需要使用到ITelephony.aidl。

  首先在Android Studio的對應的Module中創建aidl目錄,和java目錄同級,在該目錄下創建com.android.internal.telephony包和android.telephony包,然后拷貝ITelephony.aidl和NeighboringCellInfo.aidl到對應的包下,然后從新構建。通過反射拿到ITelephony對象並調用endCall方法掛斷電話。

  關鍵代碼如下:

 

private static ITelephony getITelephony(Context context){
    ITelephony iTelephony = null;
    TelephonyManager telephonyManager=(TelephonyManager)
            context.getSystemService(Context.TELEPHONY_SERVICE);
    Class<TelephonyManager> c = TelephonyManager.class;
    Method getITelephoneyMethod = null;
    try {
        getITelephoneyMethod = c.getDeclaredMethod("getITelephony",(Class[])null);
        getITelephoneyMethod.setAccessible(true);
        iTelephony = (ITelephony)getITelephoneyMethod.invoke(telephonyManager,(Object[])null);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

    return  iTelephony;
}

 

作者: 傑瑞教育
出處: http://www.cnblogs.com/jerehedu/ 
版權聲明:本文版權歸煙台傑瑞教育科技有限公司和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
技術咨詢:JRedu技術交流
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM