通话状态监听-Android13
通话状态监听-Android13
- 1、Android Telephony 模块结构
- 2、监听和广播获取通话状态
- 2.1 注册
- 2.2 通话状态通知
- 2.3 通话状态
- 3、通知状态流程
- * 关键日志
frameworks/base/core/java/android/telephony/PhoneStateListener.java
1、Android Telephony 模块结构
Android Telephony 模块结构简析
Android Telephony 模块结构简析
Telecom 框架概览
Dialer.apk:/product/priv-app/Dialer/Dialer.apk、packages/apps/DialerTelecom.apk:/system/priv-app/Telecom/Telecom.apk、packages/service/telecommTeleService.apk:/system/priv-app/TeleService/TeleService.apk、packages/service/telephony
framework.jar:frameworks/base/telecomm、frameworks/base/telephony
telephony-common.jar:frameworks/opt/telephony
vendor.ril-daemon:hardware/ril
2、监听和广播获取通话状态
主要查看
framework.jar代码
2.1 注册
-
- PhoneStateListener注册:最终调用
TelephonyRegistry.java#listenWithEventList添加到ArrayList<Record> mRecords
packages/apps/Dialer/java/com/android/incallui/InCallPresenter.java
- PhoneStateListener注册:最终调用
this.context.getSystemService(TelephonyManager.class).listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
-
- 广播注册:
public static final String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";,权限android.permission.READ_PHONE_STATE
packages/apps/Dialer/java/com/android/dialer/dialpadview/DialpadFragment.java
- 广播注册:
if (callStateReceiver == null) {IntentFilter callStateIntentFilter =new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED);callStateReceiver = new CallStateReceiver();getActivity().registerReceiver(callStateReceiver, callStateIntentFilter);}
/private class CallStateReceiver extends BroadcastReceiver {/*** Receive call state changes so that we can take down the "dialpad chooser" if the phone* becomes idle while the chooser UI is visible.*/@Overridepublic void onReceive(Context context, Intent intent) {String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);if ((TextUtils.equals(state, TelephonyManager.EXTRA_STATE_IDLE)|| TextUtils.equals(state, TelephonyManager.EXTRA_STATE_OFFHOOK))&& isDialpadChooserVisible()) {// Note there's a race condition in the UI here: the// dialpad chooser could conceivably disappear (on its// own) at the exact moment the user was trying to select// one of the choices, which would be confusing. (But at// least that's better than leaving the dialpad chooser// onscreen, but useless...)LogUtil.i("CallStateReceiver.onReceive", "hiding dialpad chooser, state: %s", state);showDialpadChooser(false);}}}
2.2 通话状态通知
frameworks/base/services/core/java/com/android/server/TelephonyRegistry.java
public void notifyCallState(int phoneId, int subId, int state, String incomingNumber) {if (!checkNotifyPermission("notifyCallState()")) {return;}if (VDBG) {log("notifyCallState: subId=" + subId+ " state=" + state + " incomingNumber=" + incomingNumber);}synchronized (mRecords) {if (validatePhoneId(phoneId)) {mCallState[phoneId] = state;mCallIncomingNumber[phoneId] = incomingNumber;for (Record r : mRecords) {if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)&& (r.subId == subId)&& (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {try {// Only the legacy PhoneStateListener receives the phone number.String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId);r.callback.onLegacyCallStateChanged(state, incomingNumberOrEmpty);} catch (RemoteException ex) {mRemoveList.add(r.binder);}}if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)&& (r.subId == subId)&& (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {try {// The phone number is not included in the new call state changed// listener.r.callback.onCallStateChanged(state);} catch (RemoteException ex) {mRemoveList.add(r.binder);}}}}handleRemoveListLocked();}broadcastCallStateChanged(state, incomingNumber, phoneId, subId);}
2.3 通话状态
frameworks/base/telephony/java/android/telephony/TelephonyManager.java
CALL_STATE_IDLE:处于无电话活动,相当于电话挂断,不过要先有CALL_STATE_OFFHOOK判断
CALL_STATE_RINGING:电话响铃
CALL_STATE_OFFHOOK:接听电话
/*** Device call state: No activity.*/public static final int CALL_STATE_IDLE = 0;/*** Device call state: Ringing. A new call arrived and is* ringing or waiting. In the latter case, another call is* already active.*/public static final int CALL_STATE_RINGING = 1;/*** Device call state: Off-hook. At least one call exists* that is dialing, active, or on hold, and no calls are ringing* or waiting.*/public static final int CALL_STATE_OFFHOOK = 2;
3、通知状态流程
frameworks/base/core/java/android/telephony/TelephonyRegistryManager.java
frameworks/base/services/core/java/com/android/server/TelephonyRegistry.java

public void notifyCallStateForAllSubs(int state, String phoneNumber) {if (!checkNotifyPermission("notifyCallState()")) {return;}if (VDBG) {log("notifyCallStateForAllSubs: state=" + state + " phoneNumber=" + phoneNumber);}synchronized (mRecords) {for (Record r : mRecords) {if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)&& (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {try {// Ensure the listener has read call log permission; if they do not return// an empty phone number.// This is ONLY for legacy onCallStateChanged in PhoneStateListener.String phoneNumberOrEmpty = r.canReadCallLog() ? phoneNumber : "";r.callback.onLegacyCallStateChanged(state, phoneNumberOrEmpty);} catch (RemoteException ex) {mRemoveList.add(r.binder);}}if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)&& (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {try {// The new callback does NOT provide the phone number.r.callback.onCallStateChanged(state);} catch (RemoteException ex) {mRemoveList.add(r.binder);}}}handleRemoveListLocked();}// Called only by Telecomm to communicate call state across different phone accounts. So// there is no need to add a valid subId or slotId.broadcastCallStateChanged(state, phoneNumber,SubscriptionManager.INVALID_SIM_SLOT_INDEX,SubscriptionManager.INVALID_SUBSCRIPTION_ID);}public void notifyCallState(int phoneId, int subId, int state, String incomingNumber) {if (!checkNotifyPermission("notifyCallState()")) {return;}if (VDBG) {log("notifyCallState: subId=" + subId+ " state=" + state + " incomingNumber=" + incomingNumber);}synchronized (mRecords) {if (validatePhoneId(phoneId)) {mCallState[phoneId] = state;mCallIncomingNumber[phoneId] = incomingNumber;for (Record r : mRecords) {if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)&& (r.subId == subId)&& (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {try {// Only the legacy PhoneStateListener receives the phone number.String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId);r.callback.onLegacyCallStateChanged(state, incomingNumberOrEmpty);} catch (RemoteException ex) {mRemoveList.add(r.binder);}}if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)&& (r.subId == subId)&& (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {try {// The phone number is not included in the new call state changed// listener.r.callback.onCallStateChanged(state);} catch (RemoteException ex) {mRemoveList.add(r.binder);}}}}handleRemoveListLocked();}broadcastCallStateChanged(state, incomingNumber, phoneId, subId);}
* 关键日志
ril.*GET_CURRENT_CALLS|TelephonyManager:|PhoneStateListener:|TelecomFramework: TelephonyConnectionService:|TelephonyMetrics:|Telecom : CallsManager|Telecom : PhoneStateBroadcaster: Broadcasted state change:|Telephony: onStateChanged|android.intent.action.PHONE_STATE|KeyguardUpdateMonitor:|notification_enqueue.*com.google.android.dialer|Dialer :.*CallState
12-17 21:06:43.523 957 957 D RILJ : [1066]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:43.524 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:43.529 957 1274 D RILJ : [1066]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:43.546 957 957 E TelephonyMetrics: writePhoneState: Call session is missing
12-17 21:06:43.676 957 957 I TelecomFramework: TelephonyConnectionService: createConnection, callManagerAccount: ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, callId: TC@4_1, request: ConnectionRequest xxxxxxxxxxxxxx Bundle[android.telecom.extra.INCOMING_CALL_ADDRESS=***, android.telecom.extra.CALL_CREATED_TIME_MILLIS=68867006, android.telecom.extra.CALL_TELECOM_ROUTING_START_TIME_MILLIS=68867038, ] isAdhocConf: N, isIncoming: true, isUnknown: false, isLegacyHandover: false, isHandover: false, addSelfManaged: true: (SBC.oSC)->CS.crCo->H.CS.crCo->H.CS.crCo.pICR(cap/cast)@E-Ajo
12-17 21:06:43.683 957 957 V Telephony: onStateChanged, state: RINGING
12-17 21:06:43.718 957 957 I TelecomFramework: TelephonyConnectionService: notifyCreateConnectionComplete TC@4_1: (...->CSW.hCCC)->CS.crCoC->H.CS.crCoC(cap/cast)@E-E-E-Ajo
12-17 21:06:43.780 596 10440 I Telecom : CallsManager: onCallFilteringComplete: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC->ICFG.sF->ICFG.sF->ICFG.sF->CILH.sL->CILH.oQC->BCF.gBS->BCF.gBS->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF(cap/cast)@E-E-Ajo
12-17 21:06:43.781 596 10440 I Telecom : CallsManager: setCallState NEW -> RINGING, call: [Call id=TC@4, state=NEW, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, handle=tel:********12, vidst=A, childs(0), has_parent(false), cap=[ sup_hld mut !v2a spd_aud], prop=[]], voip=false: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC->ICFG.sF->ICFG.sF->ICFG.sF->CILH.sL->CILH.oQC->BCF.gBS->BCF.gBS->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF(cap/cast)@E-E-Ajo
12-17 21:06:43.786 596 10440 I Telecom : CallsManager: onCallFilteringComplete: allow call.: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC->ICFG.sF->ICFG.sF->ICFG.sF->CILH.sL->CILH.oQC->BCF.gBS->BCF.gBS->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF(cap/cast)@E-E-Ajo
12-17 21:06:43.786 596 10440 I Telecom : CallsManager: addCall([Call id=TC@4, state=RINGING, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, handle=tel:********12, vidst=A, childs(0), has_parent(false), cap=[ sup_hld mut !v2a spd_aud], prop=[]], voip=false): (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC->ICFG.sF->ICFG.sF->ICFG.sF->CILH.sL->CILH.oQC->BCF.gBS->BCF.gBS->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF(cap/cast)@E-E-Ajo
12-17 21:06:43.797 957 957 I TelecomFramework: TelephonyConnectionService: onCallFilteringCompleted(TC@4_1, CallFilteringCompletionInfo{mIsBlocked=false, mIsInContacts=false, mCallResponse=null, mCallScreeningPackageName='null'}): (...->CSW.hCCC->ICFG.sF->ICFG.sF->ICFG.sF->CILH.sL->CILH.oQC->BCF.gBS->BCF.gBS->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF)->CS.oCFC->H.CS.oCFC(cap/cast/cast)@E-E-E-Ajo
12-17 21:06:43.879 596 10440 I Telecom : PhoneStateBroadcaster: Broadcasted state change: 1: (...->CS.crCo->H.CS.crCo->H.CS.crCo.pICR)->CSW.hCCC->ICFG.sF->ICFG.sF->ICFG.sF->CILH.sL->CILH.oQC->BCF.gBS->BCF.gBS->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF(cap/cast)@E-E-Ajo
12-17 21:06:43.898 957 957 I TelecomFramework: TelephonyConnectionService: onTrackedByNonUiService TC@4_1 true: (ICSBC.oSC)->CS.tBNUS->H.CS.tBNUS(cad/cast)@E-Ajw
12-17 21:06:44.038 957 957 D RILJ : [1068]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:44.039 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:44.049 957 1274 D RILJ : [1068]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:44.113 957 957 I TelecomFramework: TelephonyConnectionService: onTrackedByNonUiService TC@4_1 true: (ICSBC.oSC)->CS.tBNUS->H.CS.tBNUS(cab/cast)@E-Aj8
12-17 21:06:44.132 957 957 I TelecomFramework: TelephonyConnectionService: onAudioStateChanged TC@4_1 [AudioState isMuted: false, route: SPEAKER, supportedRouteMask: SPEAKER, activeBluetoothDevice: [null], supportedBluetoothDevices: []]: (...->CSW.hCCC->ICFG.sF->ICFG.sF->ICFG.sF->CILH.sL->CILH.oQC->BCF.gBS->BCF.gBS->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->CARSM.pM_UPDATE_SYSTEM_AUDIO_ROUTE)->CS.cASC->H.CS.cASC(cap/cast/cast)@E-E-E-Ajo
12-17 21:06:44.326 957 957 I TelecomFramework: TelephonyConnectionService: onAudioStateChanged TC@4_1 [AudioState isMuted: false, route: SPEAKER, supportedRouteMask: SPEAKER, activeBluetoothDevice: [null], supportedBluetoothDevices: []]: (...->CSW.hCCC->ICFG.sF->ICFG.sF->ICFG.sF->CILH.sL->CILH.oQC->BCF.gBS->BCF.gBS->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->ICFG.sF->CAMSM.pM_2002->CARSM.pM_SWITCH_FOCUS)->CS.cASC->H.CS.cASC(cap/cast/cast)@E-E-E-Ajo
12-17 21:06:44.551 957 957 D RILJ : [1070]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:44.551 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:44.562 957 1273 D RILJ : [1070]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:45.075 957 957 D RILJ : [1072]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:45.076 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:45.081 957 1273 D RILJ : [1072]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:45.594 957 957 D RILJ : [1074]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:45.594 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:45.597 957 1273 D RILJ : [1074]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:46.109 957 957 D RILJ : [1076]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:46.109 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:46.115 957 1273 D RILJ : [1076]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:46.626 957 957 D RILJ : [1078]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:46.626 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:46.629 957 1273 D RILJ : [1078]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:47.137 957 957 D RILJ : [1080]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:47.138 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:47.142 957 1273 D RILJ : [1080]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:47.651 957 957 D RILJ : [1082]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:47.651 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:47.655 957 1273 D RILJ : [1082]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:48.164 957 957 D RILJ : [1084]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:48.164 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:48.174 957 1273 D RILJ : [1084]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:48.682 596 9194 I Telecom : CallsManager: holdActiveCallForNewCall, newCall: [Call id=TC@4, state=RINGING, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, handle=tel:********12, vidst=A, childs(0), has_parent(false), cap=[ sup_hld mut !v2a spd_aud], prop=[]], voip=false, activeCall: null: ICA.aC(cad)@Ak4
12-17 21:06:48.706 957 957 D RILJ : [1086]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:48.707 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:48.716 957 1273 D RILJ : [1086]< GET_CURRENT_CALLS {[id=4,INCOMING,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:48.745 957 957 I TelecomFramework: TelephonyConnectionService: answer TC@4_1: (ICA.aC->CSFM.rF)->CS.an->H.CS.an(cad/cast)@E-Ak4
12-17 21:06:48.760 596 1157 I Telecom : CallsManager: setCallState RINGING -> ANSWERED, call: [Call id=TC@4, state=RINGING, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, handle=tel:********12, vidst=A, childs(0), has_parent(false), cap=[ sup_hld mut !v2a spd_aud], prop=[]], voip=false: ICA.aC->CSFM.rF(cad)@Ak4
12-17 21:06:48.910 957 957 D RILJ : [1089]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:48.912 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:48.957 957 1273 D RILJ : [1089]< GET_CURRENT_CALLS {[id=4,ACTIVE,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:49.078 957 957 V Telephony: onStateChanged, state: ACTIVE
12-17 21:06:49.161 596 1050 I Telecom : CallsManager: markCallAsActive, isSelfManaged: false: CSW.sA(cap)@AlQ
12-17 21:06:49.163 596 1050 I Telecom : CallsManager: setCallState ANSWERED -> ACTIVE, call: [Call id=TC@4, state=ANSWERED, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, handle=tel:********12, vidst=A, childs(0), has_parent(false), cap=[ sup_hld mut !v2a spd_aud], prop=[]], voip=false: CSW.sA(cap)@AlQ
12-17 21:06:49.190 596 1050 I Telecom : PhoneStateBroadcaster: Broadcasted state change: 2: CSW.sA(cap)@AlQ
12-17 21:06:49.309 957 957 D RILJ : [1091]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:49.309 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:49.331 957 1273 D RILJ : [1091]< GET_CURRENT_CALLS {[id=4,ACTIVE,toa=129,norm,mt,0,voc,noevp,,cli=1,,1,audioQuality=0] } [PHONE0]
12-17 21:06:55.815 957 957 D RILJ : [1093]> GET_CURRENT_CALLS [PHONE0]
12-17 21:06:55.816 526 526 D RIL : onRequest: GET_CURRENT_CALLS, sState: 10
12-17 21:06:55.823 957 1274 D RILJ : [1093]< GET_CURRENT_CALLS {} [PHONE0]
12-17 21:06:55.857 957 957 V Telephony: onStateChanged, state: DISCONNECTED
12-17 21:06:55.864 596 9194 I Telecom : CallsManager: setCallState ACTIVE -> DISCONNECTED, call: [Call id=TC@4, state=ACTIVE, tpac=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, cmgr=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, 1, UserHandle{0}, handle=tel:********12, vidst=A, childs(0), has_parent(false), cap=[ hld sup_hld mut !v2a spd_aud], prop=[]], voip=false: CSW.sDc(cap)@Aow
12-17 21:06:55.928 596 9194 I Telecom : PhoneStateBroadcaster: Broadcasted state change: 0: CSW.sDc(cap)@Aow
12-17 21:06:56.018 596 9720 I Telecom : CallsManager: markCallAsRemoved; callid=TC@4, immediate.: CSW.rC(cap)@ApU
12-17 21:06:56.056 596 596 I Telecom : CallsManager: handleConnectionServiceDeath: service [ConnectionServiceWrapper componentName=ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}] died: CSW.rC->CM.pR(cap)@ApU
相关文章:
通话状态监听-Android13
通话状态监听-Android13 1、Android Telephony 模块结构2、监听和广播获取通话状态2.1 注册2.2 通话状态通知2.3 通话状态 3、通知状态流程* 关键日志 frameworks/base/core/java/android/telephony/PhoneStateListener.java 1、Android Telephony 模块结构 Android Telephony…...
无懈可击的防泄密之旅:迅软DSE在民营银行的成功实践
客户简要介绍 某股份有限公司主体是中部地区的民营银行,由其母公司联合9家知名民营企业共同发起设立。正式开业于2016年,紧紧围绕目标产业生态圈和消费金融,着力打造产业银行、便捷银行、数字银行、财富管理银行为一体的BEST银行,…...
【送书活动】智能汽车、自动驾驶、车联网的发展趋势和关键技术
文章目录 前言01 《智能汽车》推荐语 02 《SoC底层软件低功耗系统设计与实现》推荐语 03 《SoC设计指南》推荐语 05 《智能汽车网络安全权威指南(上册)》推荐语 06 《智能汽车网络安全权威指南(下册)》推荐语 后记赠书活动 前言 …...
不同版本QT使用qmake时创建QML项目的区别
不同版本QT使用qmake时创建QML项目的区别 文章目录 不同版本QT使用qmake时创建QML项目的区别一、QT5新建QML项目1.1 目录结构1.2 .pro 文件内容1.3 main.cpp1.4 main.qml 二、QT6新建QML项目2.1 目录结构2.2 .pro文件内容2.3 main.cpp2.4 main.qml 三、两个版本使用资源文件的区…...
【PHP入门】1.1-PHP初步语法
-PHP语法初步- PHP是一种运行在服务器端的脚本语言,可以嵌入到HTML中。 1.1.1PHP代码标记 在PHP历史发展中,可以使用多种标记来区分PHP脚本 ASP标记: <% php代码 %>短标记: <? Php代码 ?>,以上两种…...
如何在jenkins容器中安装python+httprunner+pytest+git+allure(一)
背景: API接口自动化使用python语言实现,利用httprunner框架编写自动化用例场景(执行的时候还是依赖pytest),使用jenkins自动构建git上的源代码,并产生allure报告可视化展示API执行结果。 步骤 1.进入jenkins容器 注意使用roo…...
Android终端模拟器Termux上使用Ubuntu
Termux 上安装各种 Linux 系统是通过 proot-distro 工具来实现的,所以先安装一下 proot-distro 工具。 ~ $ pkg install proot-distro 查看Termux支持安装那些Linux ~ $ proot-distro listSupported distributions:* Alpine LinuxAlias: alpineInstalled: noComme…...
【神器】wakatime代码时间追踪工具
文章目录 wakatime简介支持的IDE安装步骤API文档插件费用写在最后 wakatime简介 wakatime就是一个IDE插件,一个代码时间追踪工具。可自动获取码编码时长和度量指标,以产生很多的coding图形报表。这些指标图形可以为开发者统计coding信息,比如…...
UML统一建模语言
一、建模语言的背景: 通俗地阐述就是:客户一开始不知道要什么,开发通过客户的阐述进行理解和分析,这个过程中间可能会产生一些误解。为了避免此类事件,所以需要建模。类似于要建造一栋楼,建筑设计师根据住…...
Linux命令行控制小米电源开关
飞灵科技产品 flyelf-tech.com,flyelf.taobao.com 最近有需求通过命令控制局域网内小米电源开关,以便于写脚本对产品进行反复上电的启动测试。参考了这篇文章:https://blog.csdn.net/2301_77209380/article/details/129797846 获取小米设备的…...
docker nginx 部署静态网站
1、dockerfile FROM nginx AS baseWORKDIR /appEXPOSE 80COPY . /app2、dockercompose.yaml version: 3 services:adminservice:container_name: adminwebbuild:context: ./dockerfile: Dockerfileports:- "5000:80"labels:description: adminwebrestart: always3、…...
uniapp之屏幕右侧出现滚动条去掉、隐藏、删除【好用!】
目录 问题解决大佬地址最后 问题 解决 在最外层view上加上class“content”;输入以下样式。注意:两个都必须存在在生效。 .content {/* 跟屏幕高度一样高,不管view中有没有内容,都撑开屏幕高的高度 */height: 100vh; overflow: auto; } .content::-webkit-scrollb…...
Linux 系统开机启动流程
可能没有完全理解,后期整理完Linux的内容,应该理解会深入一些,试着用更简洁的方式和图形来记录,以及一些概念的完善 2023-12-14 一、开机流程 BIOS MBR/GPT 加载 BIOS 的硬件信息与进行自检,并依据设定取得第一个可…...
vue2源码解析---watch和computed
监听属性watch 监听属性介绍 我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数wach 可以用于异步任务 监听属性的初始化 watch和computed都先走initSate判断传入选项 export function initState(vm) {const opts vm.$options; // 获取所有的选项if (opts.…...
【云原生】华为云踩坑日志(更新于2023.12.10)
1、华为云建议我们把sfs容量型升级到turbo版本,但是CCE产品storageclass sfs-turbo共享存储卷不支持动态绑定,官网文档可以实现动态创建子目录,建议大家直接选择这个,不要踩坑了 2、CCE 涉及到的产品,有的需要查看产品…...
计算机网络:自顶向下第八版学习指南笔记和课后实验--网络层(控制平面)
网络层:控制平面 记录一些学习计算机网络:自顶向下的学习笔记和心得 Github地址,欢迎star ⭐️⭐️⭐️⭐️⭐️ 控制平面作为一种网络范围的逻辑,不仅控制沿着从源主机到目的主机的端到端路径间的路由器如何转发数据报,而且控制…...
MFC 窗口创建过程与消息处理
目录 钩子简介 代码编写 窗口创建过程分析 消息处理 钩子简介 介绍几个钩子函数,因为它们与窗口创建工程有关 安装钩子函数 HHOOK SetWindowsHookExA([in] int idHook,[in] HOOKPROC lpfn,[in] HINSTANCE hmod,[in] DWORD dwThreadId ); 参数说明…...
基于JavaWeb+SSM+Vue微信小程序的移动学习平台系统的设计和实现
基于JavaWebSSMVue微信小程序的移动学习平台系统的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 Lun文目录 第1章 绪论 1 1.1 课题背景 1 1.2 课题意义 1 1.3 研究内容 2 第2章 开发环…...
解决docker alpine /bin/sh: ./main: not found
解决docker alpine /bin/sh: ./main: not found golang中编译之后的二进制文件部署在alpine镜像中出现了not found问题解决这种情况是因为动态链接库位置错误导致的,alpine镜像使用的是musl libc而不是gun libc。因而动态链接库的位置不一致。在基础镜像内执行&…...
深入了解网络基础:从背景到协议
这里写自定义目录标题 1. 什么是协议呢?2. 什么是网络协议?5. OSI七层网络模型6. 网络传输基本流程1. 数据准备:2. 数据传输:3. 数据接收和重新组装:4. 数据处理与应用: 7. 数据的发送(封装&…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
