Bluetooth HID device 鼠标模拟触摸屏以及Android的back,home键的实现

蓝牙HID device Role 可以支持鼠标,键盘,协议栈的部分就不说了,主要是需要input report,output report等的处理.

第一步我们是考虑直接在鼠标这个类型上来模拟触屏的操作,大家都知道,鼠标是报告相对坐标的input设备,而触摸屏是报告绝对坐标的,因此我们必须将从远程屏幕上获得的绝对坐标转为相对坐标.然后组成input report.

hid一个很重要的东西是report descriptor,报告描述符,这个标准可以在USB联盟的网页上找到.

但鼠标一般是短距离连续移动,一般在网上找到的描述符里report size都是8bit,逻辑最大值和最小值是-127到127,可是屏幕的范围就远不止这么大,起先我们考虑的是分段移动,一次移动127,如果总共要移动500,就分成4次连续移动,但是这些input事件从Android手机侧收到之后,从input设备节点读到的事件都对,但到inputreader往上的处理之后就变得很奇怪,在屏幕上无规则的严重偏移.

于是我们进行了如下修改:

   1, 修改HID descriptor, 扩大X,Y的范围到(-4096,4095),将 X和Y的report size扩大为32bit(即4个字节)
   2,扩大report buffer到10 字节,用4个byte存储x坐标,4个byte存储y坐标,这4个byte是由一个32个bit的int型的坐标值拆成4段得到的,存储的时候,低位在 前,高位在后.
   3,发送button up和button down的report的时候,有效位是buffer[0].将buffer[1]~buffer[8]里都填充0.
   4,程序初始化的时候,坐标初始点为屏幕中心,第一次移动是从中心点移动到当前位置,每次移动之后,记录当前位置供下次移动时计算差值.

这样改过之后,基本上单点点击都比较准,但如果快速多次点击的话,还是会出现input节点拿到的事件都对,屏幕显示上的坐标却乱跳的情况.还有待研究.不知道是不是Android对相对坐标支持的局限性,我们也考虑干脆用touchscreen的描述符来做.


模拟home,back键比较简单,这两个按键不是标准键盘按键,需要在描述符里自定义键值,实现要点如下:

在HID descriptor里增加Input report,定义Home和Back的键值,分别是0a 23 02 (即0x0223),0a 24 02(即0x0224), 顺序是back在前,home在后, input report 设定report id =3(数值应该是自定义的,与鼠标和其他键盘的报告id区分开就行) ,单独列出或合并在键盘的那些项目里都可,report size是1bit,count是2,填充6bit的0,拼成一个字节,第一个bit表示back,第二个bit表示home,也就是在report 里,buffer是1byte,back是0x01,home是0x02,如果前面定义home在前,back在后,则home是 0x01,back是0x02.

<think>好的,用户的问题是关于如何在Android平台上通过HID模拟触摸屏操作,特别是想了解相关的API和教程。首先,我需要回忆一下之前提供的引用内容,看看有没有相关的信息。引用1提到了通过写入/dev/input/event来模拟触摸事件,引用2和3则涉及使用BluetoothHidDeviceHID描述符来实现HID设备模拟。用户的需求是模拟触摸屏操作,而HID通常用于盘、鼠标等设备,但触摸屏属于多点触控设备,可能需要特定的HID描述符。引用3中提到Android HID多点触摸设备描述符的调试,这可能是一个关点。需要确认AndroidHID API是否支持多点触控,以及如何配置描述符。 接下来,我需要整理步骤。首先,可能需要申请HID设备权限,然后配置正确的报告描述符,特别是触摸屏的部分。然后通过HID报告发送触摸事件的数据。同时,可能需要考虑蓝牙HID或USB HID的不同方式,因为引用2提到了蓝牙,而引用3是USB。另外,用户可能需要具体的代码示例,比如如何初始化HID设备,如何构造触摸报告的数据结构。还要注意权限问题,比如BluetoothHidDevice需要特定的权限,并且设备需要配对。需要确保回答结构清晰,分步骤说明,并引用相关的参考资料。同时,生成的问题要围绕可能相关的深入点,比如性能优化、多点触控实现或兼容性问题。</think>根据Android HID协议和触摸事件模拟原理,以下是实现触摸屏模拟的完整技术路径: ### 一、HID设备注册流程 1. 创建BluetoothHidDevice实例 ```java BluetoothHidDevice hidDevice = BluetoothAdapter.getDefaultAdapter() .getProfileProxy(context, serviceListener, BluetoothProfile.HID_DEVICE); ``` 2. 注册HID服务描述符 需配置包含触摸屏功能的HID报告描述符,典型结构如下: $$ 0x05, 0x0D, // Usage Page (Digitizers) 0x09, 0x04, // Usage (Touch Screen) 0xA1, 0x01, // Collection (Application) 0x09, 0x22, // Usage (Finger) 0xA1, 0x02, // Collection (Logical) 0x09, 0x42, // Usage (Tip Switch) 0x15, 0x00, // Logical Minimum (0) 0x25, 0x01, // Logical Maximum (1) 0x75, 0x01, // Report Size (1) 0x95, 0x01, // Report Count (1) 0x81, 0x02, // Input (Data,Var,Abs) 0x09, 0x32, // Usage (In Range) 0x81, 0x02, // Input (Data,Var,Abs) 0x09, 0x47, // Usage (Touch Valid) 0x81, 0x02, // Input (Data,Var,Abs) 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x30, // Usage (X) 0x09, 0x31, // Usage (Y) 0x16, 0x00, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x7F, // Logical Maximum (32767) 0x75, 0x10, // Report Size (16) 0x95, 0x02, // Report Count (2) 0x81, 0x02, // Input (Data,Var,Abs) 0xC0, // End Collection 0xC0 // End Collection $$ 该描述符定义了触摸点坐标范围为$0-32767$,支持触点有效性检测[^3] ### 二、触摸事件发送实现 1. 构造触摸报告数据结构 ```java byte[] reportData = new byte[5]; // 触点状态 (1字节) reportData[0] = (byte) (isTouching ? 0x01 : 0x00); // X坐标 (2字节) reportData[1] = (byte) (x & 0xFF); reportData[2] = (byte) ((x >> 8) & 0xFF); // Y坐标 (2字节) reportData[3] = (byte) (y & 0xFF); reportData[4] = (byte) ((y >> 8) & 0xFF); ``` 2. 发送HID报告 ```java hidDevice.sendReport(bluetoothDevice, REPORT_ID, reportData); ``` ### 三、关配置要求 1. 需要声明`BLUETOOTH_PRIVILEGED`权限 2. 目标设备必须已配对且启用HID服务 3. 坐标值需转换为设备分辨率对应的比例值,例如: $$ x_{hid} = \frac{x_{real} \times 32767}{screenWidth} $$ ### 四、调试技巧 1. 使用`getevent`命令监听输入事件流 ```shell adb shell getevent -lt /dev/input/eventX ``` 2. 通过`uinput`模块创建虚拟输入设备[^1] 3. 使用Wireshark捕获蓝牙HID协议数据包
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值