赞
踩
源码地址: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()
具体细节就不讲了,很简单。大家一定都会的
最后十分感谢张兴老师的努力。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。