Python + adb 实现打电话功能

前言

其实很多年前写过一篇python打电话的功能,链接如下:

Python + twilio 实现打电话和发短信功能_自动发短信代码-CSDN博客

今天由于工作需要,又用python写了个关于打电话的小工具,主要是通过ADB方式实现的

实现过程

1.先利用adb指令封装几个常用的方法

具体的含义可以看注释,注释写的很清楚

	def make_a_call(self, phoneNumber):
		# 拨打电话,只需传入目标电话号码即可
		phoneNumber = int(phoneNumber)

		# 执行adb指令去拨打电话
		proc = Utils.execute_adb_command('adb shell am start -a android.intent.action.CALL -d tel:{:d}'.format(int(phoneNumber)))

		resp = proc.stdout.read()

		logging.info('Calling {:d} ...'.format(phoneNumber))

	def answer_a_call(self):
		# 接听电话的函数

		# 先获取一下当前通话状态
		state = self.get_call_state()

		# 如果状态时振铃,那么接听
		if state == CallState.RING:
			Utils.execute_adb_command('adb shell am start -a android.intent.action.ANSWER')
			logging.info('Have answered a call')
		else:
			logging.info('No call incoming')

	def get_call_state(self):
		# adb shell 后的命令用双引号,否则执行出错!!!!
		proc = Utils.execute_adb_command('adb shell "dumpsys telephony.registry|grep \"mCallState\""')
		resp = proc.stdout.read()  # 读取命令执行的结果

		state = str(resp).splitlines()[-1].split('=')[-1]  # 从返回内容中取出状态字符串

		# 返回通话状态
		return Utils.to_enum(int(state), CallState)

	def hang_up_a_call(self):
		# 执行adb 指令去挂掉电话

		# 先查询一下当前的状态
		state = self.get_call_state()

		# 如果状态时振铃,正在通话中,那么执行挂断,否则log提示
		if state in [CallState.RING, CallState.CALLING]:
			proc = Utils.execute_adb_command('adb shell input keyevent 6')
			logging.info('Have hang up a call')
		else:
			logging.info('No call to be hang up')

2.再使用pysimpleGUI库写一个简单的工具界面即可

# 这是绘制界面的函数
def make_window():
	"""
	Build a GUI page
	:return: window
	"""
	NetworkType = ['2G', '4G', '5G']

	def name(name, NAME_SIZE=11):
		dots = NAME_SIZE - len(name) - 2
		return sg.Text(name + ' ' + ' ' * dots, size=(NAME_SIZE, 1), justification='r', pad=(0, 0), font='Courier 11')

	# 绘制设置选项
	layout_basic = [
		[name('  网络类型:'), sg.Combo(default_value=NetworkType[2], values=NetworkType, size=(12, 2), key='-NETWORK-'), sg.Button('设置', key='-SET-', enable_events=True)],
		[name('  呼叫号码:'), sg.Input(default_text=10086, size=(12, 2), key='-NUMBER1-'), sg.Input(default_text='', size=(12, 2), key='-NUMBER2-'), sg.Input(default_text='', size=(12, 2), key='-NUMBER3-'), sg.Input(default_text='', size=(12, 2), key='-NUMBER4-'), sg.Input(default_text='', size=(12, 2), key='-NUMBER5-')],
		[name('  呼叫时间:'), sg.Input(default_text=30, size=(8, 2), key='-CALL_TIME-'), sg.Text('秒')],  # input代表输入框,default_text代表默认值, key代表给这输入框的起个别名
		[name('  循环次数:'), sg.Input(default_text=1, size=(8, 2), key='-COUNT-'), sg.Text('次')],

	]

	# 绘制操作选项
	layout_action = [
		[sg.Button('呼叫', size=(10, 2), key='-RUN-'), sg.Push(), sg.Button('挂断', size=(10, 2), key='-STOP-'), sg.Push(), sg.Button('退出', size=(10, 2), key='-EXIT-')]
	]

	col1 = sg.Column([[sg.Frame('设置:', layout_basic, size=(900, 140))],  [sg.Frame('操作:', layout_action, size=(900, 80))]])

	# 绘制版权所有信息,xxx内容可以自定义修改
	layout = [[sg.vtop(col1)], [sg.Push(), sg.Text('@Copyright xxxx.', font='楷体 12'), sg.Push()]]

	# 绘制工具的标题栏
	window = sg.Window('Make call V1.0.0', layout, auto_size_text=True, size=(1000, 300), finalize=True, enable_close_attempted_event=True)

	return window

3.呈现的结果如下

1.可以根据需要设置网络类型,比如2G,3G,4G,5G等等

2.可以自定义呼叫的号码,且支持多个号码

3.支持呼叫时间的自定义

4.支持循环次数的自定义

 遇到的问题

一开始通过adb命令去切换网络时,无论如何都切换不成功;即使切换后开关飞行模式也无法生效,最后发现需要重启设备方可生效。这里贴一下ADB切换网络类型的命令,供参考:

设置网络类型:settings put global preferred_network_mode + 网络类型枚举值

获取网络类型:settings get global preferred_network_mode

各个制式的网络类型枚举值如下:
 


/* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
int NETWORK_MODE_WCDMA_PREF = 0; /* GSM/WCDMA (WCDMA preferred) */
int NETWORK_MODE_GSM_ONLY   = 1; /* GSM only */
int NETWORK_MODE_WCDMA_ONLY  = 2; /* WCDMA only */
int NETWORK_MODE_GSM_UMTS   = 3; /* GSM/WCDMA (auto mode, according to PRL)
int NETWORK_MODE_CDMA       = 4; /* CDMA and EvDo (auto mode, according to PRL)
int NETWORK_MODE_CDMA_NO_EVDO   = 5; /* CDMA only */
int NETWORK_MODE_EVDO_NO_CDMA   = 6; /* EvDo only */
int NETWORK_MODE_GLOBAL   = 7; /* GSM/WCDMA, CDMA, and EvDo*/                                            
int NETWORK_MODE_LTE_CDMA_EVDO  = 8; /* LTE, CDMA and EvDo */
int NETWORK_MODE_LTE_GSM_WCDMA  = 9; /* LTE, GSM/WCDMA */
int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10;
/* LTE, CDMA, EvDo, GSM/WCDMA */
int NETWORK_MODE_LTE_ONLY     = 11; /* LTE Only mode. */
int NETWORK_MODE_LTE_WCDMA  = 12; /* LTE/WCDMA */

总结

总结下来就是ADB命令可以做很多事情,前提是需要找到相应的ADB指令,这就需要对Android有一定的了解!

有问题的伙伴可以直接加我WX:xgh321324  进行技术讨论!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不过如此1951

如果有收获,可以打赏一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值