如何使用 Python 来扩展 adb 命令?

生死看淡,不服就干!

0x00 缘起

作为一个标准的“工程师”,在控制台使用命令才是我们最终的归宿,看起来才更像大牛,当然,这都是题外话。

在进行 Android 开发时,adb 是我们最常使用的命令之一。

举个例子

当你正在调试代码逻辑时,产品同学过来说:“你把你刚发出来的那个提测的 APK 给我装一下呗。”虽然有一万只草尼玛从心中奔腾而过,但还是会屈服于产品的“美貌”,给他安装提测包。接下来,会做什么事情呢:

  1. 将产品同学的手机通过 USB 连接(有时候,你还需要手动去打开 USB 调试);
  2. 找到要安装的 APK 文件;
  3. 使用 adb 命令安装上面步骤中找到的那个 APK。

就在这个时候,你电脑上同时插着多台设备,输入的命令在执行就直接报错了:

error: more than one device/emulator
adb: error: failed to get feature set: more than one device/emulator
- waiting for device -
error: more than one device/emulator

超出了 adb 所支持的设备数,所以,你的步骤变得更非常地复杂。

  1. adb devices 列出你当前的设备列表,然后拷贝你要安装的设备Device Id
  2. 使用 adb -s deviceId install .... 来进行 APK 安装。

这个步骤重复超过 10 次,你还在重复,请仔细阅读下文,本文将教会你如何解放自己的双手,让你有更多的时间做更多的需求,开不开心[手动坏笑]。

0x01 需求分析

上面问题的痛点是:我在执行命令时,不得不去手动拿到“Device Id”,并且手动设置上去。

类似案例分析:在使用 Android Studio Debug 运行 App 的时候,会让你先选择你要安装到的设备,然后才会进行编译、安装、启动页面。

所以,需要优化“Device Id”的获取方式。我们可以使用脚本来获取当前连接在电脑上的设备,并且给出一个输入的入口,让用户选择要执行命令的设备。

0x02 代码实现

在这里,笔者使用 Python 来实现自动获取“Device Id”的功能。

写好脚本,世界会更加美好。

  • 获取设备列表

    Android SDK 中提供的 adb 工具给我们提供了很多功能,获取设备的命令如下:

    adb devices
    

    所以,只需要使用 Python 执行这条 Shell 脚本,并解析脚本输出结果,就可以拿到设备列表。代码逻辑如下:

    def readDevicesList():
    	p=os.popen('adb devices') 
    	devicesList=p.read()
    	p.close()
    	lists = devicesList.split("\n")
    	devicesNames = []
    	for item in lists:
    		if(item.strip() == ""):
    			continue
    		elif(item.startswith("List of")) :
    			continue
    		else:
    			devicesNames.append(item.split("\t")[0])
    	return devicesNames
    

    如上,就可以拿到当前连接在 USB 的设备列表。

  • 让用户选择设备

    从上面拿到了设备列表,让用户输入一个给定的 index,然后去取 index 所对应的 Device Id

    def selectDevices(devicesIds):
    	print "Please Select Devices:"
    	i = 0
    	for deviceId in devicesIds :
    		print "\033[1;34m " + str(i) + ": " + getRealDeviceName(deviceId) + "\033[0m"
    		i += 1
    	print "\033[1;34m e: exit\033[0m"
    	try: 
    		inputIndex = raw_input("Enter your device index [0, " + str(i) + ") :")
    		value = int(inputIndex)
    		if value >= i: 
    			raise Exception("index is to big.")
    		return value
    	except (KeyboardInterrupt, SystemExit) :
    		return -1
    	except Exception as e:
    		if "e" == inputIndex or "E" == inputIndex:
    			return -1
    		else:
    			print "\033[1;31mYour select index is error, please try again.\033[0m"
    			return selectDevices(devicesIds)
    

    在这里,为了有更好的输出结果,我们需要处理 KeyboardInterrupt , SystemExit 的异常事件,遇到这种异常的时候,就直接终止。当然,我们还需要处理用户输入的字符,防止输入非法字符,引起异常。

    执行结果如下图:

    优化前的 adb 执行效果

  • 拼装命令并执行在上面,已经拿到用户要安装的 APK 的 Device Id, 下面我们根据用户的输入命令来生成我们自己的命令。

    def generateShellCommand(deviceId):
    	shellCommand = "adb -s " + deviceId
    	for i in range(1, len(sys.argv)):
    		shellCommand += " " + repr(sys.argv[i])
    	print "execute shell command:"
    	print "  " + shellCommand
    	return shellCommand
    

    拿到生成的新命令,然后执行。

    if __name__ == '__main__':
    	devicesNames = readDevicesList()
    	if len(devicesNames) <= 0: 
    		print "Please connect your devices."
    	elif len(devicesNames) == 1:
    		shellCommand = generateShellCommand(devicesNames[0])
    		execShellCommand(shellCommand)		
    	else :
    		index = selectDevices(devicesNames)
    		if index != -1: 
    			useDeviceName = devicesNames[index]
    			shellCommand = generateShellCommand(useDeviceName)
    			execShellCommand(shellCommand)
    
  • 优化显示设备名称

    在前面获取到的 Device Id 列表,直接展示出来给用户选择,其实不太友好,谁会记得自己手机的 Device Id 呢。是吧。所以我们需要在进行一波操作,将 Device Id 转换成用户可以识别的设备名称。

    def getRealDeviceName(deviceId): 
    	p = os.popen('adb -s ' + deviceId + ' shell getprop ro.product.manufacturer')
    	manufacturer = p.read()
    	p.close()
    	p = os.popen('adb -s ' + deviceId + ' shell getprop ro.product.model')
    	model = p.read()
    	p.close()
    	return manufacturer.strip() + " " + model.strip()
    

    通过 adb 命令去拿到设备的 manufacturermodel 信息。

    优化后的 adb 执行结果

    立竿见影的效果。

0x03 总结

Talk is cheap, show me the code.

有很多功能,我们可以一遍一遍的去写手动执行,但是稍加处理,使用少量脚本就可以处理这些问题。追求效率,释放双手。

传送门

欢迎关注我的公众号,一起交流技术事。

  • 32
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值