通话状态监听-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. 数据的发送(封装&…...

针对这两个趋势,3.0全新新零售商业模式可以采取以下策略:
国内市场确实存在“消费升级”和“消费降级”两个趋势,这是由于不同消费者群体的需求和购买力存在差异。消费升级主要发生在高端市场,消费者愿意为高品质、高价值、高价格的商品和服务付出更多。而消费降级则主要发生在中低端市场,消费者更加…...

鸿蒙HarmonyOS开发用什么语言
1.网上流行一句有中国底蕴的话:鸿蒙系统方舟框架盘古大模型。都方舟框架了肯定主推的是ArkUI框架。其实还能使用C、Java和Js开发。 2.从API8开始,Java语言已经从鸿蒙开发剔除了,而官方推荐的是ArkTs.下图是ArkTS与TS、JS的关系。 ArkTs 是TS的…...

气象数据预测分析与可视化:天气趋势预测揭秘
气象数据预测分析与可视化:天气趋势预测揭秘 引言数据获取数据分析可视化展示Flask框架实现创新点:空气质量预测结论 引言 天气对我们日常生活和工作有着重要的影响,因此天气预测与分析变得愈发重要。本文将介绍如何通过爬取2345天气网的数据…...

install cuda cudnn tersorRT
1, dark view 2,470-server cant install 11.4 3,cuda.run and tensorRT.dpkg cant # 安装 $ ubuntu-drivers devices$ sudo apt-get install nvidia-driver-470-server # 推荐是server,都可以。#delelt sudo apt --purge remove nvidia-* CUDA Toolkit Archiv…...

Vue 3 + Vite 4 移动端低版本白屏处理
vue3打包后在低版本浏览器或webview中出现白屏,原因就是因为语法兼容问题。根据vite官方文档描述,build.target 默认支持 Chrome >87、Firefox >78、Safari >14、Edge >88 传送,所以需要我们手动兼容低版本。 方法: …...

Python爬虫-解决使用requests,Pyppeteer,Selenium遇到网站显示“您的连接不是私密连接”的问题|疑难杂症解决(2)
前言 本文是该专栏的第13篇,后面会持续分享python爬虫案例干货,记得关注。 相信很多同学在处理爬虫项目的时候,会遇到一些网站出现如下图所示的情况: 就是当你不论是使用requests进行协议请求,还是使用自动化框架pyppeteer或者selenium都会出现上图中的情况。这相信会或多…...

机场信息集成系统系列介绍(5):机场运行资源管理系统
目录 一、简介 二、主要功能 1、 航班资源管理模块 2、甘特图资源模块 3、规划管理模块 4、资源基础数据定义及配置管理模块 5、系统功能设置模块 6、 审计管理模块 一、简介 机场运行资源管理系统(ORMS) 是一种专门用于管理和优化机场运行资源的系统。它能够实现机场航…...

JavaEE:线程池精讲
目录 一.什么是线程池 二.线程池的实现原理 🎈为什么要有工厂模式? 三.线程池的构造方法解读 🎈线程池的拒绝策略 四.自己实现一个线程池 一.什么是线程池 简单来说,线程池就好比一块鱼塘,鱼塘中的每条鱼就是一个线程…...

spring-cloud-starter-gateway-mvc的网关实现
一 概括 最近,我也一直在使用SpringCloudGateway开发我们自己的网关产品。根据我对官网文档:https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway-server-mvc.html 的理解,内容如下: SpringCloudGatew…...

《PySpark大数据分析实战》-11.Spark on YARN模式安装Hadoop
📋 博主简介 💖 作者简介:大家好,我是wux_labs。😜 热衷于各种主流技术,热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员(PCTA)、TiDB数据库专家(PCTP…...