python实现adb辅助点击屏幕工具

news2025/1/21 18:47:35
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re
import os
import time
import subprocess
import tkinter as tk
from tkinter import messagebox
from PIL import Image, ImageTk

# 设置ADB路径(根据你的系统和安装路径进行调整)
ADB_PATH = 'C:/Users/DHY-20210315/AppData/Local/Android/Sdk/platform-tools/adb.exe'
# 设置截屏图片显示比例
scl = 0.7

# 创建一个GUI窗口
root = tk.Tk()
root.title("ADB辅助点击助手")
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# 设置窗口大小
window_width = 900
window_height = 600
x = (screen_width - window_width) // 2
y = (screen_height - window_height) // 2
root.geometry(f"{window_width}x{window_height}+{x}+{y}")


# 函数:通过ADB截屏并显示
def capture_and_display():
    if r_var.get() == '':
        messagebox.showinfo(title='提示', message='没有连接设备呀!')
        return
    # file = str(round(time.time() * 1000)) + '.png'
    file = 'screencap.png'
    scp = '/sdcard/Pictures/' + file
    capture_process = subprocess.Popen([ADB_PATH, '-s', r_var.get(), 'shell', 'screencap', scp])
    capture_process.wait()

    lsc = './' + file
    pull_process = subprocess.Popen([ADB_PATH, '-s', r_var.get(), 'pull', scp, lsc])
    pull_process.wait()

    screenshot = Image.open(lsc)
    width, height = screenshot.size
    new_width = int(width * scl)
    new_height = int(height * scl)
    screenshot = screenshot.resize((new_width, new_height), Image.ANTIALIAS)
    s_w = new_width + 20
    s_h = new_height + 50
    root.geometry(f"{s_w}x{s_h}+{(screen_width - s_w) // 2}+{(screen_height - s_h) // 2}")

    img = ImageTk.PhotoImage(screenshot)
    img_label.config(image=img)
    img_label.image = img


# 函数:通过ADB点击图片
def click_img(event):
    if r_var.get() == '':
        messagebox.showinfo(title='提示', message='没有连接设备呀!')
        return
    if ck_var.get() == 1:
        for i in range(8):
            subprocess.Popen(
                [ADB_PATH, '-s', r_var.get(), 'shell', 'input', 'tap', str(event.x / scl), str(event.y / scl)])
            time.sleep(0.01)
        ck_var.set(0)
    else:
        subprocess.Popen([ADB_PATH, '-s', r_var.get(), 'shell', 'input', 'tap', str(event.x / scl), str(event.y / scl)])
    time.sleep(1)
    capture_and_display()


# 函数:通过ADB发送按键
def send_back_command():
    if r_var.get() == '':
        messagebox.showinfo(title='提示', message='没有连接设备呀!')
        return
    subprocess.Popen([ADB_PATH, '-s', r_var.get(), 'shell', 'input', 'keyevent', '4'])
    time.sleep(1)
    capture_and_display()


# 函数:通过ADB发送滑动
def send_slide_command(arg):
    if r_var.get() == '':
        messagebox.showinfo(title='提示', message='没有连接设备呀!')
        return
    if arg == 1:
        subprocess.Popen([ADB_PATH, '-s', r_var.get(), 'shell', 'input', 'swipe', '969 1050 969 800 100'])
        time.sleep(1)
        capture_and_display()
    else:
        subprocess.Popen([ADB_PATH, '-s', r_var.get(), 'shell', 'input', 'swipe', '969 800 969 1050 100'])
        time.sleep(1)
        capture_and_display()


# 函数:通过ADB获取设备名
def find_device():
    dvs = os.popen("adb devices").readlines()
    dfs = ''
    for ss in dvs:
        ss = ss.strip('\n')
        if 'List of devices' not in ss and len(ss) > 6 and 'offline' not in ss:
            dv = ss.split('\t')[0]
            p = subprocess.Popen("adb -s %s shell getprop ro.product.model" % dv, stdout=subprocess.PIPE)
            result = p.communicate()
            dn = result[0].decode('utf-8').strip()
            cold_bev = tk.Radiobutton(button_frame, text=dn, variable=r_var, value=dv)
            cold_bev.pack(side="left")
            if dfs == '':
                dfs = dv
    if dfs != '':
        r_var.set(dfs)


def find_ip(input_string):
    ip_pattern = r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b'
    ip_addresses = re.findall(ip_pattern, input_string)
    return ip_addresses[0]


# 函数:通过ADB wifi连接设备
def wifi_connect():
    if r_var.get() == '':
        messagebox.showinfo(title='提示', message='没有连接设备呀!')
        return
    dv = r_var.get()
    if r_var.get().startswith('192.168.'):
        messagebox.showinfo(title='提示', message='已经是WiFi连接了啊!')
        return
    p = subprocess.Popen("adb -s %s shell ip -f inet addr show wlan0" % dv, stdout=subprocess.PIPE)
    result = p.communicate()
    dn = result[0].decode('utf-8').strip()
    ip = find_ip(dn)
    subprocess.Popen([ADB_PATH, 'connect', ip])


button_frame = tk.Frame(root)
button_frame.pack()

capture_button = tk.Button(button_frame, text="截屏", command=capture_and_display)
capture_button.pack(side="left")
tk.Label(button_frame, text="   ").pack(side="left")
back_button = tk.Button(button_frame, text="后退", command=send_back_command)
back_button.pack(side="left")
tk.Label(button_frame, text="   ").pack(side="left")
up_button = tk.Button(button_frame, text="上滑", command=lambda: send_slide_command(1))
up_button.pack(side="left")
tk.Label(button_frame, text="   ").pack(side="left")
down_button = tk.Button(button_frame, text="下滑", command=lambda: send_slide_command(0))
down_button.pack(side="left")
tk.Label(button_frame, text="   ").pack(side="left")
ck_var = tk.IntVar()
c1 = tk.Checkbutton(button_frame, text='8连击', variable=ck_var, onvalue=1, offvalue=0)
c1.pack(side="left")
tk.Label(button_frame, text="   ").pack(side="left")
r_var = tk.StringVar(value='')
find_device()
img_label = tk.Label(root)
img_label.pack()
img_label.bind('<Button-1>', click_img)
wifi_button = tk.Button(button_frame, text="WiFi连接", command=wifi_connect)
wifi_button.pack(side="left")

root.mainloop()

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

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

相关文章

Ubuntu快速搭建内网NTP Server

文章目录 安装NTP服务配置NTP配置NTP 同步源配置NTP 允许客户端访问重启NTP服务使得配置生效 推荐阅读 NTP(Network Time Protocol)------网络时间协议-----应用层协议&#xff0c;用来在分布式时间服务器和客户端之间进行时间同步。 是对网络内所有具有时钟的设备进行时钟同步…

图解 LeetCode 算法汇总——链表

本文首发公众号&#xff1a;小码A梦 一般数据主要存储的形式主要有两种&#xff0c;一种是数组&#xff0c;一种是链表。数组是用来存储固定大小的同类型元素&#xff0c;存储在内存中是一片连续的空间。而链表就不同于数组。链表中的元素不是存储在内存中可以是不连续的空间。…

酒店类型的软文怎么写?

马上就放长假了&#xff0c;有不少酒店行业来找盒子做推广&#xff0c;其实酒店行业想要写好软文只要掌握三种类型就好了&#xff0c;今天就让盒子告诉大家酒店类型的软文怎么写才能吸引用户。 一、以故事打动用户 故事型软文大多用于民宿酒店&#xff0c;民宿酒店文案除了展现…

Docker认识即安装

Docker及相关概念 Docker和虚拟机方式的区别&#xff1a;虚拟机技术是虚拟出一套硬件后&#xff0c;在其上运行一个完整的操作系统&#xff0c;在该系统上在运行所需应用进程&#xff1b;而容器内的应用进程是直接运行于宿主的内核&#xff0c;容器内没有自己的内核&#xff0…

2023区块链应用操作员认证(4级)报名来弘博创新

区块链应用操作员&#xff0c;是指运用区块链技术及工具&#xff0c;从事政务、金融、医疗、教育、养老等场景系统应用操作的人员。 腾讯作为广东省第一批公布的社会培训评价组织&#xff0c;可开展职业技能等级认定职业(工种)区块链应用操作员(4-3-2-1级)。 证书含金量 证书是…

小节4:input()函数的一些讲究

千万注意&#xff1a;不管用户输入的是什么&#xff0c;input()返回的一律都是字符串&#xff0c;代码如下&#xff1a; user_input input("Please input something: ") print(type(user_input)) 所以&#xff0c;如果直接拿用户输入的内容去做数学运算&#xff0c…

JavaScript 之 常用迭代方法forEach、filter()、map()、reduce()

JavaScript 之 常用迭代方法forEach、filter、map、reduce 1. for、forEach1.1 for 遍历的3种写法1.2 forEach 回调函数 遍历1.3 forEach 箭头函数 遍历 2. filter()2.1 介绍2.2 例子1——简单过滤2.3 例子2——在修改数组时 filter() 方法的行为2.4 例子3——在数组中搜索 3…

生成式 AI 中的风险认知

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 直到几年前&#xff0c;你能想象一台机器可以创造艺术、制作故事&#xff0c;甚至理解复杂的数据&#xff0c;如医疗和法律文件吗&#xff1f; 应该不会。对于我们大多数人来说&#xff0c;它仅限于一部看似牵强附会的…

博客系统项目

文章目录 数据库的增删改查草稿箱草稿箱自动保存分页查询后端前端 评论区后端前端 md5加盐加密 md5加盐对用户密码进行加密; 全服用户博客列表页,实现分页查询; 用户博客列表页; 写博客,发博客,改博客; 博客草稿箱,自动保存,定时发布; 博客访问量,博客评论区,博客点赞; 数据库…

MojoTween:使用「Burst、Jobs、Collections、Mathematics」优化实现的Unity顶级「Tween动画引擎」

MojoTween是一个令人惊叹的Tween动画引擎&#xff0c;针对C#和Unity进行了高度优化&#xff0c;使用了Burst、Jobs、Collections、Mathematics等新技术编码。 MojoTween提供了一套完整的解决方案&#xff0c;将Tween动画应用于Unity Objects的各个方面&#xff0c;并可以通过E…

恒运资本:人民币汇率何时走出低谷?

9月7日&#xff0c;国家外汇管理局发布统计数据显现&#xff0c;到2023年8月末&#xff0c;我国外汇储藏规划为31601亿美元&#xff0c;较7月末下降442亿美元&#xff0c;降幅为1.38%。 国家外汇管理局相关负责人表明&#xff0c;2023年8月&#xff0c;受首要经济体微观经济数…

《机器人学一(Robotics(1))》_台大林沛群 第 7 周 【轨迹规划_综合】Quiz 7

题 4-5 存疑&#xff0c;仅供参考&#xff0c;欢迎交流 文章目录 题4-9&#xff1a;题4-5求解代码&#xff1a; Python题6-7求解代码&#xff1a; Python求解 θ4-θ6 时&#xff0c; 记得 将 R 改成相应的&#xff01;&#xff01;&#xff01;&#xff01; 题8-9求解代码&…

深浅拷贝与赋值

数据类型 数据类型 在JavaScript中&#xff0c;数据类型有两大类。一类是基本数据类型&#xff0c;一类是引用数据类型。 基本数据类型有六种&#xff1a;number、string、boolean、null、undefined、symbol。 基本数据类型存放在栈中。存放在栈中的数据具有数据大小确定&a…

2023高教社杯数学建模B题思路代码 - 多波束测线问题

# 1 赛题 B 题 多波束测线问题 单波束测深是利用声波在水中的传播特性来测量水体深度的技术。声波在均匀介质中作匀 速直线传播&#xff0c; 在不同界面上产生反射&#xff0c; 利用这一原理&#xff0c;从测量船换能器垂直向海底发射声波信 号&#xff0c;并记录从声波发射到…

更换Eclipse的JDK版本

点击window->Preferences 选择Installed JREs 点击 Add 按钮&#xff0c; 选择Standard VM, 点击 Next。然后选择自己安装的JDK路径

测量仪器方案——核辐射检测仪方案

核辐射在我们日常生活中是比较常见的&#xff0c;基本在任何地方都会存在或多或少的辐射放射源&#xff0c;当它的强度超过一定数值后&#xff0c;就会对人体造成一定的影响。如果是在辐射强度过高的领域工作时&#xff0c;建议选择核辐射检测仪作为防护仪器。目前核辐射检测仪…

一点感受

做了两天企业数字化转型的评委&#xff0c;涉及全国最顶级的公司、最顶级的实际落地项目案例&#xff0c;由企业真实的落地团队亲自当面讲解。主要是为了了解了解真实的一线、真实的客户、真实的应用现状和应用水平。 &#xff08;1&#xff09;现状 我评审的涉及底层技术平台&…

无涯教程-JavaScript - HEX2DEC函数

描述 HEX2DEC函数将十六进制数字转换为十进制。 语法 HEX2DEC (number)争论 Argument描述Required/Optionalnumber 您要转换的十六进制数。 数字不能超过10个字符(40位)。数字的最高有效位是符号位。其余的39位是幅度位。 负数使用二进制补码表示。 Required Notes 十六进…

在Spring Boot项目中使用JPA

1.集成Spring Data JPA Spring Boot提供了启动器spring-boot-starter-data-jpa&#xff0c;只需要添加启动器&#xff08;Starters&#xff09;就能实现在项目中使用JPA。下面一步一步演示集成Spring Data JPA所需的配置。 步骤01 添加JPA依赖。 首先创建新的Spring Boot项目…

Git_回退到上一次commit与pull

git 回退到上个版本 rollback 回滚 git reset HEAD&#xff0c; git 回退到上一版本