python GUI编程(tkinter)基于adb 编写安卓助手

12 篇文章 0 订阅
11 篇文章 1 订阅

源码地址:https://github.com/18713341733/PhoneAssistant

以前编写adb工具都是bat格式的,今天分享一下利用python tkinterGUI编程来写工具。

基于python+adb 编写的安卓助手工具。支持录屏、截图、日志抓取、性能数据查看等功能。目前的功能不是很完善,只是单纯的打个样儿。

这个工具是很久之前用python2写的,虽然有点老,但是可以自己手动改改成python3

链接手机界面:

连接成功后,功能如图:

截屏 录屏界面:

安装APK界面:

monkey界面:

LOG日志抓取界面:

性能数据查看界面:

一些其他功能:

这些功能的实现全部是基于adb命令实现。

具体的实现逻辑等就不讲了,上代码:

目录结构如下:

首先,编写首页,

# -*- coding:utf-8 -*-
#作者:张兴,陈帅
#修改日期:2018.7.7
#修改功能:链接手机时,增加了对是否安装adb的判断
from tkinter import *
from tkinter.messagebox import *
import tkinter as tk
from MainPage import *
import os
import re
import subprocess


class HomePage1(object):
    def __init__(self, master=None):
        self.root = master  # 定义内部变量root
        self.root.geometry('%dx%d' % (300, 180))  # 设置窗口大小
        self.createPage()

    def createPage(self):
        self.page = Frame(self.root)  # 创建Frame
        self.page.pack()
        Button(self.page, text='连接手机',width=12, command=self.loginCheck).grid(row=1, stick=W, pady=10,column=1)
        Button(self.page, text='退出',width=12, command=self.page.quit).grid(row=2, column=1, stick=E)

    def loginCheck(self):
        #点击后去连接手机,连接手机后,对是否连接成功做一些判断,
        # 如何获取控制台的内容,Python2 与Python3 处理是不一样的
        #Python2的处理方式为commands模块,但是Python3中废掉了commands模块,用subprocess代替,详情使用方法访问博客:
        #https://blog.csdn.net/qq_39208536/article/details/80894752
        out = subprocess.getstatusoutput('adb devices -l')
        out1 = subprocess.getstatusoutput('adb devices')
        #out是一个tuple,(0, 'List of devices attached \nc0cfe4a4               device product:PD1515A model:vivo_X6Plus_A device:PD1515A\n')
        #out[0]为状态码,0成功,1失败
        if out[0]==0:#命令成功之后,进行判断
            if 'device product' in out[1]:
                self.page.destroy()
                MainPage(self.root)
                #连接成功返回新的页面
            else:
                self.sayTry()
                #此时命令执行成功,但是手机没有连接上
        else:
            if out1[0]==0:
                if 'device' in out1[1]:
                    self.page.destroy()
                    MainPage(self.root)
                    #连接成功返回新的页面
                else:
                   self.sayTry()
            else:
                self.sayNoadb()#增加了对adb命令执行失败的判断。

    def connectPhone(self):
        self.page.destroy()


    def sayTry(self):
        tk.messagebox.showinfo("Message", "手机连接失败,请尝试重新连接")  # 弹出消息窗口

    def sayFail(self):
        tk.messagebox.showinfo("Message", "手机连接失败,未知错误")  # 弹出消息窗口

    #没有安装adb判断
    def sayNoadb(self):
        tk.messagebox.showinfo("Message", "没有安装adb或者未配置adb环境变量")  # 弹出消息窗口




MainPage.py

from tkinter import *
from view import *  # 菜单栏对应的各个子页面


class MainPage(object):
    def __init__(self, master=None):
        self.root = master  # 定义内部变量root
        self.root.geometry('%dx%d' % (600, 450))  # 设置窗口大小
        self.createPage()

    def createPage(self):
        self.inputPage = InputFrame(self.root)  # 创建不同Frame
        self.installPage=InstallFrame(self.root)
        self.queryPage = QueryFrame(self.root)
        self.countPage = CountFrame(self.root)
        self.aboutPage = AboutFrame(self.root)
        # self.settingPage = SeetingFrame(self.root)
        self.seniorPage = SeniorFrame(self.root)#高级页面
        self.helpPage=HelpFrame(self.root)
        self.inputPage.pack()  # 默认显示基础功能界面
        menubar = Menu(self.root)
        menubar.add_command(label='基础功能', command=self.inputData)
        menubar.add_command(label='安装apk', command=self.installData)
        menubar.add_command(label='monkey', command=self.queryData)
        menubar.add_command(label='log日志', command=self.countData)
        menubar.add_command(label='性能测试', command=self.aboutDisp)
        # menubar.add_command(label='设置', command=self.setting)
        menubar.add_command(label='高级', command=self.senior)
        menubar.add_command(label='帮助', command=self.helpMe)

        self.root['menu'] = menubar  # 设置菜单栏

    def inputData(self):
        self.inputPage.pack()
        self.installPage.pack_forget()
        self.queryPage.pack_forget()
        self.countPage.pack_forget()
        self.aboutPage.pack_forget()
        # self.settingPage.pack_forget()
        self.helpPage.pack_forget()
        self.seniorPage.pack_forget()#不显示高级页面
    def installData(self):
        self.inputPage.pack_forget()
        self.installPage.pack()
        self.queryPage.pack_forget()
        self.countPage.pack_forget()
        self.aboutPage.pack_forget()
        # self.settingPage.pack_forget()
        self.helpPage.pack_forget()
        self.seniorPage.pack_forget()  # 不显示高级页面
    def queryData(self):
        self.inputPage.pack_forget()
        self.queryPage.pack()
        self.countPage.pack_forget()
        self.aboutPage.pack_forget()
        # self.settingPage.pack_forget()
        self.helpPage.pack_forget()
        self.installPage.pack_forget()
        self.seniorPage.pack_forget()  # 不显示高级页面

    def countData(self):
        self.inputPage.pack_forget()
        self.queryPage.pack_forget()
        self.countPage.pack()
        self.aboutPage.pack_forget()
        # self.settingPage.pack_forget()
        self.helpPage.pack_forget()
        self.installPage.pack_forget()
        self.seniorPage.pack_forget()  # 不显示高级页面

    def aboutDisp(self):
        self.inputPage.pack_forget()
        self.queryPage.pack_forget()
        self.countPage.pack_forget()
        self.aboutPage.pack()
        # self.settingPage.pack_forget()
        self.helpPage.pack_forget()
        self.installPage.pack_forget()
        self.seniorPage.pack_forget()  # 不显示高级页面

    # def setting(self):#设置页面
    #     self.inputPage.pack_forget()
    #     self.queryPage.pack_forget()
    #     self.countPage.pack_forget()
    #     self.aboutPage.pack_forget()
    #     self.settingPage.pack()
    #     self.helpPage.pack_forget()
    #     self.installPage.pack_forget()
    #     self.seniorPage.pack_forget()  # 不显示高级页面

    def helpMe(self):#帮助页面
        self.inputPage.pack_forget()
        self.queryPage.pack_forget()
        self.countPage.pack_forget()
        self.aboutPage.pack_forget()
        # self.settingPage.pack_forget()
        self.helpPage.pack()
        self.installPage.pack_forget()
        self.seniorPage.pack_forget()  # 不显示高级页面

    def senior(self):#高级页面
        self.inputPage.pack_forget()
        self.queryPage.pack_forget()
        self.countPage.pack_forget()
        self.aboutPage.pack_forget()
        # self.settingPage.pack_forget()
        self.helpPage.pack_forget()
        self.installPage.pack_forget()
        self.seniorPage.pack()  # 显示高级页面


view.py

from tkinter import *
from tkinter import ttk
from tkinter.messagebox import *
import os
import subprocess
import datetime
import tkinter as tk
import threading
import time
#from PIL import Image, ImageTk
import re
import signal
import tkinter.filedialog
#基础功能
class InputFrame(Frame):  # 继承Frame类
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.root = master  # 定义内部变量root
        self.itemName = StringVar()
        self.importPrice = StringVar()
        self.sellPrice = StringVar()
        self.deductPrice = StringVar()
        self.createPage()
    #基础功能页面展示
    def createPage(self):
        Label(self).grid(row=0, stick=W, pady=10)
        Button(self,text='截屏',width=25,height=5,command=self.screenshot).grid(row=1, stick=W, pady=10)
        # Button(self, text='录像',width=25,height=5,command=self.screenrecord).grid(row=2, stick=W, pady=10)
        self.switchscrBtn = Button(self, text='开始录像', width=25, height=5, command=self.switchscreenrecord)
        self.switchscrBtn.grid(row=2, stick=W, pady=10)

        # Button(self, text='安装APK', width=25, height=5, command=self.screenrecord).grid(row=3, stick=W, pady=10)
    # def screenrecord(self):
    #     Label(self).grid(row=0, stick=W, pady=10)
    #     Label(self, text='开始录屏请点击下方按钮').grid(row=3, stick=W, pady=10)
    #     self.B = Button(self, text='开始', width=12, command=self.switch)
    #     self.B.grid(row=6, stick=E, pady=10)

    def switchscreenrecord(self):

        if self.switchscrBtn['text'] == '开始录像':
            self.switchscrBtn['text'] = '结束录像'
            self.startrecord()

        else:
            self.switchscrBtn['text'] = '开始录像'
            self.endrecord()


    def startrecord(self):
        nowtime = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        self.name1 = nowtime + 'test.mp4'
        out = 'adb shell screenrecord /sdcard/test.mp4'
        self.pro = subprocess.Popen(out, stderr=subprocess.PIPE)
    # 结束进程
    def endrecord(self):
        self.pro.kill()
        out2 = subprocess.getstatusoutput('adb pull /sdcard/test.mp4 .\{}'.format(self.name1))  # .close()是关闭文件的   .kill()是杀掉进程

    #截图函数
    def screenshot(self):
        nowtime=datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        name=nowtime+'.png'
        out = subprocess.getstatusoutput('adb shell screencap -p /sdcard/screen.png')
        out1 = subprocess.getstatusoutput('adb pull /sdcard/screen.png .\{}'.format(name))
        if out[0]==0 and out1[0]==0:
            pass
        else:
            tk.messagebox.showinfo("Message", "未知原因,截图失败")  # 弹出消息窗口




#安装APK
class InstallFrame(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.root = master  # 定义内部变量root
        self.itemName = StringVar()
        self.importPrice = StringVar()
        self.sellPrice = StringVar()
        self.deductPrice = StringVar()
        self.number = StringVar()
        self.createPage()

    def createPage(self):
        Label(self).grid(row=0, stick=W, pady=10)
        Button(self, text='查找安装文件', width=25, height=5, command=self.search).grid(row=1, stick=W, pady=10)
    def search(self):
        default_dir = r"C:\Users\lenovo\Desktop"  # 设置默认打开目录
        self.filename = tkinter.filedialog.askopenfilename(title=u"选择文件",initialdir=(os.path.expanduser(default_dir)),filetypes=[("apk格式", "apk")])
        Label(self,text='路径为:').grid(row=2,stick=W,pady=10)
        Label(self, text=self.filename).grid(row=3, pady=10, stick=W)
        self.B = Button(self, text='开始安装', width=12, command=self.switch)
        self.B.grid(row=6, stick=E, pady=10)

    def switch(self):
        print(self.B)

        if self.B['text'] == '开始安装':
            self.B['text'] = '结束安装'
            self.startinstall()  # 调取安装APK函数

        else:
            self.B['text'] = '开始安装'
            self.endinstall()  # 结束抓取日志函数
    def startinstall(self):
        tk.messagebox.showinfo("Message", "马上开始安装")
        out1=self.filename
        out = 'adb install -r '
        #adb install 为安装  adb install -r为覆盖安装
        out2=out+out1
        self.pro = subprocess.Popen(out2, stderr=subprocess.PIPE)
    def endinstall(self):
        self.pro.kill()

#monkey压测
class QueryFrame(Frame):  # 继承Frame类
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.root = master  # 定义内部变量root
        self.packageName=StringVar()#包名
        self.pressureNum=StringVar()#打压次数
        self.seedNum=StringVar()#标记
        self.logLevel=StringVar()#日志级别
        self.throttle=StringVar()#时间间隔
        self.ignoreCrash=StringVar()#忽略崩溃
        self.ignoreANR=StringVar()#忽略闪退
        self.ignoreTimeout=StringVar()#忽略超时
        self.createPage()

    def createPage(self):
        Label(self).grid(row=0, stick=W, pady=10)
        Label(self, text='包名: ').grid(row=1, stick=W, pady=10)
        Entry(self, textvariable=self.packageName).grid(row=1, column=1, stick=E)
        Label(self, text='压力: ').grid(row=2, stick=W, pady=10)
        Entry(self, textvariable=self.pressureNum).grid(row=2, column=1, stick=E)
        self.press = Entry(self, textvariable=self.pressureNum)
        self.press.insert(10, 1000)
        Label(self, text='标记: ').grid(row=3, stick=W, pady=10)
        Entry(self, textvariable=self.seedNum).grid(row=3, column=1, stick=E)
        self.seed =Entry(self, textvariable=self.seedNum)
        self.seed.insert(10, 1)



        # 创建一个下拉列表
        Label(self, text='日志级别: ').grid(row=4, stick=W, pady=10)
        numberChosen = ttk.Combobox(self, width=12, textvariable=self.logLevel, state='readonly')
        numberChosen['values'] = (1, 2, 3)  # 设置下拉列表的值
        numberChosen.grid(column=1, row=4,stick=E)  # 设置其在界面中出现的位置  column代表列   row 代表行
        numberChosen.current(2)  # 设置下拉列表默认显示的值,1为 numberChosen['values'] 的下标值
        # 创建一个下拉列表,时间间隔throttle
        Label(self, text='throttle').grid(row=5, stick=W, pady=10)
        numberChosen = ttk.Combobox(self, width=12, textvariable=self.throttle, state='readonly')
        numberChosen['values'] = (100,150,200,250,300,350,400)  # 设置下拉列表的值
        numberChosen.grid(column=1, row=5, stick=E)  # 设置其在界面中出现的位置  column代表列   row 代表行
        numberChosen.current(0)  # 设置下拉列表默认显示的值,1为 numberChosen['values'] 的下标值


        Checkbutton(self,text='忽略崩溃',onvalue=1,offvalue=0,variable =self.ignoreCrash).grid(row=6, column=1, stick=E)
        #offvalue  #设置Off的值=0
        #onvalue   #设置on的值=1


        Checkbutton(self, text='忽略超时',onvalue=1,offvalue=0,variable =self.ignoreTimeout).grid(row=7, column=1, stick=E)
        self.startBtn=Button(self, text='开始压测',command=self.switch)
        self.startBtn.grid(row=8, column=5, stick=E, pady=5)

        Button(self, text='报告分析').grid(row=9, column=5, stick=E, pady=5)
        # 制作中

    # 开始与结束之间的切换
    def switch(self):

        if self.startBtn['text'] == '开始压测':
            self.startBtn['text'] = '强行终止'
            self.monkey()  # 开始跑monkey

        else:
            self.startBtn['text'] = '开始压测'
            self.killPro()  # 结束monkey



    def monkey(self):
        packageName=self.packageName.get()   # 包名
        print('包名{}'.format(packageName))
        pressureNum=int(self.pressureNum.get()) # 打压次数
        print('打压次数:{}'.format(pressureNum))
        seedNum=int(self.seedNum.get())   # 标记
        print('标记:{}'.format(seedNum))
        logLevel=int(self.logLevel.get()) # 日志级别
        print('日志级别:{}'.format(logLevel))
        ignoreCrash=self.ignoreCrash.get()
        print('忽略崩溃:{}'.format(ignoreCrash))
        ignoreTimeout=self.ignoreTimeout.get()
        throttle=int(self.throttle.get())
        print('时间间隔:{}'.format(throttle))

        print('忽略超时:{}'.format(ignoreTimeout))


        nowtime = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        filename = 'Monkey'+nowtime + ".txt"
        logcat_file = open(filename, 'w')
        logcmd = r'adb shell monkey -p {} -s {} -v -v -v --throttle {} --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --monitor-native-crashes {}'.format(packageName,seedNum,throttle,pressureNum)
        self.pro = subprocess.Popen(logcmd, stdout=logcat_file, stderr=subprocess.PIPE)
    # 结束进程
    def some_adb_cmd(self):
        p = subprocess.Popen('adb shell cd sdcard && cd Android && cd data && ps |grep monkey',stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        return_code = p.poll()
        while return_code is None:
            line = p.stdout.readline()
            return_code = p.poll()
            line = line.strip()
            line1=str(line,"utf-8")
            pattern = re.compile(r'[^\d]+(\d+)[^\d]+')
            res = re.findall(pattern, line1)
            #os.kill(int(res), signal.SIGKILL)
            res1=res[0]
            a='adb shell cd sdcard && cd Android && cd data'
            a1='kill '+res1
            a2=a+" && "+a1
            p1 = subprocess.Popen(a2,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            break

    def killPro(self):

        self.some_adb_cmd()


#log日志
class CountFrame(Frame):  # 继承Frame类
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.root = master  # 定义内部变量root
        self.filterTag=StringVar()  # 过滤标签
        self.filterStr=StringVar()  # 过滤字符串
        self.filterRegular=StringVar()  # 正则过滤
        self.logLevel = StringVar()  # 日志级别
        self.filterFormat=StringVar()#过滤项格式
        self.createPage()

    def createPage(self):
        #Label(self, text='过滤标签: ').grid(row=1, stick=W, pady=10)

        #entry=Entry(self, textvariable=self.filterTag).grid(row=1, column=1, stick=E)
        Label(self, text='过滤字符串: ').grid(row=2, stick=W, pady=10)
        Entry(self, textvariable=self.filterStr).grid(row=2, column=1, stick=E)
        #Label(self, text='正则过滤: ').grid(row=3, stick=W, pady=10)
        #Entry(self, textvariable=self.filterRegular).grid(row=3, column=1, stick=E)
        #日志级别############################################################
        # 创建一个下拉列表
       # Label(self, text='日志级别: ').grid(row=4, stick=W, pady=10)
       # Label(self).grid(row=0, stick=W, pady=10)
        #numberChosen = ttk.Combobox(self, width=12, textvariable=self.logLevel, state='readonly')
       # numberChosen['values'] = (1, 2, 3)  # 设置下拉列表的值
       # numberChosen.grid(column=1, row=4, stick=E)  # 设置其在界面中出现的位置  column代表列   row 代表行
       # numberChosen.current(1)  # 设置下拉列表默认显示的值,1为 numberChosen['values'] 的下标值
        #过滤格式############################################################
        Label(self, text='过滤项格式: ').grid(row=5, stick=W, pady=10)
        Label(self).grid(row=0, stick=W, pady=10)
        filterFormat = ttk.Combobox(self, width=12, textvariable=self.filterFormat, state='readonly')
        #-- V : Verbose (明细);
        #-- D : Debug (调试);
        #-- I : Info (信息);
        #-- W : Warn (警告);
        #-- E : Error (错误);
        #-- F : Fatal (严重错误);
        filterFormat['values'] = ('Verbose','Debug','Warn','Error','Fatal')  # 设置下拉列表的值
        filterFormat.grid(column=1, row=5, stick=E)  # 设置其在界面中出现的位置  column代表列   row 代表行
        filterFormat.current(1)  # 设置下拉列表默认显示的值,1为 numberChosen['values'] 的下标值
        # Button(self, text='开始', width=12,command=self.switch).grid(row=6, stick=E, pady=10)
        self.B=Button(self, text='开始', width=12,command=self.switch)
        self.B.grid(row=6, stick=E, pady=10)

    # 开始与结束之间的切换
    def switch(self):
        print(self.B)

        if self.B['text'] == '开始':
            self.B['text'] = '结束'
            self.logCat()#调取抓取日志函数


        else:
            self.B['text'] = '开始'
            self.killPro()#结束抓取日志函数

    #def filterLog(self):
    def logCat(self):
        #packageName = self.packageName.get()  # 包名
        #print('包名{}'.format(packageName))

        #过滤标签
       # filterTag=self.filterTag.get()
       # print('过滤标签:{}'.format(filterTag))
       # print('过滤字符串:{}'.format(self.filterStr.get()))
        #过滤字符串
        filterStr=self.filterStr.get()
        print('过滤字符串:{}'.format(filterStr))
        #正则过滤
       # filterRegular=self.filterRegular.get()

       # print('正则过滤:{}'.format(filterRegular))
        #日志级别
       # logLevel=self.logLevel.get()
       # print('日志级别:{}'.format(logLevel))
        #过滤格式项
        filterFormat=self.filterFormat.get()
        print('过滤格式项:{}'.format(filterFormat))


    #抓取日志
    #def logCat(self):
        nowtime = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        filename = nowtime + ".txt"
        logcat_file = open(filename, 'w')
        #logcmd = r'adb shell monkey -p {} -s {} -v -v -v --throttle {} --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --monitor-native-crashes {}'.format(
         #   packageName, seedNum
       # p = subprocess.Popen('adb shell cd sdcard && cd Android && cd data && ps |grep monkey', stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        if filterFormat!='' and filterStr!='':
            logcmd = r'adb shell cd sdcard && cd Android && cd data &&  logcat *:{} | grep {}'.format(filterFormat,filterStr)
        elif filterFormat!='' and filterStr=='':
            logcmd = r'adb shell cd sdcard && cd Android && cd data &&  logcat *:{}'.format(filterFormat)
        elif filterFormat=='' and filterStr !='':
            logcmd = r'adb shell cd sdcard && cd Android && cd data &&  logcat | grep {}'.format(filterStr)
        else:
            logcmd = 'adb logcat -v time'
        #logcmd = 'adb logcat -v time'
        self.pro = subprocess.Popen(logcmd, stdout=logcat_file, stderr=subprocess.PIPE)
    #结束进程
    def killPro(self):
        self.pro.kill() # .close()是关闭文件的   .kill()是杀掉进程








#性能测试界面
class AboutFrame(Frame):  # 继承Frame类
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.root = master  # 定义内部变量root
        self.createPage()


    def createPage(self):

        Button(self, text='内存监测', width=12, command=self.getMemory).grid(row=1, stick=E, pady=10, column=1)
        # Button(self, text='手机CPU监测', width=12, command=self.allCpu).grid(row=2, stick=E, pady=10, column=1)
        Button(self, text='当前应用CPU', width=12, command=self.myCpu).grid(row=2, stick=E, pady=10, column=1)
        Button(self, text='电量信息', width=12, command=self.charge).grid(row=3, stick=E, pady=10, column=1)
        Button(self, text='启动时间', width=12, command=self.startTime).grid(row=4, stick=E, pady=10, column=1)



    #电量信息
    def charge(self):
        print('电量信息')
        out = subprocess.getstatusoutput('adb shell dumpsys battery')
        top = tk.Toplevel()
        top.title('电量信息')

        top.geometry('%dx%d' % (600, 600))  # 设置窗口大小
        t = Text(top, width=600, height=600)
        t.insert('1.0', "{}".format(out[1]))
        t.pack()
        top.mainloop()

    #内存数据获取
    def getMemory(self):
        import re
        out = subprocess.getstatusoutput('adb shell dumpsys window | findstr mCurrentFocus ')
        str1 =out[1]
        pattern = re.compile(r'u0\s*(.+?)\/')
        res = re.findall(pattern, str1)
        self.package=res[0]#获取当前应用的包名

        nowtime = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        # filename = "startime"+nowtime+".txt"
        filename = "startime" + nowtime + ".xls"
        startime_file = open(filename, 'w')
        order = "adb shell dumpsys meminfo {}".format(self.package)  # 获取内存的命令
        self.pro = subprocess.Popen(order, stdout=startime_file, stderr=subprocess.PIPE)

    #手机内当前前十位的应用cpu占用动态监测
    def allCpu(self):
        top = tk.Toplevel()
        top.title('内存监测')

        top.geometry('%dx%d' % (700, 1400))  # 设置窗口大小
        #Text文本框的定义和输出
        t = Text(top, width=700, height=100)
        t.pack(fill=tkinter.X, side=tkinter.BOTTOM)
        top.mainloop()
        # out = subprocess.getstatusoutput('adb shell&&top -m 10 -s cpu')
        logcmd='adb shell&&top -m 10 -s cpu'
        out=subprocess.Popen(logcmd,stderr=subprocess.PIPE)
        t.insert(tkinter.END,"{}".format(out[1]))
        t.see(tkinter.END)
        t.update()

    #当前应用占用CPU显示
    def myCpu(self):
        import re
        out = subprocess.getstatusoutput('adb shell dumpsys window | findstr mCurrentFocus ')
        str1 = out[1]
        pattern = re.compile(r'u0\s*(.+?)\/')
        res = re.findall(pattern, str1)
        self.packageName = res[0]  # 获取当前应用的包名
        out = subprocess.getstatusoutput('adb shell dumpsys cpuinfo | find "{}"'.format(self.packageName))
        top = tk.Toplevel()
        top.title('当前应用')

        top.geometry('%dx%d' % (300, 100))  # 设置窗口大小
        t = Text(top, width=300, height=100)
        t.insert('1.0', "{}".format(out[1]))
        t.pack()
        top.mainloop()

    def startTime(self):
        pass









#设置页面
class SeetingFrame(Frame):  # 继承Frame类
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.root = master  # 定义内部变量root
        self.createPage()

    def createPage(self):
        Label(self, text='设置开发中').pack()

#高级页面
class SeniorFrame(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.root = master  # 定义内部变量root
        self.createPage()

    def createPage(self):
        # 查看手机上已经安装的所有的包名列表
        Label(self, text='当前应用包名: ').grid(row=1, stick=W, pady=10)
        Button(self, text='当前应用', width=12, command=self.currentPackage).grid(row=1, stick=E, pady=10, column=1)


        #查看手机上已经安装的所有的包名列表
        Label(self, text='包名列表: ').grid(row=2,stick=W, pady=10)
        Button(self, text='包名列表', width=12, command=self.listPackage).grid(row=2, stick=E, pady=10,column=1)
        # 查看当前手机屏幕分辨率
        Label(self, text='设备分辨率: ').grid(row=3, stick=W, pady=10)
        Button(self, text='分辨率', width=12, command=self.resolution).grid(row=3, stick=E, pady=10, column=1)
        #查看手机系统版本
        Label(self, text='当前手机版本: ').grid(row=4, stick=W, pady=10)
        Button(self, text='手机版本', width=12, command=self.systemversion).grid(row=4, stick=E, pady=10, column=1)
        Label(self, text='手机设备id: ').grid(row=5, stick=W, pady=10)
        Button(self, text='设备id', width=12, command=self.deviceid).grid(row=5, stick=E, pady=10, column=1)

    #当前应用的包名及activity
    def currentPackage(self):
        out =subprocess.getstatusoutput('adb shell dumpsys window | findstr mCurrentFocus ')
        top = tk.Toplevel()
        top.title('当前应用')

        top.geometry('%dx%d' % (700,100))  # 设置窗口大小
        t = Text(top, width=700, height=100)
        t.insert('1.0', "{}".format(out[1]))
        t.pack()
        top.mainloop()

    #所有的包名列表
    def listPackage(self):
        nowtime = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        filename = 'package'+nowtime + ".txt"
        logcat_file = open(filename, 'w')
        logcmd = 'adb shell pm list packages'
        self.pro = subprocess.Popen(logcmd, stdout=logcat_file, stderr=subprocess.PIPE)
        out = subprocess.getstatusoutput('adb shell pm list packages')


        top = tk.Toplevel()
        top.title('包名列表')

        top.geometry('%dx%d' % (400, 1200))  # 设置窗口大小

        t=Text(top,width=400,height=900)
        t.insert('1.0',"{}".format(out[1]))
        #插入文本,用引号引起来“1.0” 这个是插入文本的坐标,且1与0之间为点,而不是逗号,切记


        #wraplength: 指定多少单位后开始换行
        #justify:  指定多行的对齐方式
        #例子: Label(top, text='查看当前手机上所有包名: ',wraplength = 80,justify = 'left').grid(row=1,stick=W, pady=10)
        t.pack()
        top.mainloop()

    # 当前应用的包名及activity
    def resolution(self):
        out = subprocess.getstatusoutput('adb shell wm size')
        top = tk.Toplevel()
        top.title('分辨率')

        top.geometry('%dx%d' % (300, 100))  # 设置窗口大小
        t = Text(top, width=300, height=100)
        t.insert('1.0', "{}".format(out[1]))
        t.pack()
        top.mainloop()

    def systemversion(self):
        out = subprocess.getstatusoutput('adb shell getprop ro.build.version.release')
        top = tk.Toplevel()
        top.title('手机系统版本')

        top.geometry('%dx%d' % (300, 100))  # 设置窗口大小
        t = Text(top, width=300, height=100)
        t.insert('1.0', "{}".format(out[1]))
        t.pack()
        top.mainloop()
    def deviceid(self):
        out = subprocess.getstatusoutput('adb get-serialno')
        top = tk.Toplevel()
        top.title('手机设备id')

        top.geometry('%dx%d' % (600, 100))  # 设置窗口大小
        t = Text(top, width=600, height=100)
        t.insert('1.0', "{}".format(out[1]))
        t.pack()
        top.mainloop()








#帮助页面
class HelpFrame(Frame):  # 继承Frame类
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.root = master  # 定义内部变量root
        self.createPage()

    def createPage(self):
        a='''如有疑问,请联系...'''
        b='''Python2的处理方式为commands模块,但是Python3中废掉了commands模块,用subprocess代替'''
        c='''详情使用方法访问博客:'''
        d='''#https://blog.csdn.net/qq_39208536/article/details/80894752'''
        Label(self, text=a).grid(row=1, stick=W, pady=10)
        # Label(self, text=b).grid(row=2, stick=W, pady=10)
        # Label(self, text=c).grid(row=3, stick=W, pady=10)
        # Label(self, text=d).grid(row=4, stick=W, pady=10)




最后是main.py

from tkinter import *
from HomePage1 import *
# from icon import img
# import base64

root = Tk()
root.title('安卓助手')



HomePage1(root)
root.mainloop()

具体细节就不讲了,很简单。大家一定都会的

最后十分感谢张兴老师的努力。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

做测试的喵酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值