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

news2024/12/23 10:38:07

文章目录

  • 1.前言
  • 2.连接设备
  • 3.从本机通过adb安装apk
  • 4.从本机通过adb卸载apk

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()

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

互动直播UI设置 之 主播UI

目录 一、普通模式下&#xff0c;布局选项 1、布局按钮 1&#xff09;、点击布局按钮 2&#xff09;、选择哪种布局后&#xff0c;主进程通过WM_COPYDATA 发送信息 2、duilib样式布局文件 1&#xff09;、主画面 2&#xff09;、连麦者画面 3、主画面自动调整宽度 1&a…

UnrealSynth - 基于虚幻引擎的YOLO合成数据生成器

UnrealSynth虚幻合成数据生成器利用虚幻引擎的实时渲染能力搭建逼真的三维场景&#xff0c;为YOLO等AI模型的训练提供自动生成的图像和标注数据&#xff0c;官方下载地址&#xff1a;UnrealSynth虚幻合成数据生成器。 UnrealSynth生成的合成数据可用于深度学习模型的训练和验证…

18.3 NPCAP 构建中间人攻击

ARP欺骗&#xff08;ARP Spoofing&#xff09;是一种网络攻击手段&#xff0c;其目的是通过欺骗目标主机来实现网络攻击。ARP协议是一种用于获取MAC地址的协议&#xff0c;因此欺骗者可以使用ARP欺骗来迫使其目标主机将网络流量发送到攻击者控制的设备上&#xff0c;从而实现网…

error LNK2019: 无法解析的外部符号

文章目录 1 问题2 出现该问题的原因和解决方法2.1 原因&#xff1a;2.3 解决方法&#xff1a;需要查看一下项目的属性配置是否正确&#xff1a; 3 其他可能得原因&#xff0c;但是本项目中没有出现 1 问题 在测试base64代码的时候&#xff0c;VS2022提示我错误如下&#xff1a…

Julia数值计算初步

文章目录 复数系统运算符三角函数指数、对数、取整 Julia系列&#xff1a;编程初步&#x1f525;数组 Julia作为主打数值计算的编程语言&#xff0c;对一些常用的计算函数提供了非常细致的支持&#xff0c;十分人性化&#xff0c;体验之后爱不释手。 复数系统 在Juli中&…

笔记本怎么录屏?这3个方法请你收好

在现代教育、工作和演示中&#xff0c;屏幕录制成为了无可替代的工具。它使我们能够捕捉电脑屏幕上的一切&#xff0c;从PPT演示到教程制作&#xff0c;再到技术支持。因此&#xff0c;选择合适的录屏工具显得尤为重要。本文将详细介绍笔记本怎么录屏的3个方法&#xff0c;这些…

软件绘制 硬件加速绘制 【DisplayList RenderNode】

Android4.0以后&#xff0c;系统默认开启硬件加速来渲染视图 异同点 共同点 两者都是从SF获取一块内存&#xff0c;绘制都是在APP端&#xff0c;绘制好后都是通知SF去进行合成图层 真正的区别 真正的区别&#xff1a;绘制是通过CPU还是GPU完成的视图绘制。 对应区别在代码中的体…

SpringBoot整合Gateway 的Demo(附源码)

源码&#xff0c;可直接下载 Gateway模块 Gateway 的父pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sc…

学习嵌入式可以胜任哪一些行业?

今日话题&#xff0c;学习嵌入式可以胜任哪一些行业&#xff1f;学习嵌入式开发可以胜任许多行业&#xff0c;因为嵌入式技术在各个领域都有广泛的应用。嵌入式系统用于医疗设备、患者监测系统、药物分发设备等。智能手机、智能家居设备、游戏机等消费电子产品都包含嵌入式系统…

RocketMQ mmap原理和使用

传统文件IO 普通的IO操作的一个弊端&#xff0c;必然涉及到两次数据拷贝操作&#xff0c;对磁盘读写性能是有影响的。 那么如果我们要将一些数据写入到磁盘文件里去呢&#xff1f; 那这个就是一样的过程了&#xff0c;必须先把数据写入到用户进程空间里去&#xff0c;然后从这里…

网络时代下的声音之路:如何在中央新闻媒体发布网评稿

在当今数字时代&#xff0c;信息传播已经变得更加便捷和广泛。各大中央新闻媒体平台为民众提供了一个发布观点、表达意见的平台。在这个背景下&#xff0c;撰写并发布网评稿成为了一种重要的社会参与方式。根据媒介易软文发稿平台的总结&#xff0c;下面是探讨如何在各大中央新…

基于单片机的IC卡门禁系统设计

收藏和点赞&#xff0c;您的关注是我创作的动力 文章目录 概要 一、主要研究内容及总体设计方案1.1 系统方案设计1.2系统工作原理 二、硬件设计2.1 主控电路 三、软件设计3.2主程序设计实物附录1 原理图附录2 源程序清单 四、 结论五、 文章目录 概要 本论文重点通过对射频技术…

电脑上怎么录制视频教程带画笔工具?

无论你是创建教程、还是演示文稿&#xff0c;可能都希望使用带有画笔工具的录屏软件来帮助你创建吸引观众注意力的重要内容。幸运的是&#xff0c;有一些很棒的录屏软件可供你选择&#xff0c;本文就为你推荐一款带有画笔工具的最佳录屏软件&#xff0c;继续阅读查看吧&#xf…

明基、书客、小米的护眼台灯谁的更值得入手?三款台灯真实测评!

目前中国青少年近视占比是越来越高了&#xff0c;尤其是初中生更是重灾区。而现在看来小学阶段近视风险也有上升的趋势。所以&#xff0c;孩子在正式步入小学时&#xff0c;学习桌上不可或缺的就要放上一台好的且不错的护眼台灯。不过如今市面上的护眼台灯种类多到让人眼花缭乱…

Maven第三章:IDEA集成与常见问题

Maven第三章:IDEA集成与常见问题 前言 本章内容重点:了解如何将Maven集成到IDE(如IntelliJ IDEA或Eclipse)中,以及使用过程中遇到的常见的问题、如何解决,如何避免等,可以大大提高开发效率。 IEAD导入Maven项目 File ->Open 选择上一章创建的Maven项目 my-app查看po…

echarts多y轴优化方案

优化方向&#xff1a;点击图例&#xff0c;对y轴进行屏蔽&#xff0c;自动计算y轴位置 效果如下&#xff1a; 对应实现思路&#xff1a;通过监听图例点击事件&#xff0c;渲染y轴显示隐藏和y轴对应位置。 <script setup lang"ts"> import { onMounted, ref,…

简述JVM

文章目录 JVM简介JVM运行时数据区堆(线程共享)方法区/元空间/元数据区(线程共享)栈程序计数器 JVM类加载类加载过程双亲委派模型 垃圾回收机制(GC)判断对象是否为垃圾判断是否被引用指向 如何清理垃圾, 释放对象? JVM简介 JVM 是 Java Virtual Machine 的简称, 意为Java虚拟机…

代码随想录打卡第五十二天|123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III 题目&#xff1a; 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成两笔交易。注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购买前出售掉之…

iPhone无法连接电脑?怎么回事?解决方法来了!

苹果用户将手机和电脑连接后&#xff0c;可以轻松实现两者之间的数据传输。但是&#xff0c;在连接设备的过程中可能会出现没有任何反应的情况。这是怎么回事&#xff1f;本文将为大家介绍解决iPhone无法连接电脑的常见方法。如果您的iphone无法连接电脑&#xff0c;请尝试以下…

导入Embassy库进行爬虫

Embassy是一个基于Lua的轻量级爬虫框架&#xff0c;可以方便地进行网页抓取和数据提取。它提供了简单易用的接口和丰富的功能&#xff0c;可以帮助开发者快速构建爬虫应用。 要使用Embassy进行爬虫&#xff0c;首先需要安装Embassy库。可以通过Lua的包管理工具luarocks来安装E…