原标题:自制导出安卓系统全部应用版本号小工具
新书
速递
文 |事须渐修
写在前面
在进行安卓系统版本测试时,发测试报告需要将系统里各应用的版本附上,通常的做法是根据包名在cmd窗口手动输入'adb shell dumpsys 包名 |grep version ',如果需要查很多的应用版本号那这个工作量就会很大。也有一些小工具可以展示应用的版本号,但是没有导出功能。所有根据这个情况我编写了小脚本,可以将所有应用的版本号导出到本地的excel里,也可以将数据保存到mysql数据库存档。
一. 实现步骤分析:
1)设备与PC端通过adb连接;
2)获取系统里的应用包名列表,然后遍历应用,获取版本信息,存储在列表里;
3)调用不同的类方法可以选择将数据存贮到excel里或者数据库里,或者两个方法都调用。
二. 前期准备:
1)安装好python3.x和mysql以及adb调试环境
2)实现此功能用到的python模块有re、pymysql、openpyxl、os等
需要将pymysql、openpyxl等模块提前安装好
安装模块的方法:
<1>.在cmd下cd到python的下,如cd C:python37s然后执行pip install pymysql
<2>.将C:python37s添加到环境变量,然后直接执行py -3 -m pip install pymysql
三. 代码实现1)将要用到的mysql命令可以单独保存的,保存到sql.py文件下,封装在函数里,以便主程序调用(左右滑动或横屏查看代码)1def Sql_Command(table_name_L,table_name_R): #2个参数拼接作为数据库表名
2# 创建Version_info_Android表的sql命令,如果Version_info_Android表不存在则创建,已存在则不创建
3create_database = ' CREATEDATABASEIFNOTEXISTSVersion_info_Android DEFAULTCHARSETutf8 COLLATEutf8_general_ci;'
4# 创建testdata表
5drop_table_if_exist_sql = " droptableifexists%s;" % (table_name) #如果此表已存在则删除该表
6create_table = """ createtable%s(
7idintnotnullauto_increment comment'主键',
8packagevarchar( 40) uniquenotnullcomment'package',
9versionvarchar( 30) notnullcomment'version',
10versioncode varchar( 30) defaultnull,
11primary key( id)
12) engine= innodbcharactersetutf8 comment'Android应用版本号'; #创建表,包括id(自增),包名,version,versioncode
13""" % (table_name)
14return table_name,create_database,drop_table_if_exist_sql,create_table #在主程序中会用到这4个值
2) 将自定义类单独放在python文件里1classMyError(Exception): #继承Exception类,自定义异常类
2def__init__(self, value):
3self.value = value
4def__str__(self):
5returnrepr( self.value)
----感谢您👇灵动的小手--3)主程序1importos
2importtime
3importre
4fromopenpyxl importWorkbook
5importpymysql
6fromSql import*
7fromMyError import*
8classGet_Version:#定义类
9def__init__(self,ip):#连接adb
10os.popen( 'adb disconnect') #断开跟其他设备的连接
11os.popen( 'adb kill-server') #关闭adb服务
12try:
13ifre.match( r'((25[0-5]|2[0-4]d|((1d{2})|([1-9]?d))).){3}(25[0-5]|2[0-4]d|((1d{2})|([1-9]?d)))',ip).group==ip: #判断ip参数是否合规,此正则表达式可以从网上搜到
14return_value=os.popen( 'adb connect %s'%ip).read #读取返回值
15if( 'connected to %s'%ip) inreturn_value: #连接正常的返回值里有''connected to'关键词,如果返回值里包含此关键词则说明连接成功,可以进行下面的步骤
16print( 'adb connected successfully!,you can continue!')
17else:
18raiseMyError( '请检查输入的ip地址是否和本电脑在同一网段,或者需要启动调试设备的root权限') #如果adb连接失败,则抛出异常,提示用户错误信息
19else:
20raiseMyError( 'ip输入不合规,请检查') #如输入的ip为192.168.1.256会触发此异常,正则表达式筛选出来的结果是192.168.1.25
21exceptAttributeError:
22raiseMyError( 'ip输入不合规,请检查') #如输入的ip为256.168.1.11会触发此异常
23exceptException ase:
24print(e) #捕获其他异常
25defget_path(self):#作为excel保存的路径
26self.path=os.getcwd+ r'APP_VERSION'#要保存excel的文件路径,在该py文件同路径下的APP_VERSION文件夹
27ifnotos.path.exists(self.path): #如果路径不存在则创建此路径
28os.makedirs(self.path)
29returnself.path
30defget_rel_and_model(self):#获取要保存数据的excel_sheet名
31self.rel=os.popen( 'adb shell getprop |findstr rel')
32self.rel=self.rel.read self.rel=re.search( r'[ro.build.version.release]:s[(.*)]',self.rel).group( 1) #用固件版本号作为sheet页名称
33self.rel=self.rel.replace( '-', '_') #mysql里表名里包含'-'会报错,替换成'_'
34self.rel=self.rel.replace( '.', '_') #mysql里表名里包含'.'会报错,替换成'_'
35self.model=os.popen( 'adb shell getprop |findstr model')
36self.model=self.model.read self.model=re.search( r'[ro.product.model]:s[(.*)]',self.model).group( 1)
37returnself.rel,self.model
38defapp_list_version(self):#获取应用版本号列表
39data=os.popen( 'adb shell pm list package')
40data=data.read
41app_list=data.split( 'n')
42self.result=[[ '包名', 'Version', 'VersionCode']]
43fori inapp_list:
44ifi[: 8]== 'package:':
45temp=[]
46version=os.popen( 'adb shell dumpsys package %s|findstr version '%i[ 8:])
47version=version.read
48version=version.split
49forj inrange(len(version)):
50iflen(temp) < 2andbool(re.match( r'version',version[j])) isTrue: #只获取最新的应用版本号,限制len(mid)最长为2
51temp.append(version[j].split( '=')[ 1])
52temp.append(i[ 8:])
53temp.reverse
54self.result.append(temp)
55print(‘result完成’)
56returnself.result
57defcreat_excel_by_openpyxl(self):
58wb=Workbook #生成一个excel
59ws=wb.active #操作当前sheet页
60ws.title=self.rel #修改sheet页名称
61# 调整列宽为40
62ws.column_dimensions[ 'A'].width = 40
63ws.column_dimensions[ 'B'].width = 40
64ws.column_dimensions[ 'C'].width = 40
65fori inself.result:
66ws.append(i) #按行写入到excel里
67excel_name = '%s%s.xlsx'% (self.path,time.strftime( '%Y%m%d%H%M%S', time.localtime(time.time))) #excel名称为当前的时间点
68wb.save(excel_name)
69print( 'excel create successully')
70returnNone
71defsave_in_mysql(self, host, port, username, password, charset):
72try:
73# 连接mysql数据库
74conn = pymysql.connect(
75host=host,
76port=port,
77user=username,
78passwd=password,
79charset=charset
80)
81# 获取数据库游标
82cur = conn.cursor
83sql_command = Sql_Command(self.model,self.rel) #获取(table_name,create_database,drop_table_if_exist_sql,create_table),table_name为model_rel
84print(sql_command)
85# 创建数据库
86cur.execute(sql_command[ 1])
87# 选择创建好的gloryroad数据库
88conn.select_db( "Version_info_Android")
89# 创建测试表
90cur.execute(sql_command[ 2])
91cur.execute(sql_command[ 3]) #
92fori inself.result[ 1:]: #self.result[0]是['包名','Version','VersionCode'],不需要写入到数据库,若有从result[1]开始写入
93sql = ''.join([ "insert into %s"%sql_command[ 0], " (package, version,versioncode) values(%s, %s,%s);"]) #拼接sql命令,将table_name拼接进去
94res = cur.execute(sql,(i[ 0],i[ 1],i[ 2])) #将数据写入到表里
95print( '数据库写入完成')
96exceptpymysql.Error ase:
97raisee #如果发生异常则抛出异常
98else:
99# 关闭游标
100cur.close
101# 提交操作
102conn.commit
103# 关闭连接
104conn.close
105print( "创建数据库及表成功")
106
107if__name__== '__main__':
108ip=input( '请输入要调试设备的ip地址:')
109a=Get_Version(ip) #创建类实例
110a.get_path #获取路径
111a.get_rel_and_model #获取sheet名称
112a.app_list_version #获取result
113a.creat_excel_by_openpyxl #将result写入到excel
114a.save_in_mysql( 'localhost', 3306, 'root', 'admin', 'utf8') #将result存入数据库
四.将MyError和Sql以及主程序文件放在统计目录下,运行主程序即可
五.生成的mysql表
六.在py文件同同目录下的version文件夹下生成的excel表
责任编辑: