1.通話狀態
State {
IDLE,//待機,沒有連接
ACTIVE,//通話
HOLDING,//掛斷通話
DIALING,//響鈴
ALERTING,//提醒
INCOMING,//來電
WAITING,//等待接通
DISCONNECTED,//連接斷開後
DISCONNECTING;//連接斷開工程中
}
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;
}
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 ACM。ACM(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。國際移動用戶識別碼(IMSI:International Mobile Subscriber Identification Number)是區別移動使用者的標誌,儲存在SIM卡中,可用於區別移動使用者的有效資訊。其總長度不超過15位,同樣使用0~9的數字。其中MCC是移動用戶所屬國家代號,占3位元數字,中國的MCC規定為460;MNC是移動網號碼,最多由兩位元數位組成,用於識別移動用戶所歸屬的移動通信網;MSIN是移動用戶識別碼,用以識別某一移動通信網中的移動用戶。VLR (Visitor Location Register):拜訪位置寄存器。是一個資料庫,是存儲所管轄區域中MS(統稱拜訪客戶)的來話、去話呼叫所需檢索的資訊以及使用者簽約業務和附加業務的資訊,例如客戶的號碼,所處位置區域的識別,向客戶提供的服務等參數。*/
IMEI_NOT_ACCEPTED,/* network does not accept emergency call establishment using an IMEI 網路不接受使用緊急呼叫建立一個IMEI。IMEI(International Mobile Equipment Identity)是國際移動設備身份碼的縮寫,國際移動裝備辨識碼,是由15位元數位組成的"電子串號",它與每台手機一一對應,而且該碼是全世界唯一的。每一隻手機在組裝完成後都將被賦予一個全球唯一的一組號碼,這個號碼從生產到交付使用都將被製造生產的廠商所記錄。*/
CDMA_LOCKED_UNTIL_POWER_CYCLE,/* MS is locked until next power cycle 直到下一個電話週期,MS被關閉。MS:Mobile 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
}
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 ACM。ACM(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。國際移動用戶識別碼(IMSI:International Mobile Subscriber Identification Number)是區別移動使用者的標誌,儲存在SIM卡中,可用於區別移動使用者的有效資訊。其總長度不超過15位,同樣使用0~9的數字。其中MCC是移動用戶所屬國家代號,占3位元數字,中國的MCC規定為460;MNC是移動網號碼,最多由兩位元數位組成,用於識別移動用戶所歸屬的移動通信網;MSIN是移動用戶識別碼,用以識別某一移動通信網中的移動用戶。VLR (Visitor Location Register):拜訪位置寄存器。是一個資料庫,是存儲所管轄區域中MS(統稱拜訪客戶)的來話、去話呼叫所需檢索的資訊以及使用者簽約業務和附加業務的資訊,例如客戶的號碼,所處位置區域的識別,向客戶提供的服務等參數。*/
IMEI_NOT_ACCEPTED,/* network does not accept emergency call establishment using an IMEI 網路不接受使用緊急呼叫建立一個IMEI。IMEI(International Mobile Equipment Identity)是國際移動設備身份碼的縮寫,國際移動裝備辨識碼,是由15位元數位組成的"電子串號",它與每台手機一一對應,而且該碼是全世界唯一的。每一隻手機在組裝完成後都將被賦予一個全球唯一的一組號碼,這個號碼從生產到交付使用都將被製造生產的廠商所記錄。*/
CDMA_LOCKED_UNTIL_POWER_CYCLE,/* MS is locked until next power cycle 直到下一個電話週期,MS被關閉。MS:Mobile 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函數,如果postDialState為PostDialState.WAIT時,設置postDialState為PostDialState.STARTED,並且調用函數processNextPostDialChar開始另一個電話號碼的字串發送*/
WILD,/* The post dial string playback is waiting for a call to proceedAfterWildChar() 號碼字元等待調用proceedAfterWildChar函數,如果postDialState為PostDialState.WILD時,設置postDialState為PostDialState.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函數而暫停發送*/
}
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函數,如果postDialState為PostDialState.WAIT時,設置postDialState為PostDialState.STARTED,並且調用函數processNextPostDialChar開始另一個電話號碼的字串發送*/
WILD,/* The post dial string playback is waiting for a call to proceedAfterWildChar() 號碼字元等待調用proceedAfterWildChar函數,如果postDialState為PostDialState.WILD時,設置postDialState為PostDialState.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個連接。
當所有連接都斷開後,通話狀態斷開。
一個通話可以有多個連接,其中還包含了一些偽連接,最多能有5個連接。
當所有連接都斷開後,通話狀態斷開。
當本地掛斷電話後,會設置連接取消的原因為本地掛斷。
1)撥號
註冊一個廣播接收機“android.intent.action.NEW_OUTGOING_CALL”,
但要求使用許可android.permission.PROCESS_OUTGOING_CALLS。你可以通過“BroadcastReceiver.onReceive();String strPhoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);”撥出電話號碼;
註冊一個廣播接收機“android.intent.action.NEW_OUTGOING_CALL”,
但要求使用許可android.permission.PROCESS_OUTGOING_CALLS。你可以通過“BroadcastReceiver.onReceive();String strPhoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);”撥出電話號碼;
2)來電
使用TelephonyManager和PhoneStateListener來管理。
使用TelephonyManager和PhoneStateListener來管理。
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,並且被忽略。
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。順序記錄了正連接上的通話,這些通話包括:ACTIVE,DIALING,ALERTING,HOLDING,INCOMING,WAITING等狀態的連接。GSMCallTracker將這些連接分為了三類別進行管理:
[1]RingingCall: INCOMING ,WAITING
[2]ForegourndCall: ACTIVE, DIALING ,ALERTING
[3]BackgroundCall: HOLDING
是android的通話管理層,建立了ConnectionList來管理現行的通話連接,並向上層提供電話調用介面。
在GSMCallTracker中維護著通話列表:connections。順序記錄了正連接上的通話,這些通話包括:ACTIVE,DIALING,ALERTING,HOLDING,INCOMING,WAITING等狀態的連接。GSMCallTracker將這些連接分為了三類別進行管理:
[1]RingingCall: INCOMING ,WAITING
[2]ForegourndCall: ACTIVE, DIALING ,ALERTING
[3]BackgroundCall: HOLDING