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  进行技术讨论!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/654087.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

车机壁纸生成解决方案,定制化服务,满足个性化需求

在数字化与智能化浪潮的推动下,汽车内部设计已不再仅仅满足于基本功能的需求,更追求为用户带来前所未有的视觉享受与沉浸式体验。美摄科技,凭借其在图像生成与处理领域的深厚积累,推出了一款创新的车机壁纸生成解决方案&#xff0…

修改Windows系统hosts文件,解决GitHub国内访问速度慢甚至无法访问的问题

对国内大多数用户,GitHub的访问速度非常慢,甚至是打不开,无法访问。究其原因,多数是GitHub的CDN域名解析(DNS)遭到了污染或拦截。本文以Windows 10系统为例,通过修改本地hosts文件,解…

电脑可以录音吗?这里有你想要的答案!

在数字化时代,电脑已经成为我们日常生活中不可或缺的工具。除了办公、娱乐等基本功能外,电脑还具备许多实用的辅助功能,其中之一就是录音功能。可是电脑可以录音吗?本文将介绍两种在电脑上录音的方法,希望通过本文的介…

人生二选一:央企就业?美国做博士后?—请看她的抉择

一位30岁的女博士,收到国内央企和德国、美国的博士后邀请函,她该如何选择?知识人网小编推荐这篇文章,为大家解开谜题的同时,也给有同样纠结的学者提供一些启迪。 去年12月底的一个晚上,我收到美国一所高校发…

ubuntu系统开启ssh密码登录

文章目录 前言 一、确认否有ssh服务 二、修改/etc/ssh/sshd_config配置文件 三、重启ssh服务 总结 前言 安装好ubuntu系统后,默认是无法通过密码远程shell连接的,需要修改配置文件。 一、确认否有ssh服务 我这边使用的是ubuntu 22.04 LTS的系统&a…

AirBnb架构简史

2007 年,布莱恩切斯基 (Brian Chesky) 和乔加比亚 (Joe Gabbia) 搬到了旧金山。他们一边想为自己的创业想法筹集资金,一边又需要支付房租。 碰巧的是,当时城里正要举行一个设计会议,这意味着很多设计师都会寻找住处。他们想出了在…

海外仓系统要多少钱?最贵的未必是最好的,性价比高的才是

海外仓系统可以说已经是现在海外仓管理不可或缺的重要工具,然而,很多海外仓企业在选择海外仓系统时最头疼的问题就是不知道到底多少钱才合适。 确实,现在的海外仓系统市场价格体系非常多,几万几十万各种定价都有,让人…

linux父进程fork出子进程后,子进程为何首先需要close文件描述符。

在linux c/c编程时,父进程fork出子进程后,子进程经常第一件事就是close掉所有的文件描述符;为何需要这样做,本文用一个例子进行简单说明。 考虑到一种情况,父进程创建了tcp服务端套接字,并且listen&#x…

redis核心面试题二(实战优化)

文章目录 10. redis配置mysql实战优化[重要]11. redis之缓存击穿、缓存穿透、缓存雪崩12. redis实现分布式session 10. redis配置mysql实战优化[重要] // 最初实现OverrideTransactionalpublic Product createProduct(Product product) {productRepo.saveAndFlush(product);je…

ProxySQL路由策略实现读写分离

目的:配置proxysql路由策略后将不同用户的不同请求路由到不同的节点,实现读写分离 前提条件: 配置表mysql_replication_hostgroups,10为写组,20为读组 mysql_users表中已添加用户writer用户加入10写组,rea…

linux开发之设备树基本语法二

设备树特殊节点,对节点定义别名,chosen节点用来uboot给内核传参 上面的mmc0就是sdmmc0节点的别名 device_type属性 只对cpu节点和memory节点进行描述 自定义属性 这部分自定义,比如定义管脚标号,初始数值等 为什么我们可以在设备树上自己定义属性呢?设备树文件描述的是硬…

AI手语研究数据集;视频转视频翻译和风格化功能如黏土动画;AI检测猫咪行为;开放源码的AI驱动搜索引擎Perplexica

✨ 1: Prompt2Sign 多语言手语数据集,便捷高效用于手语研究。 Prompt2Sign 是一个全面的多语言手语数据集,旨在通过工具自动获取和处理网络上的手语视频。该数据集具有高效、轻量的特点,旨在减少先前手语数据集的不足之处。该数据集目前包含…

Python---Matplotlib(2万字总结)【从入门到掌握】

数据可视化 在完成了对数据的透视之后,可以将数据透视的结果通过可视化的方式呈现出来,简单的说,就是将数据变成漂亮的图表,因为人类对颜色和形状会更加敏感,然后再进一步解读数据背后隐藏的价值。在之前的文章中已经…

gitlab push 代码,密码正确,仍然提示HTTP Basic: Access denied. The provided password

HTTP Basic: Access denied. The provided password or token is incorrect or your account has 2FA enabled and you must use a personal access token instead of a password gitlab 登录账户密码确认正确,登录获取代码仍然提示以上问题,解决方案 …

10、QT—SQLite使用小记1

开发平台:Win10 64位 开发环境:Qt Creator 13.0.0 构建环境:Qt 5.15.2 MSVC2019 64位 构建工具:qmake 在上一篇文章中笔者介绍了sqlite的使用,并提供了一个封装好的文件,这篇文章就针对封装好的文件进行测试…

在table中获取每一行scope的值

目的 当前有一份如下数据需要展示在表格中&#xff0c;表格的页面元素套了一个折叠面板&#xff0c;需要循环page_elements中的数据展示出来 错误实践 将template放在了折叠面板中&#xff0c;获取到的scope是空数组 <el-table-column label"页面元素" show-o…

3D Slicer:从入门到精通——数据模块之DICOM

DICOM 文章目录 DICOM概述DICOM简介Slicer DICOM数据库DICOM插件 如何操作创建DICOM数据库将DICOM文件读入场景DICOM导入DICOM加载 从DICOM数据库中删除数据将数据从场景导出到DICOM数据库将数据从场景导出到DICOM文件DICOM网络传输DICOMweb网络传输 查看DICOM元数据 面板及其用…

初识STM32单片机-TIM定时器

初识STM32单片机-TIM定时器 一、定时器概述二、定时器类型2.1 基本定时器(TIM6和TIM7)2.2 通用定时器(TIM2、TIM3、TIM4和TIM5)2.3 高级定时器(TIM1和TIM8) 三、定时中断基本结构和时基单元工作时序3.1 定时器基本结构3.2 预分频器时序3.3 计数器时序3.3.1 计数器有无预装时序(…

广告界的奥斯卡:揭秘成功广告策划的核心要素

在这个品牌林立、竞争激烈的市场大潮中&#xff0c;想要让自己的品牌声音被听见&#xff0c;一个成功的广告策划无疑是你的超级扩音器。 一个成功的广告策划一般来说需要以下十大要素&#xff1a; 1. 明确的目标和受众定位&#xff1a;你的指南针 首先&#xff0c;咱们得有个…

aws eks节点的初始化引导和鉴权逻辑

kubernetes集群的kubelet的启动引导eks集群的kubelet启动引导 参考资料 https://juejin.cn/post/7016472622246395934eks安全最佳实践&#xff0c;https://aws.github.io/aws-eks-best-practices/security/docs/iam/ kubernetes集群的kubelet的启动引导 按照官方文档和相关…