В автоматизированном тестировании Android имитация телефонных звонков является распространенной задачей. С помощью инструмента Android Debug Bridge (ADB) вы можете отслеживать статус входящего вызова телефона и автоматически отвечать на вызов. В этой статье объясняется, как использовать АБР для достижения этой цели.
Прежде чем начать, убедитесь, что вы выполнили следующие приготовления:
Для мониторинга статуса вызова сотового телефона,мы можем использоватьadb shell dumpsys telephony.registry
Заказ,Эта команда предоставляет информацию о состоянии телефона.
last known state:
Phone Id=0
mCallState=1
mRingingCallState=5
mForegroundCallState=0
mBackgroundCallState=0
mPreciseCallState=Ringing call state: 5, Foreground call state: 0, Background call state: 0, Disconnect cause: -1, Precise disconnect cause: -1
mCallDisconnectCause=-1
mCallIncomingNumber=17000724942
mServiceState={mVoiceRegState=0(IN_SERVICE), mDataRegState=0(IN_SERVICE), mChannelNumber=1825, duplexMode()=1, mCellBandwidths=[15000], mOperatorAlphaLong=Китай Телеком, mOperatorAlphaShort=CT, isManualNetworkSelection=false(automatic), getRilVoiceRadioTechnology=14(LTE), getRilDataRadioTechnology=14(LTE), mCssIndicator=unsupported, mNetworkId=-1, mSystemId=-1, mCdmaRoamingIndicator=-1, mCdmaDefaultRoamingIndicator=-1, mIsEmergencyOnly=false, isUsingCarrierAggregation=false, mArfcnRsrpBoost=0, mNetworkRegistrationInfos=[NetworkRegistrationInfo{ domain=PS transportType=WLAN registrationState=UNKNOWN roamingType=NOT_ROAMING accessNetworkTechnology=UNKNOWN rejectCause=0 emergencyEnabled=false availableServices=[] cellIdentity=null voiceSpecificInfo=null dataSpecificInfo=null nrState=**** rRplmn= isUsingCarrierAggregation=false nsaState=0 mConfigRadioTech=0}, NetworkRegistrationInfo{ domain=CS transportType=WWAN registrationState=HOME roamingType=NOT_ROAMING accessNetworkTechnology=LTE rejectCause=0 emergencyEnabled=false availableServices=[VOICE,SMS,VIDEO] cellIdentity=CellIdentityLte:{ mPci=50 mEarfcn=1825 mBands=[3] mBandwidth=15000 mMcc=460 mMnc=11 mAlphaLong=CHN-CT mAlphaShort=CT mAdditionalPlmns={} mCsgInfo=null} voiceSpecificInfo=VoiceSpecificRegistrationInfo { mCssSupported=false mRoamingIndicator=0 mSystemIsInPrl=0 mDefaultRoamingIndicator=0} dataSpecificInfo=null nrState=**** rRplmn=46011 isUsingCarrierAggregation=false nsaState=0 mConfigRadioTech=0}, NetworkRegistrationInfo{ domain=PS transportType=WWAN registrationState=HOME roamingType=NOT_ROAMING accessNetworkTechnology=LTE rejectCause=0 emergencyEnabled=false availableServices=[DATA] cellIdentity=CellIdentityLte:{ mPci=50 mEarfcn=1825 mBands=[3] mBandwidth=15000 mMcc=460 mMnc=11 mAlphaLong=CHN-CT mAlphaShort=CT mAdditionalPlmns={} mCsgInfo=null} voiceSpecificInfo=null dataSpecificInfo=android.telephony.DataSpecificRegistrationInfo :{ maxDataCalls = 16 isDcNrRestricted = false isNrAvailable = false isEnDcAvailable = false LteVopsSupportInfo : mVopsSupport = 2 mEmcBearerSupport = 2 } nrState=**** rRplmn=46011 isUsingCarrierAggregation=false nsaState=0 mConfigRadioTech=0}], mNrFrequencyRange=0, mOperatorAlphaLongRaw=CHN-CT, mOperatorAlphaShortRaw=CT, mIsDataRoamingFromRegistration=false, mIsIwlanPreferred=false}
mVoiceActivationState= 0
mDataActivationState= 0
mUserMobileDataState= false
выше это adb shell dumpsys telephony.registry
Часть вывода, предоставляющая информацию о статусе телефонного звонка. Вот пояснение к информации:
Phone Id=0: выражатьсотовый номер телефона на телефоне ID。в целом,сотовый На телефоне может быть несколько телефонов, каждый телефон имеет уникальный ИДЕНТИФИКАТОР. В этом примере идентификатор для 0,выражатьсотовый Первый звонок по телефону.
mCallState=1: Указывает статус входящего вызова. Здесь, 1 Указывает, что состояние телефона CALL_STATE_RINGING, то есть звонок, указывает на то, что в данный момент есть входящий вызов.
mRingingCallState=5: Указывает состояние звонящего вызова. Здесь, 5 Указывает, что статус входящего вызова CALL_STATE_ALERTING, указывающий, что выполняется входящий вызов.
mForegroundCallState=0: Указывает состояние приоритетного вызова. Здесь, 0 Показывает, что на стойке регистрации нет активных звонков.
mBackgroundCallState=0: Указывает состояние фоновых вызовов. Здесь, 0 Указывает на отсутствие активных вызовов в фоновом режиме.
mPreciseCallState=Ringing call state: 5, Foreground call state: 0, Background call state: 0, Disconnect cause: -1, Precise disconnect cause: -1: Предоставляет более подробную информацию о статусе вызова, включая статус входящего вызова, статус приоритетного вызова, статус фонового вызова и причины отключения.
mCallDisconnectCause=-1: Указывает причину отключения вызова, -1 Указывает на то, что не предоставлена информация о причине отключения.
mCallIncomingNumber=17000724942: Указывает номер входящего звонка. Здесь номер вызывающего абонента 17000724942。
Согласно приведенной выше информации, телефон звонит и в данный момент поступает входящий звонок. Статус звонка — CALL_STATE_ALERTING, а номер вызывающего абонента — 17000724942. Это часть выходных данных telephony.registry, которая предоставляет статус телефона и информацию о вызовах.
Вот пример Python для получения статуса входящего вызова:
import subprocess
def get_call_state():
try:
output = subprocess.check_output(["adb", "shell", "dumpsys", "telephony.registry"], universal_newlines=True)
lines = output.splitlines()
for line in lines:
if "mCallState" in line:
call_state = line.split("=")[1].strip()
return int(call_state)
except subprocess.CalledProcessError as e:
print(f"Error executing adb command: {e}")
return None
Как только вы получите статус вызова, вы сможете ответить на него по мере необходимости. Обычно статус входящего звонка равен 1, что означает, что входящий звонок звонит. В это время мы можем имитировать нажатие кнопки для ответа на звонок, используя следующий код:
def answer_call():
subprocess.call('adb shell input keyevent 5', shell=True)
Вот пример, демонстрирующий, как использовать ADB в автоматизированном тестировании для прослушивания входящих вызовов и автоматического ответа на них:
if __name__ == "__main__":
call_state = get_call_state()
if call_state is not None:
print(f"Статус входящего звонка: {call_state}")
if call_state == 1: # Когда статус вызова для CALL_STATE_RINGING час
print("Ответ на звонок...")
answer_call()
else:
print("Невозможно получить статус входящего звонка")
Создайте цикл для периодической проверки статуса входящих вызовов и выполнения соответствующих действий при обнаружении вызова. Вот пример непрерывного определения статуса входящего вызова:
import subprocess
import time
def get_call_state():
try:
output = subprocess.check_output(["adb", "shell", "dumpsys", "telephony.registry"], universal_newlines=True)
lines = output.splitlines()
for line in lines:
if "mCallState" in line:
call_state = line.split("=")[1].strip()
return int(call_state)
except subprocess.CalledProcessError as e:
print(f"Error executing adb command: {e}")
return None
def answer_call():
subprocess.call('adb shell input keyevent 5', shell=True)
if __name__ == "__main__":
while True:
call_state = get_call_state()
if call_state is not None:
print(f"Статус входящего звонка: {call_state}")
if call_state == 1: # Когда статус вызова для CALL_STATE_RINGING час
print("Ответ на звонок...")
answer_call()
else:
print("Невозможно получить статус входящего звонка")
# Проверьте еще раз после сна в течение определенного периода времени
time.sleep(5) # 5Второй,Вы можете настроить время сна по мере необходимости
Различия между устройствами и производителями. Разные устройства Android и производители могут иметь разные реализации, поэтому необходимо адаптировать их с учетом конкретных обстоятельств.
Используя ADB для отслеживания статуса входящих вызовов и автоматического ответа на вызовы, вы можете эффективно интегрировать тестовые примеры, связанные с телефоном, чтобы гарантировать правильную работу приложения при различных обстоятельствах, тем самым улучшая качество и стабильность мобильных приложений. Это важная задача автоматического тестирования, особенно для приложений, которым необходимо взаимодействовать с телефоном.