当前位置: 首页 > news >正文

通话状态监听-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/Dialer
  • Telecom.apk: /system/priv-app/Telecom/Telecom.apk、packages/service/telecomm
  • TeleService.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 注册

    1. PhoneStateListener注册:最终调用TelephonyRegistry.java#listenWithEventList添加到ArrayList<Record> mRecords
      packages/apps/Dialer/java/com/android/incallui/InCallPresenter.java
this.context.getSystemService(TelephonyManager.class).listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    1. 广播注册: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在民营银行的成功实践

客户简要介绍 某股份有限公司主体是中部地区的民营银行&#xff0c;由其母公司联合9家知名民营企业共同发起设立。正式开业于2016年&#xff0c;紧紧围绕目标产业生态圈和消费金融&#xff0c;着力打造产业银行、便捷银行、数字银行、财富管理银行为一体的BEST银行&#xff0c…...

【送书活动】智能汽车、自动驾驶、车联网的发展趋势和关键技术

文章目录 前言01 《智能汽车》推荐语 02 《SoC底层软件低功耗系统设计与实现》推荐语 03 《SoC设计指南》推荐语 05 《智能汽车网络安全权威指南&#xff08;上册&#xff09;》推荐语 06 《智能汽车网络安全权威指南&#xff08;下册&#xff09;》推荐语 后记赠书活动 前言 …...

不同版本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是一种运行在服务器端的脚本语言&#xff0c;可以嵌入到HTML中。 1.1.1PHP代码标记 在PHP历史发展中&#xff0c;可以使用多种标记来区分PHP脚本 ASP标记&#xff1a; <% php代码 %>短标记&#xff1a; <? Php代码 ?>&#xff0c;以上两种…...

如何在jenkins容器中安装python+httprunner+pytest+git+allure(一)

背景&#xff1a; API接口自动化使用python语言实现&#xff0c;利用httprunner框架编写自动化用例场景&#xff08;执行的时候还是依赖pytest),使用jenkins自动构建git上的源代码&#xff0c;并产生allure报告可视化展示API执行结果。 步骤 1.进入jenkins容器 注意使用roo…...

Android终端模拟器Termux上使用Ubuntu

Termux 上安装各种 Linux 系统是通过 proot-distro 工具来实现的&#xff0c;所以先安装一下 proot-distro 工具。 ~ $ pkg install proot-distro 查看Termux支持安装那些Linux ~ $ proot-distro listSupported distributions:* Alpine LinuxAlias: alpineInstalled: noComme…...

【神器】wakatime代码时间追踪工具

文章目录 wakatime简介支持的IDE安装步骤API文档插件费用写在最后 wakatime简介 wakatime就是一个IDE插件&#xff0c;一个代码时间追踪工具。可自动获取码编码时长和度量指标&#xff0c;以产生很多的coding图形报表。这些指标图形可以为开发者统计coding信息&#xff0c;比如…...

UML统一建模语言

一、建模语言的背景&#xff1a; 通俗地阐述就是&#xff1a;客户一开始不知道要什么&#xff0c;开发通过客户的阐述进行理解和分析&#xff0c;这个过程中间可能会产生一些误解。为了避免此类事件&#xff0c;所以需要建模。类似于要建造一栋楼&#xff0c;建筑设计师根据住…...

Linux命令行控制小米电源开关

飞灵科技产品 flyelf-tech.com&#xff0c;flyelf.taobao.com 最近有需求通过命令控制局域网内小米电源开关&#xff0c;以便于写脚本对产品进行反复上电的启动测试。参考了这篇文章&#xff1a;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”;输入以下样式。注意&#xff1a;两个都必须存在在生效。 .content {/* 跟屏幕高度一样高,不管view中有没有内容,都撑开屏幕高的高度 */height: 100vh; overflow: auto; } .content::-webkit-scrollb…...

Linux 系统开机启动流程

可能没有完全理解&#xff0c;后期整理完Linux的内容&#xff0c;应该理解会深入一些&#xff0c;试着用更简洁的方式和图形来记录&#xff0c;以及一些概念的完善 2023-12-14 一、开机流程 BIOS MBR/GPT 加载 BIOS 的硬件信息与进行自检&#xff0c;并依据设定取得第一个可…...

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版本&#xff0c;但是CCE产品storageclass sfs-turbo共享存储卷不支持动态绑定&#xff0c;官网文档可以实现动态创建子目录&#xff0c;建议大家直接选择这个&#xff0c;不要踩坑了 2、CCE 涉及到的产品&#xff0c;有的需要查看产品…...

计算机网络:自顶向下第八版学习指南笔记和课后实验--网络层(控制平面)

网络层&#xff1a;控制平面 记录一些学习计算机网络:自顶向下的学习笔记和心得 Github地址&#xff0c;欢迎star ⭐️⭐️⭐️⭐️⭐️ 控制平面作为一种网络范围的逻辑&#xff0c;不仅控制沿着从源主机到目的主机的端到端路径间的路由器如何转发数据报&#xff0c;而且控制…...

MFC 窗口创建过程与消息处理

目录 钩子简介 代码编写 窗口创建过程分析 消息处理 钩子简介 介绍几个钩子函数&#xff0c;因为它们与窗口创建工程有关 安装钩子函数 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问题解决这种情况是因为动态链接库位置错误导致的&#xff0c;alpine镜像使用的是musl libc而不是gun libc。因而动态链接库的位置不一致。在基础镜像内执行&…...

深入了解网络基础:从背景到协议

这里写自定义目录标题 1. 什么是协议呢&#xff1f;2. 什么是网络协议&#xff1f;5. OSI七层网络模型6. 网络传输基本流程1. 数据准备&#xff1a;2. 数据传输&#xff1a;3. 数据接收和重新组装&#xff1a;4. 数据处理与应用&#xff1a; 7. 数据的发送&#xff08;封装&…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...