1. 程式人生 > >Android應用開發之PhoneStateListener 的使用

Android應用開發之PhoneStateListener 的使用

這兩天在做翻轉靜音的功能,需要用到PhoneStateListener,以前只是知道有這麼個東西,沒有具體用過

包含此類的包是:android.telephony.PhoneStateListener

由於StatusBar中用到了PhoneStateListener中較多的內容,索性研究了一下StatusBarPolicy.java

76 /** 77  * This class contains all of the policy about which icons are installed in the status 78  * bar at boot time.  In reality, it should go into the android.policy package, but
79
  * putting it here is the first step from extracting it. 80  */

services/java/com/android/server/status/StatusBarPolicy.java

1、首先需要通過TelephonyManager來註冊要監聽的狀態,狀態定義在類PhoneStateListener中,如下所示

1)   LISTEN_CALL_FORWARDING_INDICATOR      Listen for changes to the call-forwarding indicator.

2)   LISTEN_CALL_STATE

                                      Listen for changes to the device call state.

3)   LISTEN_CELL_LOCATION                               Listen for changes to the device's cell location. Note that this

                                                                            will result in frequent callbacks to the listener.

If you need regular location updates but want more control over the update interval or location precision, you can set up a listener through the location manager instead.

4)   LISTEN_DATA_ACTIVITY                                 Listen for changes to the direction of data traffic on the data

                                                                            connection (cellular).

Requires Permission: READ_PHONE_STATE Example: The status bar uses this to display the appropriate data-traffic icon.

5)   LISTEN_DATA_CONNECTION_STATE              Listen for changes to the data connection state (cellular).

6)   LISTEN_MESSAGE_WAITING_INDICATOR       Listen for changes to the message-waiting indicator.

Example: The status bar uses this to determine when to display the voicemail icon.

7)   LISTEN_NONE                                                Stop listening for updates.

8)   LISTEN_SERVICE_STATE                                Listen for changes to the network service state (cellular).

10) LISTEN_SIGNAL_STRENGTHS                         Listen for changes to the network signal strengths (cellular).

Example: The status bar uses this to control the signal-strength icon

StatusBarPolicy中的註冊程式碼如下所示:

438         // register for phone state notifications. 439         ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE)) 440                 .listen(mPhoneStateListener, 441                           PhoneStateListener.LISTEN_SERVICE_STATE 442                         | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS 443                         | PhoneStateListener.LISTEN_CALL_STATE 444                         | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE 445                         | PhoneStateListener.LISTEN_DATA_ACTIVITY);

當不需要再繼續監聽上述狀態時,通常需要登出掉

// unregister for phone state notifications.

((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))         .listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); 2、定義mPhoneStateListener,以內部匿名類的方式定義 885     private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 886         @Override 887         public void onSignalStrengthsChanged(SignalStrength signalStrength) { 888             mSignalStrength = signalStrength; 889             updateSignalStrength(); 890         } 891 892         @Override 893         public void onServiceStateChanged(ServiceState state) { 894             mServiceState = state; 895             updateSignalStrength(); 896             updateCdmaRoamingIcon(state); 897             updateDataIcon(); 898         } 899 900         @Override 901         public void onCallStateChanged(int state, String incomingNumber) { 902             updateCallState(state); 903             // In cdma, if a voice call is made, RSSI should switch to 1x. 904             if (isCdma()) { 905                 updateSignalStrength(); 906             } 907         } 908 909         @Override 910         public void onDataConnectionStateChanged(int state, int networkType) { 911             mDataState = state; 912             updateDataNetType(networkType); 913             updateDataIcon(); 914         } 915 916         @Override 917         public void onDataActivity(int direction) { 918             mDataActivity = direction; 919             updateDataIcon(); 920         } 921     };

1) public void onSignalStrengthsChanged(SignalStrength signalStrength)

// Callback invoked when network signal strengths changes.

通過函式updateSignalStrength更新StatusBar上的訊號圖示


2) public void onServiceStateChanged(ServiceState state)

// Callback invoked when device service state changes.

通過ServiceState返回當前服務狀態,有如下四種狀態

STATE_EMERGENCY_ONLY       The phone is registered and locked. Only emergency numbers are allowed.

STATE_IN_SERVICE                  Normal operation condition, the phone is registered with an operator either in

                                                home network or in roaming.

STATE_OUT_OF_SERVICE        Phone is not registered with any operator, the phone can be currently searching a

                                                new operator to register to, or not searching to registration at all, or registration

                                                is denied, or radio signal is not available.

STATE_POWER_OFF                 Radio of telephony is explicitly powered off.

同時還可以獲取到以下資訊

Service state: IN_SERVICE, OUT_OF_SERVICE, EMERGENCY_ONLY, POWER_OFFRoaming indicatorOperator name, short name and numeric idNetwork selection mode

StatusBarPolicy根據上面四種狀態封裝瞭如下函式,用來判斷當前是否有服務

960     private boolean hasService() { 961         if (mServiceState != null) { 962             switch (mServiceState.getState()) { 963                 case ServiceState.STATE_OUT_OF_SERVICE: 964                 case ServiceState.STATE_POWER_OFF: 965                     return false; 966                 default: 967                     return true; 968             } 969         } else { 970             return false; 971         } 972     } 3) public void onCallStateChanged(int state, String incomingNumber) // Callback invoked when device call state changes 用來更新來電圖示,其中state有三種狀態,如下

public static final int CALL_STATE_IDLE

Device call state: No activity.

Constant Value: 0 (0x00000000)

public static final int CALL_STATE_OFFHOOK

Device call state: Off-hook. At least one call exists that is dialing, active, or on hold, and no calls are ringing or waiting.

Constant Value: 2 (0x00000002)

public static final int CALL_STATE_RINGING

Device call state: Ringing. A new call arrived and is ringing or waiting. In the latter case, another call is already active.

Constant Value: 1 (0x00000001) 4) public void onDataConnectionStateChanged(int state, int networkType) // Callback invoked when connection state changes 用來控制是否顯示有行動網路資料互動,其中state有四種狀態,如下

public static final int DATA_CONNECTED

Data connection state: Connected. IP traffic should be available.

Constant Value: 2 (0x00000002)

public static final int DATA_CONNECTING

Data connection state: Currently setting up a data connection.

Constant Value: 1 (0x00000001)

public static final int DATA_DISCONNECTED

Data connection state: Disconnected. IP traffic not available.

Constant Value: 0 (0x00000000)

public static final int DATA_SUSPENDED

Data connection state: Suspended. The connection is up, but IP traffic is temporarily unavailable. For example, in a 2G network, data activity may be suspended when a voice call arrives.

Constant Value: 3 (0x00000003) 5) public void onDataActivity(int direction) // Callback invoked when data activity state changes. 用來控制顯示資料傳輸的圖示 918             mDataActivity = direction; 1115                     switch (mDataActivity) { 1116                         case TelephonyManager.DATA_ACTIVITY_IN: 1117                             iconId = mDataIconList[1]; 1118                             break; 1119                         case TelephonyManager.DATA_ACTIVITY_OUT: 1120                             iconId = mDataIconList[2]; 1121                             break; 1122                         case TelephonyManager.DATA_ACTIVITY_INOUT: 1123                             iconId = mDataIconList[3]; 1124                             break; 1125                         default: 1126                             iconId = mDataIconList[0]; 1127                             break;