【Python】基于ADB和thinker的Android宏录制工具

想法:现在很多手游都太肝,作为科研狗没那么多空闲时间,想找个方法自动化代肝,首先想到的肯定是ADB,但是ADB还需要一个一个调试触点的坐标,太麻烦了,于是一直想找个可视化的方法

思路:

1,使用ADB的截图功能获取当前屏幕

2,使用thinker绘制图形界面,显示屏幕截图

3,使用thinker抓取鼠标点击和拖动的事件并记录下坐标

4,使用ADB命令将记录好的行为重新播放出来

遇到的问题:

1,本来想直接在Android系统上进行操作,在电脑端使用adb shell getevent直接获取十六进制格式的事件,然后再用adb shell sendevent命令发送回去,但是报错显示权限不足,查了一下似乎是新版本的Android禁止了ADB直接将事件发送至Android端,只能使用adb shell input命令模拟按键执行

2,坐标问题,ADB中,事件的坐标并不是直接对应于手机屏幕的物理位置的,而是对应着屏幕旋转后的显示方向,左上角为(0,0),同时,截图生成的图像也满足这个规律

3,分辨率问题:手机的分辨率比电脑还高(lll¬ω¬),需要进行缩放,缩放后获取的坐标要再缩放回去

4,延时问题:截图从手机上传输到电脑上需要时间,如果不等传输完成就读取图片会直接报错,这时候只能在截图完成后sleep等待传输完成,由此产生的时延使得录制宏的过程中记录时间失去了意义,不过ADB模拟按键本来就时延挺长的么,所以只要在一些关键位置,比如加载阶段,手动加个timeout命令就行了

效果图:

 

代码:

#recorder.py
import tkinter as tk
from PIL import Image,ImageTk
import os
import time

from matplotlib.pyplot import title

scale=0.25
imagefilename = '1.png'
recordfilename= "record.txt"
file=open(recordfilename,"w",buffering=1)
global lastdist
def RefreshImage():
    os.system("adb shell screencap -p /sdcard/"+imagefilename)
    os.system("adb pull /sdcard/"+imagefilename)
    os.system("adb shell rm /sdcard/"+imagefilename)
    time.sleep(0.5)

    img = Image.open(imagefilename)
    img=img.resize((int(img.size[0]*scale),int(img.size[1]*scale)))
    photo = ImageTk.PhotoImage(img)
    return photo

def PressCallBack(event): 
    dist=[int(event.x/scale),int(event.y/scale)]
    #print("当前位置:",dist[0],dist[1])
    global lastdist
    lastdist=dist
    

def ReleaseCallBack(event):
    dist=[int(event.x/scale),int(event.y/scale)]
    global lastdist
    if(lastdist[0]==dist[0] and lastdist[1]==dist[1]):
    #print(event)
        os.system("adb shell input tap "+str(dist[0])+" "+str(dist[1]))
        print("tap at "+str(dist[0])+" "+str(dist[1]))
        file.write("adb shell input tap "+str(dist[0])+" "+str(dist[1])+"\n")
    else:
        os.system("adb shell input swipe "+str(lastdist[0])+" "+str(lastdist[1])+" "+str(dist[0])+" "+str(dist[1]))
        print("swipe from "+str(lastdist[0])+" "+str(lastdist[1])+" to "+str(dist[0])+" "+str(dist[1]))
        file.write("adb shell input swipe "+str(lastdist[0])+" "+str(lastdist[1])+" "+str(dist[0])+" "+str(dist[1])+"\n")
    img=RefreshImage()
    label.configure(image=img)
    label.image=img

root = tk.Tk()
#tk.
photo=RefreshImage()
#frame = tk.Frame(root, width = int(img.size[0]*scale), height = int(img.size[1]*scale),image=img)
label = tk.Label(root,image=photo)

label.bind("<Button-1>",PressCallBack)
label.bind("<ButtonRelease-1>",ReleaseCallBack)
label.pack()

root.mainloop()

 

#player.py
import os,time

Loops=200
recordfilename="record.txt"
file=open(recordfilename,"r")
command=file.readlines()
file.close()
for t in range(Loops):
    for i in command:
        os.system(i)
        #time.sleep(0.5)

 

posted @ 2022-03-18 22:18  Isakovsky  阅读(514)  评论(0编辑  收藏  举报