【Andriod】使用adb命令安装和卸载apk的通用python脚本

1.前言

如不会使用adb请看之前的文章
【Andriod】adb调试安卓手机时连接真机或模拟器的3种方法,你知道么?

2.连接设备

import os  # python标准库中的os模块

"""
使用python编写脚本对app完成自动启动的操作
"""


class AdbConnect:
    #如果配置了环境变量这里可以为空,我没有配置所以得从根目如调用adb
    ANDROID_SDB_ABS_PATH = "F:\dev_tools\\android-sdk_r24.4.1-windows\\android-sdk-windows\platform-tools\\"

    # 构造函数
    def __init__(self, device_name):
        # 初始化时,传入的device_name表示模拟器的名称(USB连接传设备编号,模拟器传ip端口)
        self.device_name = device_name

    # 连接设备
    def adb_connect(self):
        # (1)popen和system方法都可以执行指令,popen可以接受返回对象,此处要查看连接设备的列表,把查询到的连接设备结果保存在变量device_list中
        device = os.popen(self.ANDROID_SDB_ABS_PATH + "adb devices")
        device_list = device.read()
        print("连接设备列表1:\n{}".format(device_list))

        # (2)判断设备名称是否在连接设备列表中,如果不在就调用连接设备的方法,再查询连接状态是否成功,如果在就直接查询连接设备和状态
        # 判断连接设备的名称是否在连接设备列表中
        if self.device_name not in device_list:
            self.connection_equipment()  # 调用连接设备的方法
            # print(self.query_device_list())
            return self.query_device_list()  # 查询连接设备和状态
        else:
            # print(self.query_device_list())
            return self.query_device_list()  # 查询连接设备和状态

    # 查询连接设备的列表(可根据连接设备名称查询连接设备的状态)
    def query_device_list(self):
        device = os.popen(self.ANDROID_SDB_ABS_PATH + "adb devices")
        # popen与system可以执行指令,popen可以接受返回对象

        device_list = device.read()
        # 读取adb devices返回的结果

        print("连接设备列表2:\n{}".format(device_list))
        # 打印连接设备列表

        con_attached_list = device_list[device_list.rfind(self.device_name):-2]
        # 从连接设备列表截取连接设备的名称到连接状态这部分的字符串,连接设备列表的字符串最后两行是空所以取-2
        # print(con_attached_list)# FJH7N19131000457	device

        dve_len = len(self.device_name)
        # 计算连接设备的长度dve_len,根据此长度来确定截取连接状态的位置
        # print(dve_len) # 16

        dve_ps = con_attached_list.rfind(self.device_name)
        # 取出连接设备在连接设备列表的起始位置dve_ps
        # print(dve_ps) # 0

        con_attached = con_attached_list[dve_ps + dve_len + 1:dve_ps + dve_len + 7]
        # 截取连接设备的连接状态,从起始位置dve_ps加上连接设备长度dve_len+1(设备名称到状态之间有空格所有+1)
        # 从状态开始的位置往后截取6个字符:dve_ps + dve_len + 7,后面只需判断这部分截取的结果是否是device
        #print(con_attached)# device

        if self.device_name in con_attached_list and con_attached == 'device':
        
            # 判断连接设备的名称是否在连接设备列表,且状态是否为device
            return "adb已连接上设备{}".format(self.device_name)
        elif self.device_name in con_attached_list and con_attached != 'device':
            return "连接设备的状态异常\n{}".format(con_attached_list)
        elif self.device_name not in con_attached_list:
            return "未连接该设备,请检查"
        else:
            return "未知错误"

    def connection_equipment(self):
        os.system("adb connect {}".format(self.device_name))
        # 使用adb connect 连接设备


if __name__ == '__main__':
    a = AdbConnect("FJH7N19131000457")
    s = a.adb_connect()
    print(s)

执行结果
在这里插入图片描述

3.从本机通过adb安装apk

import os
from adb_connect import AdbConnect


class AppInstall:

    def __init__(self, device_name, apk_path, method=''):
        self.apk_path = apk_path  # apk的路径
        self.install_method = method  # 安装的app方法,常规安装(默认)、R(覆盖安装)、D(降级安装)
        self.device = device_name  # 设备的名称(USB连接传设备编号,模拟器传ip端口)

    def app_install(self):  # 安装的方法
        adb_cont = AdbConnect(self.device) # 初始化adb连接的类,传入设备名称
        device_status = adb_cont.adb_connect()  # 调用adb连接类的方法连接设备

        if "已连接上设备" in device_status:  # 如果已连接设备则执行下面的安装app步骤
            print(device_status)  # 打印连接设备的列表
            try:
                if self.install_method == '':  # 判断是否传入的安装方法为空
                    self.app_direct_install()  # 调用常规安装app的方法
                elif self.install_method == 'R':  # 传入了R参数,表示覆盖安装
                    self.app_replace_install()  # 调用覆盖安装的方法
                elif self.app_downgrade_install() == 'D':  # 传入了D参数,表示降级安装
                    self.app_downgrade_install()  # 调用降级安装的方法
                else:
                    pass
            except Exception as e:  # 如果有错误则打印错误
                print(e)
        else:
            print(device_status)  # 如果不是已连接设备,则打印连接设备列表

    def app_direct_install(self):  # 常规安装app的方法
        install = os.popen(
            AdbConnect.ANDROID_SDB_ABS_PATH + "adb install {}".format(self.apk_path))  # 执行adb install命令常规安装
        install_re = install.read()  # 把安装的结果赋值给变量install_re
        if 'Success' in install_re[-9:-1]:  # 判断安装结果的部分包含Success
            return print("app已成功安装")  # 打印app已安装成功
        else:
            return print("app未成功安装,安装结果:{}\n覆盖或降级安装需要在初始化时添加安装附加参数:R(覆盖安装)、D(降级安装)".format(install_re[-41:-2]))

    def app_replace_install(self):  # 覆盖安装的方法
        install = os.popen(
            AdbConnect.ANDROID_SDB_ABS_PATH + "adb install -r {}".format(self.apk_path))  # 执行adb install -r命令覆盖安装
        install_re = install.read()
        if 'Success' in install_re[-9:-1]:
            return print("app已成功安装")
        else:
            return print("app未成功安装,安装结果:{}\n覆盖或降级安装需要在初始化时添加安装附加参数:R(覆盖安装)、D(降级安装)".format(install_re[-41:-2]))

    def app_downgrade_install(self):  # 降级安装的方法
        install = os.popen(
            AdbConnect.ANDROID_SDB_ABS_PATH + "adb install -r -d {}".format(self.apk_path))  # 执行adb install -r -d命令降级安装
        install_re = install.read()
        if 'Success' in install_re[-9:-1]:
            return print("app已成功安装")
        else:
            return print("app未成功安装,安装结果:{}\n覆盖或降级安装需要在初始化时添加安装附加参数:R(覆盖安装)、D(降级安装)".format(install_re[-41:-2]))


if __name__ == '__main__':
    # a = AppInstall(r"D:\ac\APP\tools\yibijizhang.apk", "127.0.0.1:62001", method="R")
    # a.app_install()

    #b = AppInstall("127.0.0.1:62001", r"D:\download\meituan10.10.403.apk")
    #b.app_install()

    c = AppInstall("FJH7N19131000457", r"F:\my_tools\DigiFinex_V2023.10.12_debugT.apk","R")
    c.app_install()

执行结果
在这里插入图片描述

4.从本机通过adb卸载apk

import os
from adb_connect import AdbConnect



class AppUninstall:
    def __init__(self, device_name):
        self.device = device_name  # 设备的名称(USB连接传设备编号,模拟器传ip端口)
        con = AdbConnect(self.device)  # 实例化连接设备的类
        con.adb_connect()  # 调用连接设备的方法

    def app_uninstall(self):
        app_pack_list = self.app_packages_three()  # 调用查询第三方包名的方法,得到包含所有第三方安装包名的列表
        if app_pack_list:  # 判断第三方安装包名的列表不为空
            print("安装的app包名列表:\n{}".format(app_pack_list))  # 打印第三方安装包名列表
            uninstall_app_pack = input("请输入要删除app的包名:")  # 输入要删除的包名
            if uninstall_app_pack in app_pack_list:  # 判断输入要删除的包名在查询出来的结果中
                un_re = os.popen(AdbConnect.ANDROID_SDB_ABS_PATH + "adb uninstall {}".format(
                    uninstall_app_pack))  # 使用adb uninstall <包名>命令卸载app
                uninstall_re = un_re.read()  # 读取卸载的结果
                uninstall_result = uninstall_re[:7]  # 截取卸载结果的前7位字母
                if uninstall_result == 'Success':  # 判断卸载结果的7位字母为Success
                    print("app卸载成功")  # 打印app卸载成功
                else:
                    print("未知错误")  # 打印未知错误
            else:
                print("您输入的包名不存在,请检查!")  # 如果输入的包名不存在包名列表中则提示
        else:
            print("未查询到第三方安装的app")  # 如果第三方安装包名列表为空则提示

    def app_packages_three(self):
        packages = os.popen(AdbConnect.ANDROID_SDB_ABS_PATH + "adb shell pm list packages -3")  # adb命令查询第三方安装的包名
        app_packages = packages.read()  # 读取第三方安装的app包名
        print(app_packages)

        app_pack_str = app_packages.replace('\n', '')  # 读取结果把换行符\n替换为空,删除换行符
        app_pack_list = app_pack_str.split("package:")  # 使用split方法切片,得到包名的一个列表
        print(app_pack_list)

        app_pack_list.pop(0)  # 使用列表的pop方法删除包名列表中的第一个数据
        return app_pack_list  # 返回包名列表


if __name__ == '__main__':
    a = AppUninstall("FJH7N19131000457")
    a.app_uninstall()

执行结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq877728715/article/details/134055455