HID 键鼠自动化控制指南
更新: 2026/3/2 字数: 0 字 时长: 0 分钟
基于物理级硬件的 零权限 / 强隔离 / 高一致性 自动化方案
HID(Human Interface Device)键鼠自动化 是一种纯硬件层输入模拟方案。 它通过 ESP32 / 专用 HID 硬件,在 USB / OTG / 蓝牙协议层模拟标准键盘、鼠标、触控设备,对手机或其他终端进行操作控制。
👉 从操作系统视角看,这些行为与真实外设输入完全一致。
核心优势
零权限运行
HID 键鼠控制基于外置硬件输入实现,不依赖任何系统级能力或高权限接口,包括但不限于:
- 无障碍 / 辅助功能
- ADB 调试通道 / 开发人员选项
- Root 或系统修改能力
无需授权、不占用系统权限,插入即生效。
强环境隔离性
HID 方案的操作路径完全位于系统输入链路最前端:
- 输入事件来源为 外部物理设备
- 行为由系统输入子系统统一接收
- 不通过应用层 API、不注入进程、不修改系统状态
- 不产生额外的调用痕迹或运行特征
从系统与应用的角度看, 👉 这些操作等价于真实用户使用键盘、鼠标或触控设备完成的输入行为。
全功能覆盖,适配多种业务形态
支持完整的输入与控制能力,包括:
- 按键与组合键模拟
- 文本输入与粘贴
- 精准触控与多点手势
- 滑动、缩放、长按等交互
- 屏幕截图与视觉联动
同时兼容 BLE 蓝牙 / OTG / USB 多种连接方式,满足不同部署环境。
高稳定性 & 低时延表现
| 指标 | HID 硬件方案 | 传统软件方案 |
|---|---|---|
| 输入延迟 | 5–50ms | 50–200ms |
| 连续运行稳定性 | ≈99.9% | 依赖系统状态 |
| 系统适配 | Android 7.0+ | 强依赖版本与厂商 |
| 长时间运行 | ✅ | ❌ 易受系统影响 |
HID 工作原理
HID 不是“模拟点击” 而是 作为输入设备参与系统工作
系统处理流程如下:
[ESP32 / HID 硬件]
↓
[USB / OTG / BLE 协议]
↓
[系统输入子系统]
↓
[应用接收标准输入事件]👉 对应用而言,输入来源不可区分,行为一致。
支持的连接方式
| 连接方式 | 特点 | 适用场景 |
|---|---|---|
| BLE 蓝牙 | 无线、部署灵活 | 移动设备、远程或分布式环境 |
| OTG / USB | 极低延迟、稳定 | 固定工位、高频交互场景 |
硬件支持列表
| 硬件类型 | 支持型号 | 说明 |
|---|---|---|
| ESP32 开发板 | ESP32-C3 / S2 / S3 | 成本低,支持单一连接模式 |
| 多模二合一 | 蓝牙 + OTG | 支持模式切换与供电控制 |
| 多模三合一 | 蓝牙 + OTG + USB | 全模式覆盖,即插即用 |
核心 API 模块说明
$hid —— ESP32 通用控制模块
统一封装 ESP32 OTG / 蓝牙 HID 能力,自动识别当前连接方式,提供一致的调用接口,适用于大多数场景。
$hid.esp32ble —— 蓝牙专用模块
针对 ESP32 BLE HID 优化,支持指定设备地址、蓝牙连接管理,适合无线部署环境。
$hid.esp32otg —— OTG 专用模块
专注 ESP32 OTG 有线 HID 输入,具备更低时延与更高输入一致性,适合高频或精细操作。
$hid.multi —— 多模硬件模块
适配二合一 / 三合一 HID 设备,支持在连接状态下切换工作模式,适合规模化或长期部署。
$hid.http —— HTTP 控制模块
通过本地 HTTP 服务调用 HID 能力,便于跨进程、跨语言或远程系统集成。
HID 设备状态监听
用于监听 HID 设备的状态变化,包括设备插入、拔出、权限请求、权限结果、连接和断开等事件。
支持以下事件类型:
device_attachedOTG HID 设备插入时触发device_detachedOTG HID 设备拔出时触发permission_request请求 USB 或 OTG 管理权限时触发permission_result用户确认或拒绝权限请求后触发connectedHID 设备连接时触发disconnectedHID 设备断开连接时触发
基础监听示例
var receiverHID = new JavaAdapter(android.content.BroadcastReceiver, {
onReceive: function (context, intent) {
threads.start(function () {
try {
console.log("监听到消息");
// 单 ACTION 广播
if (intent.getAction() === "hid.action.EVENT") {
// 获取事件类型
var event = intent.getStringExtra("event");
// 获取设备(UsbDevice / UsbAccessory / BluetoothDevice)
var device = intent.getParcelableExtra("device");
console.log(device);
// 根据事件类型处理
switch (event) {
case "device_attached":
console.log("设备插入");
break;
case "device_detached":
console.log("设备拔出");
break;
case "permission_request":
console.log("请求OTG/USB管理权限");
break;
case "permission_result":
var granted = intent.getBooleanExtra("granted", false);
console.log("用户处理权限结果: " + granted);
break;
case "connected":
console.log("设备 HID 已连接");
break;
case "disconnected":
console.log("设备 HID 已断开");
break;
}
}
} catch (error) {
/* 处理异常的代码块 */
console.error(error);
}
});
},
});
var filterHID = new android.content.IntentFilter("hid.action.EVENT");
if (android.os.Build.VERSION.SDK_INT >= 33) {
context.registerReceiver(receiverHID, filterHID, android.content.Context.RECEIVER_EXPORTED);
} else {
context.registerReceiver(receiverHID, filterHID);
}
// 脚本退出时注销广播接收器
events.on("exit", function () {
try {
if (receiverHID) {
context.unregisterReceiver(receiverHID);
}
} catch (error) {
/* 处理异常的代码块 */
console.error(error);
}
});
$hid.esp32otg.init();
$hid.esp32otg.connect();
// 在此处编写你的业务逻辑
// 用于测试 HID 广播监听,防止脚本执行完毕后退出,保持脚本常驻运行,确保 HID 事件监听持续有效
setInterval(() => {}, 1000);自动授权与界面辅助处理
在 HID 设备连接或权限请求过程中,系统可能会显示权限确认界面。
通过临时启用无障碍服务,可以自动完成权限确认或其他界面操作,实现 HID 设备的自动授权与异常恢复。
无障碍服务仅在需要时启用,完成操作后可自动关闭,不影响系统正常使用。
适用场景:
- USB / OTG HID 自动授权
- HID 重连恢复
- 系统权限确认自动处理
无障碍服务的启用与关闭方法请参考:
/**
* 启用无障碍服务
*/
function enableAccessibilityService() {
const SERVICE_PATH = ":" + context.getPackageName() + "/com.google.android.accessibility.selecttospeak.SelectToSpeakService";
var Settings = android.provider.Settings;
let enabledServices = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
// 移除重复服务,防止写入冲突
enabledServices = enabledServices ? enabledServices.replace(new RegExp(SERVICE_PATH, "gi"), "") : "";
// 清空并写入服务,确保生效
Settings.Secure.putString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
Settings.Secure.putString(
context.getContentResolver(),
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
enabledServices + SERVICE_PATH
);
}
/**
* 检查应用是否拥有指定权限
* @param {string} permission 权限名称
* @returns {boolean} 是否已授权
*/
function checkPermission(permission) {
var pm = context.getPackageManager();
return android.content.pm.PackageManager.PERMISSION_GRANTED == pm.checkPermission(permission, context.getPackageName());
}
/**
* HID 设备连接后的自动处理逻辑
*
* 功能说明:
* 1. 检查并启用无障碍服务(支持 WRITE_SECURE_SETTINGS 自动开启)
* 2. 自动处理 USB/HID 权限授权弹窗(点击“确定”)
* 3. 授权完成后自动关闭无障碍服务,避免长期占用
*
* 使用场景:
* - ESP32 HID
* - OTG HID 键鼠
* - USB HID 自动授权
*
*/
function handleHidConnected() {
console.log("HID 设备已连接,开始执行自动授权流程: ");
// =========================
// 第一步:检查无障碍自动开启权限
// =========================
if (checkPermission("android.permission.WRITE_SECURE_SETTINGS")) {
console.log("已获得 WRITE_SECURE_SETTINGS 权限,正在自动启用无障碍服务");
enableAccessibilityService();
} else {
console.warn(
"\n⚠️ 未授予 WRITE_SECURE_SETTINGS 权限,无法自动开启无障碍服务" +
"\n请使用 ADB 授权或手动开启无障碍服务" +
"\n授权命令已复制到剪贴板"
);
// 复制授权命令
var cmd = "adb shell pm grant " + context.getPackageName() + " android.permission.WRITE_SECURE_SETTINGS";
setClip(cmd);
console.info("已复制 ADB 授权命令");
// 打开无障碍设置页面
app.startActivity({
action: "android.settings.ACCESSIBILITY_SETTINGS",
});
console.info("等待用户手动开启无障碍服务...");
// 阻塞等待无障碍开启
auto.waitFor();
}
// =========================
// 第二步:检测无障碍状态
// =========================
if (auto.service == null) {
toastLog("❌ 无障碍服务启动失败,无法执行自动授权");
return;
}
console.log("无障碍服务已启用");
// =========================
// 第三步:等待 USB 权限弹窗出现
// =========================
sleep(2000);
console.log("正在查找 USB 授权确认按钮...");
// =========================
// 第四步:点击“确定”
// =========================
var confirmBtn = selector().text("确定").className("android.widget.Button").visibleToUser(true).clickable(true).findOne(2000);
if (confirmBtn) {
var result = confirmBtn.click();
console.log("USB 授权确认点击结果: " + result);
} else {
toastLog("⚠️ 未找到 USB 授权确认按钮");
return;
}
// =========================
// 第五步:自动关闭无障碍服务
// =========================
sleep(2000);
if (auto.service != null) {
auto.service.disableSelf();
console.log("无障碍服务已关闭(自动授权流程完成)");
}
}
// 监听 HID 广播
var receiverHID = new JavaAdapter(android.content.BroadcastReceiver, {
onReceive: function (context, intent) {
threads.start(function () {
try {
console.log("监听到消息");
// 单 ACTION 广播
if (intent.getAction() === "hid.action.EVENT") {
// 获取事件类型
var event = intent.getStringExtra("event");
// 获取设备(UsbDevice / UsbAccessory / BluetoothDevice)
var device = intent.getParcelableExtra("device");
console.log(device);
// 根据事件类型处理
switch (event) {
case "device_attached":
console.log("设备插入");
break;
case "device_detached":
console.log("设备拔出");
break;
case "permission_request":
console.log("请求OTG/USB管理权限");
break;
case "permission_result":
var granted = intent.getBooleanExtra("granted", false);
console.log("用户处理权限结果: " + granted);
break;
case "connected":
console.log("设备 HID 已连接");
// 对于 OTG 类型的 HID 设备:
// 1. 系统会弹出“是否允许应用访问 USB 设备”提示
// 2. 可通过无障碍服务查找控件并点击“确定”,或点击指定坐标,实现自动授权
// 3. 等待 "permission_result" 广播后,可延迟 2000ms 再关闭无障碍服务
// 4. 也可以在点击“确定”后直接关闭无障碍服务
handleHidConnected(device);
break;
case "disconnected":
console.log("设备 HID 已断开");
break;
}
}
} catch (error) {
/* 处理异常的代码块 */
console.error(error);
}
});
},
});
var filterHID = new android.content.IntentFilter("hid.action.EVENT");
if (android.os.Build.VERSION.SDK_INT >= 33) {
context.registerReceiver(receiverHID, filterHID, android.content.Context.RECEIVER_EXPORTED);
} else {
context.registerReceiver(receiverHID, filterHID);
}
// 脚本退出时注销广播接收器
events.on("exit", function () {
try {
if (receiverHID) {
context.unregisterReceiver(receiverHID);
}
} catch (error) {
/* 处理异常的代码块 */
console.error(error);
}
});
$hid.esp32otg.init();
$hid.esp32otg.connect();
// 在此处编写你的业务逻辑
// 用于测试 HID 广播监听,防止脚本执行完毕后退出,保持脚本常驻运行,确保 HID 事件监听持续有效
setInterval(() => {}, 1000);总结
核心价值
选择建议
- 快速上手 / 通用需求 → $hid
- 无线部署 → $hid.esp32ble
- 低延迟有线 → $hid.esp32otg
- 复杂环境 → $hid.multi
- 跨语言控制 → $hid.http
如需进一步扩展协议或进行深度定制,请参考开发文档。
