编程小白,刚接触也首次接触编程不过一个月多,首先接触的就是python编程。
正好单位需要对多台设备批量安装APK的工具,就想着以完成这样一个小工具的目标来学习python。
刚开始的思路是:
获取连接设备的数量
获取连接设备的IMEI
批量安装apk
打开应用及获取应用版本
import os
import glob
# 获取设备编号
devices = os.popen("adb devices").read()
devices_list = devices.split()
# 已连接设备数
num = 0
for i in devices_list:
if i == "device":
num += 1
print("已连接设备数量:",num)
# 获取多部设备的IMEI
for i in devices_list[4::2]:
# 获取设备系统版本
devices_version = os.popen("adb -s " + i + " shell getprop ro.build.version.release").read()
devices_version_num = devices_version.split(".")
devices_version_num1 = int(devices_version_num[0])
# 当系统版本大于4.4时
# 当系统版本超过一个数时
if len(devices_version_num) >= 2:
devices_version_num2 = int(devices_version_num[1])
if devices_version_num1 > 4 and devices_version_num2 != 4:
devices_IMEI = os.popen("adb -s " + i + " shell service call iphonesubinfo 1").read()
devices_IMEI_list = devices_IMEI.split("'")
devices_IMEI_num = '''
----------设备----------
设备IMEI:{0} 系统版本:{1}
'''.format(devices_IMEI_list[1::2], devices_version)
print(devices_IMEI_num)
if devices_version_num1 <= 4 and devices_version_num2 <= 4:
devices_IMEI = os.popen("adb -s " + i + " shell service call iphonesubinfo 1").read()
devices_IMEI_list = devices_IMEI.split("'")
devices_IMEI_num = '''
----------设备----------
设备IMEI:{0} 系统版本:{1}
'''.format(devices_IMEI_list[1::2], devices_version)
print(devices_IMEI_num)
# 当系统版本只有一个数时
else:
if devices_version_num1 > 4:
devices_IMEI = os.popen("adb -s " + i + " shell service call iphonesubinfo 1").read()
devices_IMEI_list = devices_IMEI.split("'")
devices_IMEI_num = '''
----------设备----------
设备IMEI:{0} 系统版本:{1}
'''.format(devices_IMEI_list[1::2], devices_version)
# 打印IMEI
print(devices_IMEI_num)
if devices_version_num1 <= 4:
devices_IMEI = os.popen("adb -s " + i + " shell service call iphonesubinfo 1").read()
devices_IMEI_list = devices_IMEI.split("'")
devices_IMEI_num = '''
----------设备----------
设备IMEI:{0} 系统版本:{1}
'''.format(devices_IMEI_list[1::2], devices_version)
print(devices_IMEI_num)
# 安装apk
for i in devices_list[4::2]:
apk_file = glob.glob("*.apk")
if len(apk_file) >= 1:
for apk in glob.glob("*.apk"):
print(apk)
os.system("adb -s " + i + " install -r " + apk)
else:
print("未找到apk")
os.system("pause")
for i in devices_list[4::2]:
devices_package = os.popen("adb -s " + i + " shell pm list package").read()
if "应用包名" in devices_package:
os.system("adb -s " + i + " shell am start -n ········Activity")
print("应用已安装")
os.system("pause")
else:
print(None)
os.system("pause")
这个程序在使用的过程中有一些问题,比如:
获取的IMEI号掺着“多余”的符号
安装apk的时候不是同时多个设备安装apk,而是一台安装完成后继续下一台设备
我想要的效果是多台设备同时安装应用,本来打算学一下Python中的进程,想看看用多进程或者进程池的方法行不行。
但直到后来看到了另一种方法——
不是用Python,而是用DOS脚本。
我发现DOS脚本更加简单,而且能够实现同时多台设备安装apk,而且更改更加方便——虽然我本来的目的是为了学习Python——但此刻我想既然有更简便的方法来实现自己的需求,那索性围魏救赵一把。
我又开始接触DOS。
然后,我的思路又变成了,通过启动BAT文件实现安装与获取版本的目的。
主程序:
import os
# 设备数量
devices = os.popen("adb devices").read()
devices_list = devices.split()
devices_list_num = []
for i in devices_list[4::2]:
devices_list_num.append(i)
print("连接设备数:", len(devices_list_num))
# 设备IMEI
for i in devices_list[4::2]:
devices_IMEI = os.popen("adb -s " + i + " shell service call iphonesubinfo 1").read()
devices_IMEI_list = devices_IMEI.split("'")
print("设备IMEI:", devices_IMEI_list[1::2])
# 执行bat文件
bat_path1 = os.path.abspath(".")
os.system(os.path.join(bat_path1, "updata.bat"))
bat = os.listdir(bat_path1)
# 获取应用版本号
for i in bat:
if i == "end.txt":
for i in devices_list[4::2]:
devices_package = os.popen("adb -s " + i + " shell pm list package").read()
if "应用包名" in devices_package:
os.system("adb -s " + i + " shell am start -n ·····Activity")
os.system(os.path.join(bat_path1, "vision.bat"))
for i in bat:
if i == "end.txt":
file_path1 = os.path.join(bat_path1, i)
os.remove(file_path1)
if i == "start.txt":
file_path1 = os.path.join(bat_path1, i)
os.remove(file_path1)
os.system("pause")
因为现在安卓版本4.4以下的很少见了,所以舍弃了对安卓系统版本的获取判断,只针对4.4以上的设备获取IMEI
安装apk的dos脚本:
@echo off
echo>start.txt
adb devices >devices.txt
for /f "skip=1 tokens=1 delims= " %%i in (devices.txt) do (echo %%i >>devicenum.txt)
for /f %%i in (devicenum.txt) do (start "开始安装" cmd /c "@echo off&& for /r "%cd%\ready_apk\" %%a in (*.apk) do (adb -s %%i install -r %%a &&echo>end.txt)" )
del devicenum.txt
pause
echo.
获取版本号和IMEI的脚本:
@echo off
adb devices>devices2.txt
for /f "skip=1 tokens=1 delims= " %%i in (devices2.txt) do ( echo %%i >> devicesnum.txt)
for /f %%i in (devicesnum.txt) do (
echo 设备ID:&&adb -s %%i shell "service call iphonesubinfo 1 | grep -o '[0-9a-f]\{8\} ' | tail -n+3 | while read a; do echo -n \\u${a:4:4}\\u${a:0:4}; done"
echo.
echo 应用已安装
echo 应用版本:
adb -s %%i shell dumpsys package 应用包名 | findstr versionName
echo.
)
del devices2.txt
del devicesnum.txt
pause
但是这一版在实际运行中又遇到了一个问题:
Python内有for循环,dos中也有for循环。
这就造成,Python内for每循环一次:“获取设备编号——获取设备内已安装应用——运行bat文件”这个过程,bat内的for循环就完成执行一次。
也就是说,我获取一遍设备的已安装应用后,bat文件就获取一次所有设备的某应用的版本
也就是说,假如有四台设备同时安装应用,那么这四台设备每台所安装的应用的版本号就要被获取四次。
这一次,逼迫我不得不继续将这部分任务重新放到Python里面。
然后又弄出了船新版本:
import os
# 设备数量
devices = os.popen("adb devices").read()
devices_list = devices.split()
devices_list_num = []
for i in devices_list[4::2]:
devices_list_num.append(i)
print("连接设备数:", len(devices_list_num))
# 执行update批处理文件
bat_path1 = os.path.abspath(".")
os.system(os.path.join(bat_path1, "updata.bat"))
bat = os.listdir(bat_path1)
# 获取设备ID,获取版本号
for a in bat:
if a == "end.txt":
for i in devices_list[4::2]:
devices_IMEI = os.popen("adb -s " + i + " shell service call iphonesubinfo 1").read()
devices_IMEI_list = devices_IMEI.split("'")
devices_ID_list = []
for x in devices_IMEI_list[1::2]:
devices_ID_list.append(x)
devices_id = "".join(devices_ID_list)
devices_ID = "".join([a for a in devices_id if a != "." and a != " "])
print("设备ID:", devices_ID)
devices_package = os.popen("adb -s " + i + " shell pm list package").read()
os.system("adb -s " + i + " shell am start -n ······Activity")
Vn = os.popen("adb -s " + i + " shell dumpsys package ······ | findstr versionName").read()
print("应用版本:", Vn)
# 删除文档
for i in bat:
if i == "end.txt":
file_path1 = os.path.join(bat_path1, i)
os.remove(file_path1)
if i == "start.txt":
file_path1 = os.path.join(bat_path1, i)
os.remove(file_path1)
os.system("pause")
目前该版本还在试用中,也不知道会不会出现什么新问题······
除了安装工具,我还做了两个其他的小工具
一个是将指定的apk文件复制到准备安装的文件夹中的小工具,程序如下:
import os
import shutil
apk_path1 = (os.path.abspath(".") + r"\ready_apk")
apk1 = os.listdir(apk_path1)
def CopyApk():
apk_path2 = (os.path.abspath(".") + r"\apk")
apk2 = os.listdir(apk_path2)
apk_name = input("需安装的apk文件:")
apk_name2 = apk_name.split()
apk_path3 = (os.path.abspath(".") + r"\apk\\" + apk_name)
copyapk = os.listdir(apk_path3)
apk_list = []
for i in apk2:
for a in apk_name2:
if i == a:
apk_list.append(i)
print(apk_list)
choice2 = input("确认复制此apk文件(Y/y or N/n):")
if choice2 == "y" or choice2 == "Y":
for i in copyapk:
file_path2 = os.path.join(apk_path3, i)
shutil.copy(file_path2, apk_path1)
if len(apk1) > 0:
for i in apk1:
file_path1 = os.path.join(apk_path1, i)
os.remove(file_path1)
print("已删除ready_apk中所有文件")
CopyApk()
if len(apk1) == 0:
CopyApk()
另一个是在连接设备时对设备进行“扫描”,看看哪台设备没有连接上,或者USB口或其他地方出现了问题无法连接。
这个工具是通过不断打开bat文件,不断下发adb命令实现的。
在安装工具运行时——安装apk的bat文件打开时会生成一个文档,这个工具就是通过不断判断这个文档是否存在而暂停或者继续运行
import os
import time
n = 0
while True:
bat_path2 = os.path.abspath(".")
bat = os.listdir(bat_path2)
for i in bat:
if "start.txt" not in bat:
bat_path1 = os.path.abspath(".")
os.system(os.path.join(bat_path1, "devices.bat"))
txt = open("devices.txt").read()
txt_list = txt.split("\n")
txt_list = [x for x in txt_list if x != ""]
n += 1
print("刷新次数:", n)
print("连接设备:", len(txt_list)-1)
if len(txt_list) - 1 > 0:
bat_path1 = os.path.abspath(".")
os.system(os.path.join(bat_path1, "devices_id.bat"))
time.sleep(2)
os.system("cls")
else:
time.sleep(2)
os.system("cls")
if i == "start.txt":
break
break
编程初学者,所写的程序可能有些粗糙,也可能有很多问题。
在此对自己的“成就”进行记录