Android開源代碼解讀の使用TelephonyManager獲取移動網絡信息

本文介紹使用TelephonyManager來獲取手機SIM卡的狀態和移動網絡的相關信息,主要使用瞭

TelephonyManager.listen函數,這個函數源碼如下:
 
 
[java]
 public void listen(PhoneStateListener listener, int events) {
     String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
     try {
         Boolean notifyNow = (getITelephony() != null);
         mRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
     } catch (RemoteException ex) {
         // system process dead 
     } catch (NullPointerException ex) {
         // system process dead 
     }
 }
 public void listen(PhoneStateListener listener, int events) {
     String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
     try {
         Boolean notifyNow = (getITelephony() != null);
         mRegistry.listen(pkgForDebug, listener.callback, events, notifyNow);
     } catch (RemoteException ex) {
         // system process dead
     } catch (NullPointerException ex) {
         // system process dead
     }
 }
 
具體的實現不是本文的重點,這裡隻來瞭解函數的兩個參數:
 
1)PhoneStateListener listener
 
一般根據events的值,來實現相應的回調函數接口,在回調函數裡面執行我們的處理,這些接口包括:
 
[java]
 public void onServiceStateChanged(ServiceState serviceState)
 public void onMessageWaitingIndicatorChanged(boolean mwi) 
 public void onCallForwardingIndicatorChanged(boolean cfi)
 public void onCellLocationChanged(CellLocation location) 
 public void onCallStateChanged(int state, String incomingNumber) 
 public void onDataConnectionStateChanged(int state) 
 public void onDataConnectionStateChanged(int state, int networkType) 
 public void onDataActivity(int direction) 
 public void onSignalStrengthsChanged(SignalStrength signalStrength) 
 public void onServiceStateChanged(ServiceState serviceState)
 public void onMessageWaitingIndicatorChanged(boolean mwi)
 public void onCallForwardingIndicatorChanged(boolean cfi)
 public void onCellLocationChanged(CellLocation location)
 public void onCallStateChanged(int state, String incomingNumber)
 public void onDataConnectionStateChanged(int state)
 public void onDataConnectionStateChanged(int state, int networkType)
 public void onDataActivity(int direction)
 public void onSignalStrengthsChanged(SignalStrength signalStrength)
 2)int events
 
Events取值如下:
 
[java]
 public static final int LISTEN_NONE = 0; //停止監聽 
 public static final int LISTEN_SERVICE_STATE = 0x00000001;
 public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 0x00000004;
 public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008;
 public static final int LISTEN_CELL_LOCATION = 0x00000010;
 public static final int LISTEN_CALL_STATE = 0x00000020;
 public static final int LISTEN_DATA_CONNECTION_STATE = 0x00000040;
 public static final int LISTEN_DATA_ACTIVITY = 0x00000080;
 public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100;
 public static final int LISTEN_NONE = 0; //停止監聽
 public static final int LISTEN_SERVICE_STATE = 0x00000001;
 public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 0x00000004;
 public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008;
 public static final int LISTEN_CELL_LOCATION = 0x00000010;
 public static final int LISTEN_CALL_STATE = 0x00000020;
 public static final int LISTEN_DATA_CONNECTION_STATE = 0x00000040;
 public static final int LISTEN_DATA_ACTIVITY = 0x00000080;
 public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100;
 下面就是使用瞭上面知識點的代碼瞭,先看佈局文件network_detector.xml:
 
[html]
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     >
     <TextView android:id="@+id/phone_type"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content" />
     <TextView android:id="@+id/network_name"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content" />
     <TextView android:id="@+id/sim_state"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content" />
     <TextView android:id="@+id/network_type"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content" />
 </LinearLayout>
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     >
     <TextView android:id="@+id/phone_type"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content" />
     <TextView android:id="@+id/network_name"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content" />
     <TextView android:id="@+id/sim_state"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content" />
     <TextView android:id="@+id/network_type"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content" />
 </LinearLayout>
 
完整Java代碼如下(對APIDemos的解析,有刪改):
 
 
[java]
 package hust.iprai.asce1885;
 
 import android.app.Activity;
 import android.os.Bundle;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.widget.TextView;
 
 public class NetworkDetector extends Activity {
     
     //SIM卡狀態常量 
     private static final String SIM_ABSENT = "Absent"; //手機內無SIM卡 
     private static final String SIM_READY = "Ready"; //SIM卡已準備好 
     private static final String SIM_PIN_REQUIRED = "PIN required"; //需要SIM卡的PIN解鎖 
     private static final String SIM_PUK_REQUIRED = "PUK required"; //需要SIM卡的PUK解鎖  
     private static final String SIM_NETWORK_LOCKED = "Network locked"; //需要Network PIN解鎖 
     private static final String SIM_UNKNOWN = "Unknown"; //狀態未知 
     
     //網絡類型常量 
     private static final String NETWORK_CDMA = "CDMA: Either IS95A or IS95B (2G)";
     private static final String NETWORK_EDGE = "EDGE (2.75G)";
     private static final String NETWORK_GPRS = "GPRS (2.5G)";
     private static final String NETWORK_UMTS = "UMTS (3G)";
     private static final String NETWORK_EVDO_0 = "EVDO revision 0 (3G)";
     private static final String NETWORK_EVDO_A = "EVDO revision A (3G – Transitional)";
     private static final String NETWORK_EVDO_B = "EVDO revision B (3G – Transitional)";
     private static final String NETWORK_1X_RTT = "1xRTT  (2G – Transitional)";
     private static final String NETWORK_HSDPA = "HSDPA (3G – Transitional)";
     private static final String NETWORK_HSUPA = "HSUPA (3G – Transitional)";
     private static final String NETWORK_HSPA = "HSPA (3G – Transitional)";
     private static final String NETWORK_IDEN = "iDen (2G)";
     private static final String NETWORK_UNKOWN = "Unknown";
     
     //手機制式類型常量 
     private static final String PHONE_CDMA = "CDMA";
     private static final String PHONE_GSM = "GSM";
     private static final String PHONE_NONE = "No radio";
         
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.network_detector);
         
         //獲取telephony系統服務,用於取得SIM卡和網絡相關信息 
         final TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
         
         //更新界面上相關網絡信息 
         updateViews(tm);
         
         //由於SIM卡狀態和網絡信息隨時都可能發生變化,因此需要註冊PhoneStateListener 
         //來實時更新界面顯示的信息。這裡監聽兩個事件:LISTEN_SERVICE_STATE和LISTEN_DATA_CONNECTION_STATE 
         //它們分別對應回調函數onServiceStateChanged和onDataConnectionStateChanged 
         tm.listen(new PhoneStateListener() {
 
             @Override
             public void onDataConnectionStateChanged(int state, int networkType) {
                 //數據連接狀態改變可能導致網絡類型的改變 
                 updateViews(tm);
             }
 
             @Override
             public void onServiceStateChanged(ServiceState serviceState) {
                 updateViews(tm);
             }
             
         }, PhoneStateListener.LISTEN_SERVICE_STATE 
                 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
     }
     
     @Override
     protected void onResume() {
         super.onResume();
         final TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
         updateViews(tm);
     }
     
     /**
      * 更新SIM卡狀態和網絡信息
      * @param tm
      */
     private final void updateViews(TelephonyManager tm) {
         TextView view = null;
         
         view = (TextView) findViewById(R.id.sim_state);
         view.setText("SIM State : " + mapSimStateToName(tm.getSimState()));
         
         view = (TextView) findViewById(R.id.network_type);
         view.setText("Network Type : " + mapNetworkTypeToName(tm.getNetworkType()));
         
         view = (TextView) findViewById(R.id.network_name);
         view.setText("Network Operator : " + tm.getNetworkOperatorName());
         
         view = (TextView) findViewById(R.id.phone_type);
         view.setText("Phone Type : " + mapDeviceTypeToName(tm.getPhoneType()));
         
     }
 
     /**
      * 將手機制式值以字符串形式返回
      * @param phoneType
      * @return
      */
     private String mapDeviceTypeToName(int phoneType) {
         switch (phoneType) {
         case TelephonyManager.PHONE_TYPE_CDMA:
             return PHONE_CDMA;
         case TelephonyManager.PHONE_TYPE_GSM:
             return PHONE_GSM;
         case TelephonyManager.PHONE_TYPE_NONE:
             return PHONE_NONE;
         default:
             //不應該走到這個分支 
             return null;
         }
     }
 
     /**
      * 將網絡類型值以字符串形式返回
      * @param networkType
      * @return
      */
     private String mapNetworkTypeToName(int networkType) {
         switch (networkType) {
         case TelephonyManager.NETWORK_TYPE_CDMA:
             return NETWORK_CDMA;
         case TelephonyManager.NETWORK_TYPE_EDGE:
             return NETWORK_EDGE;
         case TelephonyManager.NETWORK_TYPE_GPRS:
             return NETWORK_GPRS;
         case TelephonyManager.NETWORK_TYPE_UMTS:
             return NETWORK_UMTS;
         case TelephonyManager.NETWORK_TYPE_EVDO_0:
             return NETWORK_EVDO_0;
         case TelephonyManager.NETWORK_TYPE_EVDO_A:
             return NETWORK_EVDO_A;
         case TelephonyManager.NETWORK_TYPE_EVDO_B:
             return NETWORK_EVDO_B;
         case TelephonyManager.NETWORK_TYPE_1xRTT:
             return NETWORK_1X_RTT;
         case TelephonyManager.NETWORK_TYPE_HSDPA:
             return NETWORK_HSDPA;
         case TelephonyManager.NETWORK_TYPE_HSPA:
             return NETWORK_HSPA;
         case TelephonyManager.NETWORK_TYPE_HSUPA:
             return NETWORK_HSUPA;
         case TelephonyManager.NETWORK_TYPE_IDEN:
             return NETWORK_IDEN;
         case TelephonyManager.NETWORK_TYPE_UNKNOWN:
         default:
             return NETWORK_UNKOWN;
         }
     }
 
     /**
      * 將SIM卡狀態值以字符串形式返回
      * @param simState
      * @return
      */
     private static String mapSimStateToName(int simState) {
         switch (simState) {
         case TelephonyManager.SIM_STATE_ABSENT:
             return SIM_ABSENT;
         case TelephonyManager.SIM_STATE_READY:
             return SIM_READY;
         case TelephonyManager.SIM_STATE_PIN_REQUIRED:
             return SIM_PIN_REQUIRED;
         case TelephonyManager.SIM_STATE_PUK_REQUIRED:
             return SIM_PUK_REQUIRED;
         case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
             return SIM_NETWORK_LOCKED;
         case TelephonyManager.SIM_STATE_UNKNOWN:
             return SIM_UNKNOWN;
         default:
             //不應該走到這個分支 
             return null;
         }
     }
     
 }
 package hust.iprai.asce1885;
 
import android.app.Activity;
 import android.os.Bundle;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.widget.TextView;
 
public class NetworkDetector extends Activity {
 
  //SIM卡狀態常量
  private static final String SIM_ABSENT = "Absent"; //手機內無SIM卡
  private static final String SIM_READY = "Ready"; //SIM卡已準備好
  private static final String SIM_PIN_REQUIRED = "PIN required"; //需要SIM卡的PIN解鎖
  private static final String SIM_PUK_REQUIRED = "PUK required"; //需要SIM卡的PUK解鎖
  private static final String SIM_NETWORK_LOCKED = "Network locked"; //需要Network PIN解鎖
  private static final String SIM_UNKNOWN = "Unknown"; //狀態未知
   
     //網絡類型常量
  private static final String NETWORK_CDMA = "CDMA: Either IS95A or IS95B (2G)";
  private static final String NETWORK_EDGE = "EDGE (2.75G)";
  private static final String NETWORK_GPRS = "GPRS (2.5G)";
  private static final String NETWORK_UMTS = "UMTS (3G)";
     private static final String NETWORK_EVDO_0 = "EVDO revision 0 (3G)";
     private static final String NETWORK_EVDO_A = "EVDO revision A (3G – Transitional)";
     private static final String NETWORK_EVDO_B = "EVDO revision B (3G – Transitional)";
     private static final String NETWORK_1X_RTT = "1xRTT  (2G – Transitional)";
     private static final String NETWORK_HSDPA = "HSDPA (3G – Transitional)";
     private static final String NETWORK_HSUPA = "HSUPA (3G – Transitional)";
     private static final String NETWORK_HSPA = "HSPA (3G – Transitional)";
     private static final String NETWORK_IDEN = "iDen (2G)";
     private static final String NETWORK_UNKOWN = "Unknown";
   
     //手機制式類型常量
     private static final String PHONE_CDMA = "CDMA";
     private static final String PHONE_GSM = "GSM";
     private static final String PHONE_NONE = "No radio";
     
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.network_detector);
       
         //獲取telephony系統服務,用於取得SIM卡和網絡相關信息
         final TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
       
         //更新界面上相關網絡信息
         updateViews(tm);
       
         //由於SIM卡狀態和網絡信息隨時都可能發生變化,因此需要註冊PhoneStateListener
         //來實時更新界面顯示的信息。這裡監聽兩個事件:LISTEN_SERVICE_STATE和LISTEN_DATA_CONNECTION_STATE
         //它們分別對應回調函數onServiceStateChanged和onDataConnectionStateChanged
         tm.listen(new PhoneStateListener() {
 
   @Override
    public void onDataConnectionStateChanged(int state, int networkType) {
     //數據連接狀態改變可能導致網絡類型的改變
     updateViews(tm);
    }
 
   @Override
    public void onServiceStateChanged(ServiceState serviceState) {
     updateViews(tm);
    }
         
         }, PhoneStateListener.LISTEN_SERVICE_STATE
           | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
     }
   
  @Override
  protected void onResume() {
   super.onResume();
   final TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
   updateViews(tm);
  }
   
     /**
      * 更新SIM卡狀態和網絡信息
      * @param tm
      */
     private final void updateViews(TelephonyManager tm) {
      TextView view = null;
     
      view = (TextView) findViewById(R.id.sim_state);
      view.setText("SIM State : " + mapSimStateToName(tm.getSimState()));
     
      view = (TextView) findViewById(R.id.network_type);
      view.setText("Network Type : " + mapNetworkTypeToName(tm.getNetworkType()));
     
      view = (TextView) findViewById(R.id.network_name);
      view.setText("Network Operator : " + tm.getNetworkOperatorName());
     
      view = (TextView) findViewById(R.id.phone_type);
      view.setText("Phone Type : " + mapDeviceTypeToName(tm.getPhoneType()));
     
     }
 
    /**
      * 將手機制式值以字符串形式返回
      * @param phoneType
      * @return
      */
  private String mapDeviceTypeToName(int phoneType) {
         switch (phoneType) {
         case TelephonyManager.PHONE_TYPE_CDMA:
             return PHONE_CDMA;
         case TelephonyManager.PHONE_TYPE_GSM:
             return PHONE_GSM;
         case TelephonyManager.PHONE_TYPE_NONE:
             return PHONE_NONE;
         default:
          //不應該走到這個分支
             return null;
         }
  }
 
 /**
   * 將網絡類型值以字符串形式返回
   * @param networkType
   * @return
   */
  private String mapNetworkTypeToName(int networkType) {
         switch (networkType) {
         case TelephonyManager.NETWORK_TYPE_CDMA:
             return NETWORK_CDMA;
         case TelephonyManager.NETWORK_TYPE_EDGE:
             return NETWORK_EDGE;
         case TelephonyManager.NETWORK_TYPE_GPRS:
             return NETWORK_GPRS;
         case TelephonyManager.NETWORK_TYPE_UMTS:
             return NETWORK_UMTS;
         case TelephonyManager.NETWORK_TYPE_EVDO_0:
             return NETWORK_EVDO_0;
         case TelephonyManager.NETWORK_TYPE_EVDO_A:
             return NETWORK_EVDO_A;
         case TelephonyManager.NETWORK_TYPE_EVDO_B:
             return NETWORK_EVDO_B;
         case TelephonyManager.NETWORK_TYPE_1xRTT:
             return NETWORK_1X_RTT;
         case TelephonyManager.NETWORK_TYPE_HSDPA:
             return NETWORK_HSDPA;
         case TelephonyManager.NETWORK_TYPE_HSPA:
             return NETWORK_HSPA;
         case TelephonyManager.NETWORK_TYPE_HSUPA:
             return NETWORK_HSUPA;
         case TelephonyManager.NETWORK_TYPE_IDEN:
             return NETWORK_IDEN;
         case TelephonyManager.NETWORK_TYPE_UNKNOWN:
         default:
             return NETWORK_UNKOWN;
         }
  }
 
 /**
   * 將SIM卡狀態值以字符串形式返回
   * @param simState
   * @return
   */
  private static String mapSimStateToName(int simState) {
         switch (simState) {
         case TelephonyManager.SIM_STATE_ABSENT:
             return SIM_ABSENT;
         case TelephonyManager.SIM_STATE_READY:
             return SIM_READY;
         case TelephonyManager.SIM_STATE_PIN_REQUIRED:
             return SIM_PIN_REQUIRED;
         case TelephonyManager.SIM_STATE_PUK_REQUIRED:
             return SIM_PUK_REQUIRED;
         case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
             return SIM_NETWORK_LOCKED;
         case TelephonyManager.SIM_STATE_UNKNOWN:
             return SIM_UNKNOWN;
         default:
             //不應該走到這個分支
             return null;
         }
  }
 

 }

程序執行結果如圖所示:

 

摘自 ASCE1885

發佈留言