feat: 添加自动手机双清脚本,初始化存储库
This commit is contained in:
155
README.md
Normal file
155
README.md
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
# 自动手机双清脚本
|
||||||
|
|
||||||
|
一个模块化、易于维护和扩展的Python脚本,用于自动执行Android手机的双清操作。
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
- ✅ **模块化设计**:遵循SOLID原则,代码结构清晰,便于维护和扩展
|
||||||
|
- ✅ **设备检测**:自动检测已连接的Android设备
|
||||||
|
- ✅ **Recovery模式**:自动重启设备到Recovery模式
|
||||||
|
- ✅ **双清操作**:自动执行清除数据/恢复出厂设置和清除缓存分区
|
||||||
|
- ✅ **日志记录**:详细的日志记录,便于问题排查
|
||||||
|
- ✅ **可配置**:通过配置文件轻松调整参数
|
||||||
|
- ✅ **多设备支持**:支持同时连接多个设备时选择操作目标
|
||||||
|
|
||||||
|
## 环境要求
|
||||||
|
|
||||||
|
- Windows 10/11
|
||||||
|
- Python 3.10+
|
||||||
|
- Android SDK Platform Tools(ADB工具)
|
||||||
|
- 已开启USB调试的Android设备
|
||||||
|
|
||||||
|
## 安装步骤
|
||||||
|
|
||||||
|
### 1. 安装Python
|
||||||
|
|
||||||
|
从[Python官网](https://www.python.org/downloads/windows/)下载并安装Python 3.10或更高版本。
|
||||||
|
|
||||||
|
### 2. 安装ADB工具
|
||||||
|
|
||||||
|
1. 下载[Android SDK Platform Tools](https://developer.android.com/studio/releases/platform-tools)
|
||||||
|
2. 解压到任意目录(例如:`C:\platform-tools`)
|
||||||
|
3. 将该目录添加到系统环境变量PATH中
|
||||||
|
|
||||||
|
### 3. 配置设备
|
||||||
|
|
||||||
|
1. 在Android设备上开启开发者选项
|
||||||
|
2. 开启USB调试
|
||||||
|
3. 允许USB调试授权
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
### 基本使用
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 命令行参数(可选)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 指定ADB路径
|
||||||
|
ADB_PATH="C:\platform-tools\adb.exe" python main.py
|
||||||
|
|
||||||
|
# 调整日志级别
|
||||||
|
LOG_LEVEL="DEBUG" python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### 操作流程
|
||||||
|
|
||||||
|
1. 脚本启动后会自动检测已连接的设备
|
||||||
|
2. 选择要操作的设备
|
||||||
|
3. 确认是否开始双清操作
|
||||||
|
4. 脚本自动重启设备到Recovery模式
|
||||||
|
5. 执行清除数据和清除缓存操作
|
||||||
|
6. 自动重启设备
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
auto2Clean/
|
||||||
|
├── main.py # 主脚本文件
|
||||||
|
├── config.py # 配置文件
|
||||||
|
├── logger_setup.py # 日志配置模块
|
||||||
|
├── auto_clean.log # 日志文件(自动生成)
|
||||||
|
└── README.md # 项目说明文档
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置说明
|
||||||
|
|
||||||
|
### 主要配置项(config.py)
|
||||||
|
|
||||||
|
| 配置项 | 类型 | 默认值 | 说明 |
|
||||||
|
|--------|------|--------|------|
|
||||||
|
| ADB_PATH | str | "adb" | ADB工具路径 |
|
||||||
|
| ADB_TIMEOUT | int | 30 | ADB命令超时时间(秒) |
|
||||||
|
| RECOVERY_WAIT_TIMEOUT | int | 60 | 等待Recovery模式超时时间(秒) |
|
||||||
|
| LOG_LEVEL | str | "INFO" | 日志级别 |
|
||||||
|
| LOG_FILE | str | "auto_clean.log" | 日志文件路径 |
|
||||||
|
| AUTO_REBOOT_AFTER_CLEAN | bool | True | 双清完成后自动重启 |
|
||||||
|
| CONFIRM_BEFORE_OPERATION | bool | True | 操作前确认 |
|
||||||
|
|
||||||
|
## 维护指南
|
||||||
|
|
||||||
|
### 添加新功能
|
||||||
|
|
||||||
|
1. **遵循模块化原则**:每个功能模块独立
|
||||||
|
2. **使用配置文件**:将可配置参数添加到config.py
|
||||||
|
3. **添加日志**:在关键步骤添加日志记录
|
||||||
|
4. **错误处理**:完善异常处理机制
|
||||||
|
|
||||||
|
### 扩展操作
|
||||||
|
|
||||||
|
可以通过继承或扩展现有类来添加新功能:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 示例:添加新的Recovery操作
|
||||||
|
class ExtendedRecoveryOperations(RecoveryOperations):
|
||||||
|
def wipe_dalvik_cache(self, serial: Optional[str] = None) -> None:
|
||||||
|
"""清除Dalvik缓存"""
|
||||||
|
logger.info("开始清除Dalvik缓存...")
|
||||||
|
command = ["shell", "wipe dalvik-cache"]
|
||||||
|
if serial:
|
||||||
|
command = ["-s", serial] + command
|
||||||
|
|
||||||
|
self.adb_tool.run_command(command)
|
||||||
|
time.sleep(15)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
|
||||||
|
**Q: 检测不到设备**
|
||||||
|
- 确保USB调试已开启
|
||||||
|
- 确保已安装设备驱动
|
||||||
|
- 尝试重新插拔USB线
|
||||||
|
- 检查ADB是否正常工作(`adb devices`)
|
||||||
|
|
||||||
|
**Q: 无法进入Recovery模式**
|
||||||
|
- 确保设备已解锁Bootloader
|
||||||
|
- 检查Recovery模式是否可用
|
||||||
|
- 尝试手动进入Recovery模式验证
|
||||||
|
|
||||||
|
**Q: 双清操作失败**
|
||||||
|
- 检查Recovery模式是否支持ADB命令
|
||||||
|
- 确保设备已正确进入Recovery模式
|
||||||
|
- 查看日志文件获取详细错误信息
|
||||||
|
|
||||||
|
## 版本历史
|
||||||
|
|
||||||
|
### v1.0.0
|
||||||
|
- 初始版本
|
||||||
|
- 支持基本双清操作
|
||||||
|
- 模块化设计
|
||||||
|
- 日志记录功能
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
## 贡献
|
||||||
|
|
||||||
|
欢迎提交Issue和Pull Request来改进这个项目。
|
||||||
|
|
||||||
|
## 联系方式
|
||||||
|
|
||||||
|
如有问题或建议,请通过Issue联系。
|
||||||
BIN
__pycache__/adb_tool.cpython-310.pyc
Normal file
BIN
__pycache__/adb_tool.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/config.cpython-310.pyc
Normal file
BIN
__pycache__/config.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/config.cpython-312.pyc
Normal file
BIN
__pycache__/config.cpython-312.pyc
Normal file
Binary file not shown.
BIN
__pycache__/logger_setup.cpython-310.pyc
Normal file
BIN
__pycache__/logger_setup.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/logger_setup.cpython-312.pyc
Normal file
BIN
__pycache__/logger_setup.cpython-312.pyc
Normal file
Binary file not shown.
146
adb_tool.py
Normal file
146
adb_tool.py
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
ADB工具封装模块
|
||||||
|
|
||||||
|
该模块提供了ADB工具的封装,用于与Android设备进行通信。
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
import logging
|
||||||
|
from typing import List, Optional
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from config import Config
|
||||||
|
|
||||||
|
# 初始化日志
|
||||||
|
logger = logging.getLogger("auto_clean")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DeviceInfo:
|
||||||
|
"""设备信息数据类"""
|
||||||
|
serial: str
|
||||||
|
model: str
|
||||||
|
product: str
|
||||||
|
device: str
|
||||||
|
|
||||||
|
|
||||||
|
class ADBTool:
|
||||||
|
"""ADB工具封装类"""
|
||||||
|
|
||||||
|
def __init__(self, adb_path: str = Config.ADB_PATH):
|
||||||
|
self.adb_path = adb_path
|
||||||
|
logger.debug(f"初始化ADBTool,ADB路径: {self.adb_path}")
|
||||||
|
self._check_adb_exists()
|
||||||
|
|
||||||
|
def _check_adb_exists(self) -> None:
|
||||||
|
"""检查ADB工具是否存在"""
|
||||||
|
logger.debug("开始检查ADB工具是否存在")
|
||||||
|
try:
|
||||||
|
result = subprocess.run([self.adb_path, "version"], capture_output=True, text=True, check=True)
|
||||||
|
logger.debug(f"ADB版本信息: {result.stdout.strip()}")
|
||||||
|
logger.info("ADB工具检测成功")
|
||||||
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||||
|
logger.error("ADB工具未找到,请确保ADB已安装并添加到系统PATH")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def run_command(self, command: List[str], timeout: int = Config.ADB_TIMEOUT) -> str:
|
||||||
|
"""运行ADB命令"""
|
||||||
|
full_command = [self.adb_path] + command
|
||||||
|
logger.debug(f"执行命令: {' '.join(full_command)}, 超时时间: {timeout}秒")
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
full_command,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=timeout,
|
||||||
|
check=True
|
||||||
|
)
|
||||||
|
logger.debug(f"命令执行成功,输出: {result.stdout.strip()}")
|
||||||
|
return result.stdout.strip()
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
logger.error(f"命令执行失败: {e.stderr}")
|
||||||
|
logger.debug(f"失败命令: {' '.join(full_command)}")
|
||||||
|
raise
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
logger.error(f"命令执行超时({timeout}秒)")
|
||||||
|
logger.debug(f"超时命令: {' '.join(full_command)}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def get_connected_devices(self) -> List[DeviceInfo]:
|
||||||
|
"""获取已连接的设备列表"""
|
||||||
|
logger.debug("开始获取已连接的设备列表")
|
||||||
|
try:
|
||||||
|
output = self.run_command(["devices", "-l"])
|
||||||
|
logger.debug(f"设备列表原始输出: {output}")
|
||||||
|
|
||||||
|
devices = []
|
||||||
|
|
||||||
|
for line in output.split('\n')[1:]:
|
||||||
|
if line.strip():
|
||||||
|
parts = line.split()
|
||||||
|
serial = parts[0]
|
||||||
|
device_info = {}
|
||||||
|
|
||||||
|
for part in parts[1:]:
|
||||||
|
if ':' in part:
|
||||||
|
key, value = part.split(':', 1)
|
||||||
|
device_info[key] = value
|
||||||
|
|
||||||
|
device = DeviceInfo(
|
||||||
|
serial=serial,
|
||||||
|
model=device_info.get('model', 'unknown'),
|
||||||
|
product=device_info.get('product', 'unknown'),
|
||||||
|
device=device_info.get('device', 'unknown')
|
||||||
|
)
|
||||||
|
devices.append(device)
|
||||||
|
logger.debug(f"发现设备: {serial} - {device.model}")
|
||||||
|
|
||||||
|
logger.info(f"共检测到 {len(devices)} 台设备")
|
||||||
|
return devices
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"获取设备列表失败: {e}")
|
||||||
|
logger.debug(f"获取设备列表失败详情: {str(e)}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
def reboot_to_recovery(self, serial: Optional[str] = None) -> None:
|
||||||
|
"""重启设备到Recovery模式"""
|
||||||
|
logger.debug(f"重启设备到Recovery模式,设备序列号: {serial}")
|
||||||
|
command = ["reboot", "recovery"]
|
||||||
|
if serial:
|
||||||
|
command = ["-s", serial] + command
|
||||||
|
|
||||||
|
self.run_command(command)
|
||||||
|
logger.info("设备正在重启到Recovery模式...")
|
||||||
|
|
||||||
|
def wait_for_recovery_mode(self, serial: Optional[str] = None, timeout: int = Config.RECOVERY_WAIT_TIMEOUT) -> bool:
|
||||||
|
"""等待设备进入Recovery模式"""
|
||||||
|
logger.debug(f"等待设备进入Recovery模式,超时时间: {timeout}秒,设备序列号: {serial}")
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
while time.time() - start_time < timeout:
|
||||||
|
try:
|
||||||
|
command = ["shell", "getprop", "ro.bootmode"]
|
||||||
|
if serial:
|
||||||
|
command = ["-s", serial] + command
|
||||||
|
|
||||||
|
output = self.run_command(command, timeout=5)
|
||||||
|
logger.debug(f"Bootmode检查输出: {output}")
|
||||||
|
|
||||||
|
if "recovery" in output.lower():
|
||||||
|
logger.info("设备已进入Recovery模式")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"检查Recovery模式时出现异常: {str(e)}")
|
||||||
|
pass
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
elapsed = int(time.time() - start_time)
|
||||||
|
logger.debug(f"等待Recovery模式中... 已等待 {elapsed}/{timeout}秒")
|
||||||
|
|
||||||
|
logger.error(f"等待Recovery模式超时({timeout}秒)")
|
||||||
|
return False
|
||||||
14
auto_clean.log
Normal file
14
auto_clean.log
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
2025-12-22 22:45:11,312 - INFO - ADB<44><42><EFBFBD><EFBFBD><DFBC><EFBFBD><EFBFBD>ɹ<EFBFBD>
|
||||||
|
2025-12-22 22:45:11,312 - INFO - ִ<><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: adb devices -l
|
||||||
|
2025-12-22 23:00:08 - auto_clean - INFO - ADB工具检测成功
|
||||||
|
2025-12-22 23:00:08 - auto_clean - INFO - 共检测到 0 台设备
|
||||||
|
2025-12-22 23:00:08 - auto_clean - WARNING - 未检测到任何已连接的设备
|
||||||
|
2025-12-22 23:02:04 - auto_clean - INFO - ADB工具检测成功
|
||||||
|
2025-12-22 23:02:04 - auto_clean - INFO - 共检测到 0 台设备
|
||||||
|
2025-12-22 23:02:04 - auto_clean - WARNING - 未检测到任何已连接的设备
|
||||||
|
2025-12-22 23:02:37 - auto_clean - INFO - ADB工具检测成功
|
||||||
|
2025-12-22 23:02:37 - auto_clean - INFO - 共检测到 0 台设备
|
||||||
|
2025-12-22 23:02:37 - auto_clean - WARNING - 未检测到任何已连接的设备
|
||||||
|
2025-12-22 23:06:20 - auto_clean - INFO - ADB工具检测成功
|
||||||
|
2025-12-22 23:06:20 - auto_clean - INFO - 共检测到 0 台设备
|
||||||
|
2025-12-22 23:06:20 - auto_clean - WARNING - 未检测到任何已连接的设备
|
||||||
50
config.py
Normal file
50
config.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
配置文件
|
||||||
|
|
||||||
|
该文件包含脚本的所有可配置参数,便于后期维护和调整。
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
"""配置类"""
|
||||||
|
|
||||||
|
# ADB相关配置
|
||||||
|
ADB_PATH: str = "adb" # ADB工具路径,默认使用系统PATH中的adb
|
||||||
|
ADB_TIMEOUT: int = 30 # ADB命令超时时间(秒)
|
||||||
|
|
||||||
|
# 操作超时配置
|
||||||
|
RECOVERY_WAIT_TIMEOUT: int = 60 # 等待Recovery模式超时时间(秒)
|
||||||
|
WIPE_DATA_WAIT_TIME: int = 30 # 等待清除数据完成时间(秒)
|
||||||
|
WIPE_CACHE_WAIT_TIME: int = 15 # 等待清除缓存完成时间(秒)
|
||||||
|
|
||||||
|
# 日志配置
|
||||||
|
LOG_LEVEL: str = "INFO" # 日志级别: DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||||
|
LOG_FILE: str = "auto_clean.log" # 日志文件路径
|
||||||
|
LOG_MAX_SIZE: int = 10 * 1024 * 1024 # 单个日志文件最大大小(10MB)
|
||||||
|
LOG_BACKUP_COUNT: int = 5 # 保留的日志备份文件数
|
||||||
|
|
||||||
|
# 设备配置
|
||||||
|
DEFAULT_DEVICE_SERIAL: Optional[str] = None # 默认设备序列号
|
||||||
|
|
||||||
|
# 操作配置
|
||||||
|
AUTO_REBOOT_AFTER_CLEAN: bool = True # 双清完成后自动重启
|
||||||
|
CONFIRM_BEFORE_OPERATION: bool = True # 操作前确认
|
||||||
|
|
||||||
|
# 重试配置
|
||||||
|
MAX_RETRY_COUNT: int = 3 # 最大重试次数
|
||||||
|
RETRY_DELAY: int = 2 # 重试间隔时间(秒)
|
||||||
|
|
||||||
|
|
||||||
|
# 环境变量覆盖配置
|
||||||
|
if os.getenv("ADB_PATH"):
|
||||||
|
Config.ADB_PATH = os.getenv("ADB_PATH")
|
||||||
|
|
||||||
|
if os.getenv("LOG_LEVEL"):
|
||||||
|
Config.LOG_LEVEL = os.getenv("LOG_LEVEL")
|
||||||
|
|
||||||
|
if os.getenv("LOG_FILE"):
|
||||||
|
Config.LOG_FILE = os.getenv("LOG_FILE")
|
||||||
45
logger_setup.py
Normal file
45
logger_setup.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
日志配置模块
|
||||||
|
|
||||||
|
该模块负责配置和初始化日志系统,提供统一的日志接口。
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from logging.handlers import RotatingFileHandler
|
||||||
|
from config import Config
|
||||||
|
|
||||||
|
|
||||||
|
def setup_logger() -> logging.Logger:
|
||||||
|
"""配置并返回日志记录器"""
|
||||||
|
logger = logging.getLogger("auto_clean")
|
||||||
|
logger.setLevel(getattr(logging, Config.LOG_LEVEL))
|
||||||
|
|
||||||
|
# 避免重复添加处理器
|
||||||
|
if logger.handlers:
|
||||||
|
return logger
|
||||||
|
|
||||||
|
# 创建格式化器
|
||||||
|
formatter = logging.Formatter(
|
||||||
|
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||||
|
datefmt='%Y-%m-%d %H:%M:%S'
|
||||||
|
)
|
||||||
|
|
||||||
|
# 控制台处理器
|
||||||
|
console_handler = logging.StreamHandler()
|
||||||
|
console_handler.setFormatter(formatter)
|
||||||
|
logger.addHandler(console_handler)
|
||||||
|
|
||||||
|
# 文件处理器(支持日志轮转)
|
||||||
|
file_handler = RotatingFileHandler(
|
||||||
|
Config.LOG_FILE,
|
||||||
|
maxBytes=Config.LOG_MAX_SIZE,
|
||||||
|
backupCount=Config.LOG_BACKUP_COUNT,
|
||||||
|
encoding='utf-8'
|
||||||
|
)
|
||||||
|
file_handler.setFormatter(formatter)
|
||||||
|
logger.addHandler(file_handler)
|
||||||
|
|
||||||
|
logger.debug("日志系统初始化完成")
|
||||||
|
return logger
|
||||||
211
main.py
Normal file
211
main.py
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
自动手机双清脚本
|
||||||
|
|
||||||
|
该脚本提供了一个模块化的框架,用于自动执行Android手机的双清操作(清除数据/恢复出厂设置和清除缓存分区)。
|
||||||
|
设计遵循SOLID原则,便于后期维护和功能扩展。
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
import logging
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
# 导入配置、日志和ADB工具
|
||||||
|
from config import Config
|
||||||
|
from logger_setup import setup_logger
|
||||||
|
from adb_tool import ADBTool, DeviceInfo
|
||||||
|
|
||||||
|
# 初始化日志
|
||||||
|
logger = setup_logger()
|
||||||
|
logger.debug("主脚本初始化完成")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RecoveryOperations:
|
||||||
|
"""Recovery模式操作类"""
|
||||||
|
|
||||||
|
def __init__(self, adb_tool: ADBTool):
|
||||||
|
self.adb_tool = adb_tool
|
||||||
|
logger.debug("RecoveryOperations初始化完成")
|
||||||
|
|
||||||
|
def wipe_data(self, serial: Optional[str] = None) -> None:
|
||||||
|
"""清除数据/恢复出厂设置"""
|
||||||
|
logger.debug(f"开始清除数据/恢复出厂设置,设备序列号: {serial}")
|
||||||
|
logger.info("开始清除数据/恢复出厂设置...")
|
||||||
|
command = ["shell", "wipe data"]
|
||||||
|
if serial:
|
||||||
|
command = ["-s", serial] + command
|
||||||
|
|
||||||
|
self.adb_tool.run_command(command)
|
||||||
|
logger.debug(f"等待清除数据完成,等待时间: {Config.WIPE_DATA_WAIT_TIME}秒")
|
||||||
|
time.sleep(Config.WIPE_DATA_WAIT_TIME) # 等待操作完成
|
||||||
|
logger.debug("清除数据操作完成")
|
||||||
|
|
||||||
|
def wipe_cache(self, serial: Optional[str] = None) -> None:
|
||||||
|
"""清除缓存分区"""
|
||||||
|
logger.debug(f"开始清除缓存分区,设备序列号: {serial}")
|
||||||
|
logger.info("开始清除缓存分区...")
|
||||||
|
command = ["shell", "wipe cache"]
|
||||||
|
if serial:
|
||||||
|
command = ["-s", serial] + command
|
||||||
|
|
||||||
|
self.adb_tool.run_command(command)
|
||||||
|
logger.debug(f"等待清除缓存完成,等待时间: {Config.WIPE_CACHE_WAIT_TIME}秒")
|
||||||
|
time.sleep(Config.WIPE_CACHE_WAIT_TIME) # 等待操作完成
|
||||||
|
logger.debug("清除缓存操作完成")
|
||||||
|
|
||||||
|
def reboot_system(self, serial: Optional[str] = None) -> None:
|
||||||
|
"""重启系统"""
|
||||||
|
logger.debug(f"开始重启系统,设备序列号: {serial}")
|
||||||
|
logger.info("开始重启系统...")
|
||||||
|
command = ["shell", "reboot"]
|
||||||
|
if serial:
|
||||||
|
command = ["-s", serial] + command
|
||||||
|
|
||||||
|
self.adb_tool.run_command(command)
|
||||||
|
logger.debug("重启系统命令已发送")
|
||||||
|
|
||||||
|
|
||||||
|
class AutoCleanController:
|
||||||
|
"""自动双清控制器类"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
logger.debug("初始化AutoCleanController")
|
||||||
|
self.adb_tool = ADBTool()
|
||||||
|
self.recovery_ops = RecoveryOperations(self.adb_tool)
|
||||||
|
logger.debug("AutoCleanController初始化完成")
|
||||||
|
|
||||||
|
def run_auto_clean(self, serial: Optional[str] = None) -> None:
|
||||||
|
"""执行自动双清流程"""
|
||||||
|
logger.debug("开始执行自动双清流程")
|
||||||
|
try:
|
||||||
|
# 检查设备连接
|
||||||
|
devices = self.adb_tool.get_connected_devices()
|
||||||
|
if not devices:
|
||||||
|
logger.error("未检测到已连接的设备")
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(f"检测到 {len(devices)} 台设备")
|
||||||
|
for device in devices:
|
||||||
|
logger.info(f"设备: {device.serial} - {device.model}")
|
||||||
|
logger.debug(f"设备详细信息: {device}")
|
||||||
|
|
||||||
|
# 选择设备
|
||||||
|
target_serial = serial if serial else devices[0].serial
|
||||||
|
logger.info(f"选择设备: {target_serial}")
|
||||||
|
logger.debug(f"目标设备序列号: {target_serial}")
|
||||||
|
|
||||||
|
# 重启到Recovery模式
|
||||||
|
logger.debug("步骤1: 重启设备到Recovery模式")
|
||||||
|
self.adb_tool.reboot_to_recovery(target_serial)
|
||||||
|
|
||||||
|
# 等待Recovery模式
|
||||||
|
logger.debug("步骤2: 等待设备进入Recovery模式")
|
||||||
|
if not self.adb_tool.wait_for_recovery_mode(target_serial):
|
||||||
|
logger.error("设备未进入Recovery模式,操作终止")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 执行双清
|
||||||
|
logger.debug("步骤3: 执行清除数据操作")
|
||||||
|
self.recovery_ops.wipe_data(target_serial)
|
||||||
|
|
||||||
|
logger.debug("步骤4: 执行清除缓存操作")
|
||||||
|
self.recovery_ops.wipe_cache(target_serial)
|
||||||
|
|
||||||
|
# 重启系统
|
||||||
|
if Config.AUTO_REBOOT_AFTER_CLEAN:
|
||||||
|
logger.debug("步骤5: 重启系统")
|
||||||
|
self.recovery_ops.reboot_system(target_serial)
|
||||||
|
|
||||||
|
logger.info("双清操作完成,设备正在重启...")
|
||||||
|
logger.debug("自动双清流程执行完毕")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"自动双清过程中发生错误: {e}")
|
||||||
|
logger.debug(f"错误详情: {str(e)}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
logger.debug("主函数开始执行")
|
||||||
|
try:
|
||||||
|
controller = AutoCleanController()
|
||||||
|
logger.debug("AutoCleanController创建成功")
|
||||||
|
|
||||||
|
# 显示欢迎信息
|
||||||
|
print("=" * 60)
|
||||||
|
print("自动手机双清脚本")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# 检查设备
|
||||||
|
devices = controller.adb_tool.get_connected_devices()
|
||||||
|
logger.debug(f"设备列表: {devices}")
|
||||||
|
|
||||||
|
if not devices:
|
||||||
|
print("未检测到已连接的Android设备")
|
||||||
|
print("请确保设备已开启USB调试并连接到电脑")
|
||||||
|
logger.warning("未检测到任何已连接的设备")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 选择设备
|
||||||
|
if len(devices) == 1:
|
||||||
|
print(f"检测到设备: {devices[0].serial} - {devices[0].model}")
|
||||||
|
logger.debug(f"单设备模式,设备: {devices[0].serial}")
|
||||||
|
|
||||||
|
if Config.CONFIRM_BEFORE_OPERATION:
|
||||||
|
choice = input("是否开始双清操作? (y/N): ")
|
||||||
|
if choice.lower() == 'y':
|
||||||
|
controller.run_auto_clean(devices[0].serial)
|
||||||
|
else:
|
||||||
|
print("操作已取消")
|
||||||
|
logger.info("用户取消操作")
|
||||||
|
else:
|
||||||
|
print("自动开始双清操作...")
|
||||||
|
controller.run_auto_clean(devices[0].serial)
|
||||||
|
else:
|
||||||
|
print("检测到多个设备:")
|
||||||
|
for i, device in enumerate(devices):
|
||||||
|
print(f"{i+1}. {device.serial} - {device.model}")
|
||||||
|
|
||||||
|
logger.debug(f"多设备模式,共{len(devices)}台设备")
|
||||||
|
|
||||||
|
try:
|
||||||
|
selection = int(input("请选择要操作的设备编号: ")) - 1
|
||||||
|
if 0 <= selection < len(devices):
|
||||||
|
print(f"选择设备: {devices[selection].serial} - {devices[selection].model}")
|
||||||
|
|
||||||
|
if Config.CONFIRM_BEFORE_OPERATION:
|
||||||
|
choice = input("是否开始双清操作? (y/N): ")
|
||||||
|
if choice.lower() == 'y':
|
||||||
|
controller.run_auto_clean(devices[selection].serial)
|
||||||
|
else:
|
||||||
|
print("操作已取消")
|
||||||
|
logger.info("用户取消操作")
|
||||||
|
else:
|
||||||
|
print("自动开始双清操作...")
|
||||||
|
controller.run_auto_clean(devices[selection].serial)
|
||||||
|
else:
|
||||||
|
print("无效的选择")
|
||||||
|
logger.warning("用户输入无效的设备编号")
|
||||||
|
except ValueError:
|
||||||
|
print("请输入有效的数字")
|
||||||
|
logger.error("用户输入非数字字符")
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n操作已取消")
|
||||||
|
logger.info("用户通过Ctrl+C取消操作")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"程序执行失败: {e}")
|
||||||
|
print(f"错误: {e}")
|
||||||
|
finally:
|
||||||
|
logger.debug("主函数执行完毕")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
7
requirements.txt
Normal file
7
requirements.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# 项目依赖
|
||||||
|
# 该项目主要使用Python标准库,无需额外安装依赖
|
||||||
|
# 如果需要添加第三方库,可以在此列出
|
||||||
|
|
||||||
|
# 示例:
|
||||||
|
# requests>=2.26.0
|
||||||
|
# pyserial>=3.5
|
||||||
Reference in New Issue
Block a user