Python基础(adb获取当前界面xml)

123

import uiautomator2 as u2

def save_xml_to_file(xml_content, filename="ui_dump.xml"):
    """保存XML内容到文件"""
    try:
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(xml_content)
        print(f"XML内容已保存到文件: {filename}")
        return True
    except Exception as e:
        print(f"保存XML文件时出错: {e}")
        return False

def dump_ui_xml():
    """获取并保存当前界面的XML结构"""
    try:
        # 连接设备
        d = u2.connect()
        print("设备已连接")
        
        # 检查设备连接状态
        if not d.exists:
            print("警告:设备可能未正确连接,请检查USB连接和调试模式")
            return False
        
        # 获取当前界面的UI层次结构
        print("正在获取UI层次结构...")
        xml_content = d.dump_hierarchy()
        
        # 保存原始XML内容
        if save_xml_to_file(xml_content):
            print("UI层次结构已成功保存到 ui_dump.xml")
            return True
        return False
        
    except Exception as e:
        print(f"获取UI层次结构时出错: {e}")
        return False

if __name__ == "__main__":
    try:
        print("正在获取当前界面的XML结构...")
        dump_ui_xml()
    except Exception as e:
        print(f"发生错误: {e}")
        print("\n请确保:")
        print("1. 已安装所需库: pip install uiautomator2")
        print("2. 设备已通过USB连接并已启用USB调试")
        print("3. 已安装ATX代理 (python -m uiautomator2 init)")
        print("4. 尝试重启ATX服务: python -m uiautomator2 restart")

输入id和class选择性的筛选。

import uiautomator2 as u2
import xml.etree.ElementTree as ET
import re
import os
from PIL import Image, ImageDraw, ImageFont
 
def save_xml_to_file(xml_content, filename="ui_dump.xml"):
    """保存XML内容到文件"""
    try:
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(xml_content)
        print(f"XML内容已保存到文件: {filename}")
        return True
    except Exception as e:
        print(f"保存XML文件时出错: {e}")
        return False
 
def dump_ui_xml():
    """获取并保存当前界面的XML结构"""
    try:
        # 连接设备
        d = u2.connect()
        print("设备已连接")
        
        # 检查设备连接状态
        if not d.exists:
            print("警告:设备可能未正确连接,请检查USB连接和调试模式")
            return False, None
        
        # 获取当前界面的UI层次结构
        print("正在获取UI层次结构...")
        xml_content = d.dump_hierarchy()
        
        # 保存原始XML内容
        if save_xml_to_file(xml_content):
            print("UI层次结构已成功保存到 ui_dump.xml")
            return xml_content, d
        return False, None
        
    except Exception as e:
        print(f"获取UI层次结构时出错: {e}")
        return False, None

def parse_bounds(bounds_str):
    """解析元素边界坐标"""
    # 从字符串如 "[0,0][100,100]" 提取坐标
    pattern = r'\[(\d+),(\d+)\]\[(\d+),(\d+)\]'
    match = re.match(pattern, bounds_str)
    if match:
        x1, y1, x2, y2 = map(int, match.groups())
        return (x1, y1, x2, y2)
    return None

def list_all_elements():
    """列出所有可用的class和id"""
    try:
        # 获取XML内容和设备连接
        result = dump_ui_xml()
        if not result:
            return False
        
        xml_content, _ = result
        
        # 解析XML
        root = ET.fromstring(xml_content)
        
        # 收集所有唯一的class和id
        classes = set()
        ids = set()
        
        # 遍历所有节点
        for elem in root.iter():
            class_name = elem.attrib.get('class', '')
            elem_id = elem.attrib.get('resource-id', '')
            
            if class_name:
                classes.add(class_name)
            if elem_id:
                ids.add(elem_id)
        
        # 输出结果
        print("\n可用的Class:")
        for i, class_name in enumerate(sorted(classes)):
            print(f"{i+1}. {class_name}")
        
        print("\n可用的ID:")
        for i, elem_id in enumerate(sorted(ids)):
            print(f"{i+1}. {elem_id}")
        
        return True
    
    except Exception as e:
        print(f"列出元素时出错: {e}")
        return False

def highlight_elements_by_class_id(target_class=None, target_id=None, save_image=True):
    """根据指定的class和id标识UI元素并在截图上圈出来"""
    try:
        # 获取XML内容和设备连接
        result = dump_ui_xml()
        if not result:
            return False
        
        xml_content, d = result
        
        # 截取当前屏幕
        print("正在截取屏幕...")
        screenshot_path = "screen.png"
        d.screenshot(screenshot_path)
        
        # 解析XML
        root = ET.fromstring(xml_content)
        
        # 查找所有元素
        highlighted_elements = []
        
        # 遍历所有节点
        for elem in root.iter():
            class_name = elem.attrib.get('class', '')
            elem_id = elem.attrib.get('resource-id', '')
            bounds = elem.attrib.get('bounds', '')
            
            # 匹配条件:如果指定了class或id,则只匹配指定的元素
            match_class = not target_class or (target_class in class_name)
            match_id = not target_id or (target_id in elem_id)
            
            # 如果同时指定了class和id,两者都要匹配
            # 如果只指定了其中一个,则只需匹配指定的那个
            is_match = False
            if target_class and target_id:
                is_match = match_class and match_id
            else:
                is_match = match_class or match_id
            
            if is_match and bounds:
                coords = parse_bounds(bounds)
                if coords:
                    highlighted_elements.append({
                        'class': class_name,
                        'id': elem_id,
                        'bounds': bounds,
                        'coords': coords,
                        'text': elem.attrib.get('text', '')
                    })
        
        # 在截图上标记元素
        if save_image and highlighted_elements:
            print("正在标记元素...")
            img = Image.open(screenshot_path)
            draw = ImageDraw.Draw(img)
            
            # 尝试加载字体,如果失败则使用默认字体
            try:
                font = ImageFont.truetype("arial.ttf", 14)
            except IOError:
                font = ImageFont.load_default()
            
            # 在图像上绘制矩形和标签
            for i, elem in enumerate(highlighted_elements):
                x1, y1, x2, y2 = elem['coords']
                
                # 绘制矩形
                draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
                
                # 准备标签文本
                if elem['id']:
                    label = f"{i+1}. ID: {elem['id'].split('/')[-1]}"
                else:
                    label = f"{i+1}. Class: {elem['class'].split('.')[-1]}"
                
                # 绘制标签背景和文本
                text_bbox = draw.textbbox((0, 0), label, font=font)
                text_width = text_bbox[2] - text_bbox[0]
                text_height = text_bbox[3] - text_bbox[1]
                
                draw.rectangle([x1, y1-text_height-4, x1+text_width+4, y1], fill="red")
                draw.text((x1+2, y1-text_height-2), label, fill="white", font=font)
            
            # 保存标记后的图像
            marked_image_path = "marked_elements.png"
            img.save(marked_image_path)
            print(f"已将标记元素的截图保存到: {os.path.abspath(marked_image_path)}")
        
        # 输出结果
        if highlighted_elements:
            print(f"\n已找到 {len(highlighted_elements)} 个匹配的元素:")
            for i, elem in enumerate(highlighted_elements):
                print(f"{i+1}. Class: {elem['class']}")
                if elem['id']:
                    print(f"   ID: {elem['id']}")
                print(f"   位置: {elem['bounds']}, 文本: {elem['text']}")
        else:
            print(f"\n未找到匹配的元素")
        
        return highlighted_elements
    
    except Exception as e:
        print(f"处理元素时出错: {e}")
        import traceback
        traceback.print_exc()
        return False
 
def main():
    try:
        print("欢迎使用UI元素标识工具")
        print("------------------------")
        
        # 先列出所有可用的class和id
        print("正在获取当前界面的所有元素...")
        list_all_elements()
        
        # 询问用户要查找的元素
        print("\n请输入要查找的元素属性(留空则匹配所有元素):")
        target_class = input("Class (可选): ").strip()
        target_id = input("ID (可选): ").strip()
        
        if not target_class and not target_id:
            print("未指定任何属性,将标记所有元素")
        
        # 标记元素
        print("\n正在查找并标记元素...")
        highlight_elements_by_class_id(target_class, target_id)
        
    except Exception as e:
        print(f"发生错误: {e}")
        print("\n请确保:")
        print("1. 已安装所需库: pip install uiautomator2 pillow")
        print("2. 设备已通过USB连接并已启用USB调试")
        print("3. 已安装ATX代理 (python -m uiautomator2 init)")
        print("4. 尝试重启ATX服务: python -m uiautomator2 restart")

if __name__ == "__main__":
    main()

大小尺寸进行选择

import uiautomator2 as u2
import xml.etree.ElementTree as ET
import re
import os
from PIL import Image, ImageDraw, ImageFont
import math
from collections import defaultdict
 
def save_xml_to_file(xml_content, filename="ui_dump.xml"):
    """保存XML内容到文件"""
    try:
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(xml_content)
        print(f"XML内容已保存到文件: {filename}")
        return True
    except Exception as e:
        print(f"保存XML文件时出错: {e}")
        return False
 
def dump_ui_xml():
    """获取并保存当前界面的XML结构"""
    try:
        # 连接设备
        d = u2.connect()
        print("设备已连接")
        
        # 检查设备连接状态
        if not d.exists:
            print("警告:设备可能未正确连接,请检查USB连接和调试模式")
            return False, None
        
        # 获取当前界面的UI层次结构
        print("正在获取UI层次结构...")
        xml_content = d.dump_hierarchy()
        
        # 保存原始XML内容
        if save_xml_to_file(xml_content):
            print("UI层次结构已成功保存到 ui_dump.xml")
            return xml_content, d
        return False, None
        
    except Exception as e:
        print(f"获取UI层次结构时出错: {e}")
        return False, None

def parse_bounds(bounds_str):
    """解析元素边界坐标"""
    # 从字符串如 "[0,0][100,100]" 提取坐标
    pattern = r'\[(\d+),(\d+)\]\[(\d+),(\d+)\]'
    match = re.match(pattern, bounds_str)
    if match:
        x1, y1, x2, y2 = map(int, match.groups())
        return (x1, y1, x2, y2)
    return None

def highlight_elements_by_class_id(target_class=None, target_id=None, save_image=True):
    """根据指定的class和id标识UI元素并在截图上圈出来,返回匹配的元素列表"""
    try:
        # 获取XML内容和设备连接
        result = dump_ui_xml()
        if not result:
            return []
        
        xml_content, d = result
        
        # 截取当前屏幕
        print("正在截取屏幕...")
        screenshot_path = "screen.png"
        d.screenshot(screenshot_path)
        
        # 解析XML
        root = ET.fromstring(xml_content)
        
        # 查找所有元素
        highlighted_elements = []
        
        # 遍历所有节点
        for elem in root.iter():
            class_name = elem.attrib.get('class', '')
            elem_id = elem.attrib.get('resource-id', '')
            bounds = elem.attrib.get('bounds', '')
            
            # 匹配条件:如果指定了class或id,则只匹配指定的元素
            match_class = not target_class or (target_class in class_name)
            match_id = not target_id or (target_id in elem_id)
            
            # 如果同时指定了class和id,两者都要匹配
            # 如果只指定了其中一个,则只需匹配指定的那个
            is_match = False
            if target_class and target_id:
                is_match = match_class and match_id
            else:
                is_match = match_class or match_id
            
            if is_match and bounds:
                coords = parse_bounds(bounds)
                if coords:
                    x1, y1, x2, y2 = coords
                    width = x2 - x1
                    height = y2 - y1
                    
                    # 只添加有实际尺寸的元素
                    if width > 0 and height > 0:
                        highlighted_elements.append({
                            'class': class_name,
                            'id': elem_id,
                            'bounds': bounds,
                            'coords': coords,
                            'width': width,
                            'height': height,
                            'text': elem.attrib.get('text', '')
                        })
        
        # 在截图上标记元素
        if save_image and highlighted_elements:
            print("正在标记元素...")
            img = Image.open(screenshot_path)
            draw = ImageDraw.Draw(img)
            
            # 尝试加载字体,如果失败则使用默认字体
            try:
                font = ImageFont.truetype("arial.ttf", 14)
            except IOError:
                font = ImageFont.load_default()
            
            # 在图像上绘制矩形和标签
            for i, elem in enumerate(highlighted_elements):
                x1, y1, x2, y2 = elem['coords']
                
                # 绘制矩形
                draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
                
                # 准备标签文本
                if elem['id']:
                    label = f"{i+1}. ID: {elem['id'].split('/')[-1]}"
                else:
                    label = f"{i+1}. Class: {elem['class'].split('.')[-1]}"
                
                # 绘制标签背景和文本
                text_bbox = draw.textbbox((0, 0), label, font=font)
                text_width = text_bbox[2] - text_bbox[0]
                text_height = text_bbox[3] - text_bbox[1]
                
                draw.rectangle([x1, y1-text_height-4, x1+text_width+4, y1], fill="red")
                draw.text((x1+2, y1-text_height-2), label, fill="white", font=font)
            
            # 保存标记后的图像
            marked_image_path = "marked_elements.png"
            img.save(marked_image_path)
            print(f"已将标记元素的截图保存到: {os.path.abspath(marked_image_path)}")
        
        # 输出结果
        if highlighted_elements:
            print(f"\n已找到 {len(highlighted_elements)} 个匹配的元素:")
            for i, elem in enumerate(highlighted_elements):
                print(f"{i+1}. Class: {elem['class']}")
                if elem['id']:
                    print(f"   ID: {elem['id']}")
                print(f"   位置: {elem['bounds']}, 尺寸: {elem['width']}x{elem['height']} 像素")
                if elem['text']:
                    print(f"   文本: {elem['text']}")
        else:
            print(f"\n未找到匹配的元素")
        
        return highlighted_elements
    
    except Exception as e:
        print(f"处理元素时出错: {e}")
        import traceback
        traceback.print_exc()
        return []

def group_by_similar_size(elements, tolerance=0.1):
    """将元素按照相似尺寸分组
    
    Args:
        elements: 元素列表
        tolerance: 尺寸相似度容差(0.1表示10%的误差范围)
    
    Returns:
        分组后的元素字典,键为(宽度, 高度)的元组,值为元素列表
    """
    # 按尺寸分组的字典
    size_groups = defaultdict(list)
    
    # 已处理的尺寸集合,用于避免重复
    processed_sizes = set()
    
    # 先对元素按面积排序
    elements.sort(key=lambda x: x['width'] * x['height'])
    
    # 分组处理
    for elem in elements:
        width, height = elem['width'], elem['height']
        
        # 检查是否已经有相似尺寸的组
        found_group = False
        for w, h in processed_sizes:
            # 计算宽高的相对误差
            width_diff = abs(width - w) / max(width, w)
            height_diff = abs(height - h) / max(height, h)
            
            # 如果宽高都在容差范围内,则认为是相似尺寸
            if width_diff <= tolerance and height_diff <= tolerance:
                size_groups[(w, h)].append(elem)
                found_group = True
                break
        
        # 如果没找到相似尺寸的组,则创建新组
        if not found_group:
            size_groups[(width, height)].append(elem)
            processed_sizes.add((width, height))
    
    return size_groups

def show_size_groups(matched_elements):
    """显示按相似尺寸分组的元素集合,并允许用户选择集合进行标记"""
    try:
        if not matched_elements:
            print("没有匹配的元素可供分组")
            return False
            
        # 按相似尺寸分组
        size_groups = group_by_similar_size(matched_elements)
        
        # 将分组转换为列表,便于索引
        groups_list = []
        for size, elements in size_groups.items():
            width, height = size
            groups_list.append({
                'size': size,
                'elements': elements,
                'count': len(elements)
            })
        
        # 按元素数量排序,数量多的排在前面
        groups_list.sort(key=lambda x: x['count'], reverse=True)
        
        # 输出分组信息
        print(f"\n已将 {len(matched_elements)} 个元素按相似尺寸分为 {len(groups_list)} 个集合:")
        for i, group in enumerate(groups_list):
            width, height = group['size']
            print(f"{i+1}. 尺寸约 {width}x{height} 像素,包含 {group['count']} 个元素")
        
        # 询问用户要查看的集合
        while True:
            try:
                selection = input("\n请输入要查看的尺寸集合编号(输入0退出): ")
                if selection == "0":
                    return True
                
                # 解析用户输入的编号
                group_idx = int(selection.strip())
                if 1 <= group_idx <= len(groups_list):
                    selected_group = groups_list[group_idx-1]
                    show_group_elements(selected_group)
                else:
                    print(f"编号 {group_idx} 无效,有效范围: 1-{len(groups_list)}")
                
            except ValueError:
                print("输入无效,请输入数字编号")
        
        return True
        
    except Exception as e:
        print(f"处理尺寸分组时出错: {e}")
        import traceback
        traceback.print_exc()
        return False

def show_group_elements(group):
    """显示指定尺寸集合中的元素,并允许用户选择特定元素标记"""
    try:
        width, height = group['size']
        elements = group['elements']
        
        print(f"\n尺寸约 {width}x{height} 像素的集合包含 {len(elements)} 个元素:")
        for i, elem in enumerate(elements):
            print(f"{i+1}. Class: {elem['class']}")
            if elem['id']:
                print(f"   ID: {elem['id']}")
            print(f"   位置: {elem['bounds']}, 精确尺寸: {elem['width']}x{elem['height']} 像素")
            if elem['text']:
                print(f"   文本: {elem['text']}")
            print("---")
        
        # 询问用户是否要标记所有元素或选择特定元素
        print("\n请选择操作:")
        print("1. 标记该集合中的所有元素")
        print("2. 选择特定元素进行标记")
        print("0. 返回上级菜单")
        
        choice = input("\n请输入选项编号: ")
        
        if choice == "1":
            # 标记所有元素
            mark_selected_elements(elements, list(range(1, len(elements)+1)), "screen.png")
        elif choice == "2":
            # 选择特定元素
            while True:
                try:
                    selection = input("\n请输入要单独标记的元素编号(多个编号用逗号分隔,输入0返回): ")
                    if selection == "0":
                        return
                    
                    # 解析用户输入的编号
                    selected_indices = [int(idx.strip()) for idx in selection.split(",") if idx.strip()]
                    if not selected_indices:
                        print("未选择任何元素,请重新输入")
                        continue
                    
                    # 验证编号是否有效
                    valid_indices = []
                    for idx in selected_indices:
                        if 1 <= idx <= len(elements):
                            valid_indices.append(idx)
                        else:
                            print(f"编号 {idx} 无效,有效范围: 1-{len(elements)}")
                    
                    if valid_indices:
                        # 标记选定的元素
                        mark_selected_elements(elements, valid_indices, "screen.png")
                        break
                    
                except ValueError:
                    print("输入无效,请输入数字编号")
        
    except Exception as e:
        print(f"显示集合元素时出错: {e}")
        import traceback
        traceback.print_exc()

def show_rectangle_dimensions_by_filter(matched_elements):
    """显示匹配元素的矩形尺寸,并允许用户选择特定矩形进行标记"""
    try:
        if not matched_elements:
            print("没有匹配的元素可供选择")
            return False
            
        # 输出所有匹配元素的尺寸信息
        print(f"\n根据筛选条件找到 {len(matched_elements)} 个UI元素:")
        for i, elem in enumerate(matched_elements):
            print(f"{i+1}. 尺寸: {elem['width']}x{elem['height']} 像素")
            print(f"   位置: {elem['bounds']}")
            if elem['id']:
                print(f"   ID: {elem['id']}")
            print(f"   Class: {elem['class']}")
            if elem['text']:
                print(f"   文本: {elem['text']}")
            print("---")
        
        # 询问用户要标记的元素
        while True:
            try:
                selection = input("\n请输入要单独标记的元素编号(多个编号用逗号分隔,输入0退出): ")
                if selection == "0":
                    return True
                
                # 解析用户输入的编号
                selected_indices = [int(idx.strip()) for idx in selection.split(",") if idx.strip()]
                if not selected_indices:
                    print("未选择任何元素,请重新输入")
                    continue
                
                # 验证编号是否有效
                valid_indices = []
                for idx in selected_indices:
                    if 1 <= idx <= len(matched_elements):
                        valid_indices.append(idx)
                    else:
                        print(f"编号 {idx} 无效,有效范围: 1-{len(matched_elements)}")
                
                if valid_indices:
                    # 标记选定的元素
                    mark_selected_elements(matched_elements, valid_indices, "screen.png")
                    break
                
            except ValueError:
                print("输入无效,请输入数字编号")
        
        return True
        
    except Exception as e:
        print(f"处理元素尺寸时出错: {e}")
        import traceback
        traceback.print_exc()
        return False

def mark_selected_elements(all_elements, selected_indices, screenshot_path):
    """标记用户选择的特定元素"""
    try:
        print("正在标记选定的元素...")
        img = Image.open(screenshot_path)
        draw = ImageDraw.Draw(img)
        
        # 尝试加载字体,如果失败则使用默认字体
        try:
            font = ImageFont.truetype("arial.ttf", 14)
        except IOError:
            font = ImageFont.load_default()
        
        # 在图像上只标记选定的元素
        for idx in selected_indices:
            elem = all_elements[idx-1]  # 索引从0开始,但显示给用户是从1开始
            x1, y1, x2, y2 = elem['coords']
            
            # 绘制矩形,使用不同颜色
            draw.rectangle([x1, y1, x2, y2], outline="blue", width=3)
            
            # 准备标签文本
            label = f"{idx}. {elem['width']}x{elem['height']}像素"
            
            # 绘制标签背景和文本
            text_bbox = draw.textbbox((0, 0), label, font=font)
            text_width = text_bbox[2] - text_bbox[0]
            text_height = text_bbox[3] - text_bbox[1]
            
            draw.rectangle([x1, y1-text_height-4, x1+text_width+4, y1], fill="blue")
            draw.text((x1+2, y1-text_height-2), label, fill="white", font=font)
        
        # 保存标记后的图像
        selected_image_path = "selected_elements.png"
        img.save(selected_image_path)
        print(f"已将选定元素的截图保存到: {os.path.abspath(selected_image_path)}")
        
        # 输出选定元素的详细信息
        print("\n选定元素的详细信息:")
        for idx in selected_indices:
            elem = all_elements[idx-1]
            print(f"{idx}. 尺寸: {elem['width']}x{elem['height']} 像素")
            print(f"   位置: {elem['bounds']}")
            if elem['id']:
                print(f"   ID: {elem['id']}")
            print(f"   Class: {elem['class']}")
            if elem['text']:
                print(f"   文本: {elem['text']}")
            print("---")
        
    except Exception as e:
        print(f"标记选定元素时出错: {e}")
        import traceback
        traceback.print_exc()
 
def main():
    try:
        print("欢迎使用UI元素标识工具")
        print("------------------------")
        
        while True:
            print("\n请选择操作:")
            print("1. 根据class或id标记元素并选择特定矩形")
            print("2. 根据class或id标记元素并按相似尺寸分组")
            print("0. 退出")
            
            choice = input("\n请输入选项编号: ")
            
            if choice == "1":
                # 询问用户要查找的元素
                print("\n请输入要查找的元素属性(留空则匹配所有元素):")
                target_class = input("Class (可选): ").strip()
                target_id = input("ID (可选): ").strip()
                
                if not target_class and not target_id:
                    print("未指定任何属性,将标记所有元素")
                
                # 标记元素并获取匹配的元素列表
                print("\n正在查找并标记元素...")
                matched_elements = highlight_elements_by_class_id(target_class, target_id)
                
                # 显示匹配元素的尺寸并选择特定矩形标记
                if matched_elements:
                    print("\n是否要根据尺寸选择特定矩形进行标记?(y/n)")
                    if input().lower() == 'y':
                        show_rectangle_dimensions_by_filter(matched_elements)
            elif choice == "2":
                # 询问用户要查找的元素
                print("\n请输入要查找的元素属性(留空则匹配所有元素):")
                target_class = input("Class (可选): ").strip()
                target_id = input("ID (可选): ").strip()
                
                if not target_class and not target_id:
                    print("未指定任何属性,将标记所有元素")
                
                # 标记元素并获取匹配的元素列表
                print("\n正在查找并标记元素...")
                matched_elements = highlight_elements_by_class_id(target_class, target_id)
                
                # 按相似尺寸分组并显示
                if matched_elements:
                    show_size_groups(matched_elements)
            elif choice == "0":
                print("感谢使用,再见!")
                break
            else:
                print("无效的选项,请重新输入")
        
    except Exception as e:
        print(f"发生错误: {e}")
        print("\n请确保:")
        print("1. 已安装所需库: pip install uiautomator2 pillow")
        print("2. 设备已通过USB连接并已启用USB调试")
        print("3. 已安装ATX代理 (python -m uiautomator2 init)")
        print("4. 尝试重启ATX服务: python -m uiautomator2 restart")

if __name__ == "__main__":
    main()

你可能感兴趣的:(python,adb,xml)