2015年6月3日 星期三

[轉]GSM-Phone-Call-Connection

1.通話狀態
State {
     IDLE,//
待機,沒有連接
     ACTIVE,//
通話
     HOLDING,//
掛斷通話
     DIALING,//
響鈴
     ALERTING,//
提醒
     INCOMING,//
來電
     WAITING,//
等待接通
     DISCONNECTED,//
連接斷開後
     DISCONNECTING;//
連接斷開工程中
}

2.通話失敗的原因
CallFailCause {
    // Unassigned/Unobtainable number
未分配的號碼
    static final int UNOBTAINABLE_NUMBER = 1;
    static final int NORMAL_CLEARING     = 16;
    // Busy Tone
對方正在通話
    static final int USER_BUSY           = 17;
    // No Tone
    static final int NUMBER_CHANGED      = 22;
    static final int STATUS_ENQUIRY      = 30;
    static final int NORMAL_UNSPECIFIED  = 31;
    // Congestion Tone
    static final int NO_CIRCUIT_AVAIL    = 34;
    static final int TEMPORARY_FAILURE   = 41;
    static final int SWITCHING_CONGESTION    = 42;
    static final int CHANNEL_NOT_AVAIL   = 44;
    static final int QOS_NOT_AVAIL       = 49;
    static final int BEARER_NOT_AVAIL    = 58;
    // others
    static final int ACM_LIMIT_EXCEEDED = 68;
    static final int CALL_BARRED        = 240;
    static final int FDN_BLOCKED        = 241;
    static final int ERROR_UNSPECIFIED = 0xffff;
    static final int IMSI_UNKNOWN_IN_VLR = 242;
    static final int IMEI_NOT_ACCEPTED = 243;
}

3.連接取消的原因
DisconnectCause {
        NOT_DISCONNECTED,/* has not yet disconnected
連接失敗*/
        INCOMING_MISSED,/* an incoming call that was missed and never answered
錯過了來電*/
        NORMAL,/* normal; remote
對方掛斷電話*/
        LOCAL,/* normal; local hangup
自己掛斷電話*/
        BUSY,/* outgoing call to busy line
撥打的號碼正在通話*/
        CONGESTION,/* outgoing call to congested network
網路擁擠*/
        MMI,/*not presently used; dial()returns null
撥號的號碼未被使用*/
        INVALID_NUMBER,/* invalid dial string
無效的號碼串*/
        LOST_SIGNAL,
        LIMIT_EXCEEDED,/* eg GSM ACM limit exceeded
超出限額的GSM ACMACM(Association for Computing Machinery )中文:美國電腦協會是一個世界性的電腦從業員專業組織*/
        INCOMING_REJECTED,/* an incoming call that was rejected
來電被拒絕*/
        POWER_OFF,/* radio is turned off explicitly
無線網路被關閉*/
        OUT_OF_SERVICE,/* out of service
服務區外*/
        ICC_ERROR,/* No ICC, ICC locked, or other ICC error */
        CALL_BARRED,/* call was blocked by call barrring
呼叫限制攔截*/
        FDN_BLOCKED,/* call was blocked by fixed dial number
固定撥號攔截*/
        CS_RESTRICTED,/* call was blocked by restricted all voice access
拒絕語音接入攔截*/
        CS_RESTRICTED_NORMAL,/* call was blocked by restricted normal voice access
拒絕通話攔截*/
        CS_RESTRICTED_EMERGENCY,/* call was blocked by restricted emergency voice access */
        UNOBTAINABLE_NUMBER,/* Unassigned number (3GPP TS 24.008 table 10.5.123)
未分配的號碼*/
        IMSI_UNKNOWN_IN_VLR,/* IMSI is not known at the VLR VLR
不能識別IMSI。國際移動用戶識別碼(IMSIInternational Mobile Subscriber Identification Number)是區別移動使用者的標誌,儲存在SIM卡中,可用於區別移動使用者的有效資訊。其總長度不超過15位,同樣使用09的數字。其中MCC是移動用戶所屬國家代號,占3位元數字,中國的MCC規定為460MNC是移動網號碼,最多由兩位元數位組成,用於識別移動用戶所歸屬的移動通信網;MSIN是移動用戶識別碼,用以識別某一移動通信網中的移動用戶。VLR (Visitor Location Register):拜訪位置寄存器。是一個資料庫,是存儲所管轄區域中MS(統稱拜訪客戶)的來話、去話呼叫所需檢索的資訊以及使用者簽約業務和附加業務的資訊,例如客戶的號碼,所處位置區域的識別,向客戶提供的服務等參數。*/
        IMEI_NOT_ACCEPTED,/* network does not accept emergency call establishment using an IMEI
網路不接受使用緊急呼叫建立一個IMEIIMEI(International Mobile Equipment Identity)是國際移動設備身份碼的縮寫,國際移動裝備辨識碼,是由15位元數位組成的"電子串號",它與每台手機一一對應,而且該碼是全世界唯一的。每一隻手機在組裝完成後都將被賦予一個全球唯一的一組號碼,這個號碼從生產到交付使用都將被製造生產的廠商所記錄。*/
        CDMA_LOCKED_UNTIL_POWER_CYCLE,/* MS is locked until next power cycle
直到下一個電話週期,MS被關閉。MSMobile station 的縮寫,移動台*/
        CDMA_DROP,
        CDMA_INTERCEPT,/* INTERCEPT order received, MS state idle entered
接到攔截命令,MS進入閒置狀態*/
        CDMA_REORDER,/* MS has been redirected, call is cancelled
呼叫被取消 */
        CDMA_SO_REJECT,/* service option rejection
拒絕服務選項*/
        CDMA_RETRY_ORDER,/* requeseted service is rejected, retry delay is set
請求被拒絕,設置延時重試*/
        CDMA_ACCESS_FAILURE,
        CDMA_PREEMPTED,
        CDMA_NOT_EMERGENCY,/* not an emergency call
不是緊急號碼*/
        CDMA_ACCESS_BLOCKED,/* Access Blocked by CDMA network
CDMA網路攔截*/
        ERROR_UNSPECIFIED
    }

4.電話號碼字串的狀態
PostDialState {
    NOT_STARTED,/* The post dial string playback hasn't been started, or this call is not yet connected,  or this is an incoming call
號碼字元未被發送出去,或者此呼叫尚未連接,或者這只是一個來電*/
    STARTED,/* The post dial string playback has begun
號碼字元發送啟動*/
        WAIT,/* The post dial string playback is waiting for a call to proceedAfterWaitChar()
號碼字元等待調用proceedAfterWaitChar函數,如果postDialStatePostDialState.WAIT時,設置postDialStatePostDialState.STARTED,並且調用函數processNextPostDialChar開始另一個電話號碼的字串發送*/
    WILD,/* The post dial string playback is waiting for a call to proceedAfterWildChar()
號碼字元等待調用proceedAfterWildChar函數,如果postDialStatePostDialState.WILD時,設置postDialStatePostDialState.STARTED,並且如果已經發出去的字串的最後一個字元不在“0-9*#”中,則調用函數processNextPostDialChar開始另一個電話號碼的字串發送*/
    COMPLETE,/* The post dial string playback is complete
所有號碼字元都完成發送*/
    CANCELLED,/* The post dial string playback was cancelled with cancelPostDial()
號碼字元取消發送*/
    PAUSE/* The post dial string playback is pausing for a call to processNextPostDialChar
號碼字元為調用processNextPostDialChar函數而暫停發送*/
    }

5.GSMCall
一個通話可以有多個連接,其中還包含了一些偽連接,最多能有5個連接。
當所有連接都斷開後,通話狀態斷開。

當本地掛斷電話後,會設置連接取消的原因為本地掛斷。

1)撥號
註冊一個廣播接收機“android.intent.action.NEW_OUTGOING_CALL”
但要求使用許可android.permission.PROCESS_OUTGOING_CALLS。你可以通過“BroadcastReceiver.onReceive();String strPhoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);”撥出電話號碼;


2)來電
使用TelephonyManagerPhoneStateListener來管理。

6.GSMConnection
1)
獲取連接創建的時間,連接的時間,斷開連接的時間;通話的時間,通話被保持的時間。
2)
得到連接斷開的原因。
3)
通話掛斷與連接取消之間的關係:
DisconnectCause disconnectCauseFromCode(int causeCode) {
        switch (causeCode) {
            case CallFailCause.USER_BUSY:
                return DisconnectCause.BUSY;
            case CallFailCause.NO_CIRCUIT_AVAIL:
            case CallFailCause.TEMPORARY_FAILURE:
            case CallFailCause.SWITCHING_CONGESTION:
            case CallFailCause.CHANNEL_NOT_AVAIL:
            case CallFailCause.QOS_NOT_AVAIL:
            case CallFailCause.BEARER_NOT_AVAIL:
                return DisconnectCause.CONGESTION;
            case CallFailCause.ACM_LIMIT_EXCEEDED:
                return DisconnectCause.LIMIT_EXCEEDED;
            case CallFailCause.CALL_BARRED:
                return DisconnectCause.CALL_BARRED;
            case CallFailCause.FDN_BLOCKED:
                return DisconnectCause.FDN_BLOCKED;
            case CallFailCause.UNOBTAINABLE_NUMBER:
                return DisconnectCause.UNOBTAINABLE_NUMBER;
            /*Display the following call fail cause only when Adapt feature is enabled.
只有在適應功能已啟用才顯示下面的調用失敗。*/
            case CallFailCause.IMSI_UNKNOWN_IN_VLR:
                if (SystemProperties.getBoolean("persist.cust.tel.adapt", false)) {
                    return DisconnectCause.IMSI_UNKNOWN_IN_VLR;
                }
            case CallFailCause.IMEI_NOT_ACCEPTED:
                if (SystemProperties.getBoolean("persist.cust.tel.adapt", false)) {
                    return DisconnectCause.IMEI_NOT_ACCEPTED;
                }
            case CallFailCause.ERROR_UNSPECIFIED:
            case CallFailCause.NORMAL_CLEARING:
            default:
                GSMPhone phone = owner.phone;
                int serviceState = phone.getServiceState().getState();
                if (serviceState == ServiceState.STATE_POWER_OFF) {
                    return DisconnectCause.POWER_OFF;
                } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE
                        || serviceState == ServiceState.STATE_EMERGENCY_ONLY ) {
                    return DisconnectCause.OUT_OF_SERVICE;
                } else if (phone.getIccCard().getState() != SimCard.State.READY) {
                    return DisconnectCause.ICC_ERROR;
                } else if (causeCode == CallFailCause.ERROR_UNSPECIFIED) {
                    if (phone.mSST.rs.isCsRestricted()) {
                        return DisconnectCause.CS_RESTRICTED;
                    } else if (phone.mSST.rs.isCsEmergencyRestricted()) {
                        return DisconnectCause.CS_RESTRICTED_EMERGENCY;
                    } else if (phone.mSST.rs.isCsNormalRestricted()) {
                        return DisconnectCause.CS_RESTRICTED_NORMAL;
                    } else {
                        return DisconnectCause.ERROR_UNSPECIFIED;
                    }
                } else if (causeCode == CallFailCause.NORMAL_CLEARING) {
                    return DisconnectCause.NORMAL;
                } else {
                /*If nothing else matches, report unknown call drop reason to app, not NORMAL call end.
沒有匹配的通話失敗原因則報告未知的應用程式錯誤使得通話非正常結束*/
                    return DisconnectCause.ERROR_UNSPECIFIED;
                }
        }
    }
4)
獲取通話的狀態。
5)
對號碼各個字元發送狀態做處理。
6)processPostDialChar
為號碼字元執行適當的行動,但不通知應用程式。如果字元是無效的,返回false,並且被忽略。

7.GsmServiceStateTracker
與漫遊設置有關,與網路時間同步有關,與運營商有關...

8.GsmCallTracker
android的通話管理層,建立了ConnectionList來管理現行的通話連接,並向上層提供電話調用介面。
GSMCallTracker中維護著通話列表:connections。順序記錄了正連接上的通話,這些通話包括:ACTIVEDIALINGALERTINGHOLDINGINCOMINGWAITING等狀態的連接。GSMCallTracker將這些連接分為了三類別進行管理:
  [1]RingingCall: INCOMING ,WAITING
  [2]ForegourndCall: ACTIVE, DIALING ,ALERTING
  [3]BackgroundCall: HOLDING

[轉]Android核心分析文章連結

CSDN上看到了maxLeng有關Android的系列文章(2010)
28.Android GDISurface&Canvas