2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > Android设备通过蓝牙HID技术模拟鼠标技术实现

Android设备通过蓝牙HID技术模拟鼠标技术实现

时间:2020-02-18 14:40:14

相关推荐

Android设备通过蓝牙HID技术模拟鼠标技术实现

目录

一,背景介绍

二,技术方案

2.1 获取BluetoothHidDevice实例

2.2 注册/解除注册HID实例

2.3 Hid report description描述符生成工具

2.4 通过sendReport想host发送按键信息

一,背景介绍

日常生活中,各种物理遥控器和鼠标等设备,需要摆放和携带,便捷性有待考验。根据蓝牙HID特性,可以用蓝牙协议模仿鼠标事件,来实现空中鼠标等功能。

二,技术方案

自Android 9开放BluetoothHidDevice功能后,Android平台可以很简单的通过BluetoothHidDevice模拟键盘鼠标等蓝牙hid device角色。

2.1 获取BluetoothHidDevice实例

BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();bluetoothAdapter.setName("MOUSE BT");bluetoothAdapter.getProfileProxy(context,mProfileServiceListener,BluetoothProfile.HID_DEVICE);

2.2 注册/解除注册HID实例

public static BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() {@Overridepublic void onServiceDisconnected(int profile) {Log.e(TAG, "hid onServiceDisconnected");if (profile == BluetoothProfile.HID_DEVICE) {mHidDevice.unregisterApp();}}@SuppressLint("NewApi")@Overridepublic void onServiceConnected(int profile, BluetoothProfile proxy) {Log.e(TAG, "hid onServiceConnected");bluetoothProfile = proxy;if (profile == BluetoothProfile.HID_DEVICE) {mHidDevice = (BluetoothHidDevice) proxy;HidConsts.HidDevice = mHidDevice;BluetoothHidDeviceAppSdpSettings sdp = new BluetoothHidDeviceAppSdpSettings(HidConsts.NAME, HidConsts.DESCRIPTION, HidConsts.PROVIDER, BluetoothHidDevice.SUBCLASS1_COMBO, HidConsts.Descriptor);mHidDevice.registerApp(sdp, null, null, Executors.newCachedThreadPool(), mCallback);}}};

在获取到BluetoothHidDevice实例后通过registerApp注册hid device,此时hid host角色会被禁用,因此在不需要hid device功能时要及时解除hid device的注册。

registerApp函数中最重要的一个参数BluetoothHidDeviceAppSdpSettings,主要是给对端host提供hid device角色的名称,描述信息,供应商信息,以及Hid device的Reports Descriptor。

2.3 Hid report description描述符生成工具

参考文章《官网HID描述符工具》

public class HidConfig {

public final static String NAME = "My Keyboard";

public final static String DESCRIPTION = "Lgd's Keyboard";

public final static String PROVIDER = "Lgd";

public static final byte[] KEYBOARD_DESCRIPTOR =

{

(byte) 0x05, (byte) 0x01, // USAGE_PAGE (Generic Desktop)

(byte) 0x09, (byte) 0x06, // USAGE (Keyboard)

(byte) 0xa1, (byte) 0x01, // COLLECTION (Application)

(byte) 0x85, (byte) 0x02, //REPORT_ID (2)

(byte) 0x05, (byte) 0x07, // USAGE_PAGE (Keyboard)

(byte) 0x19, (byte) 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)

(byte) 0x29, (byte) 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)

(byte) 0x15, (byte) 0x00, // LOGICAL_MINIMUM (0)

(byte) 0x25, (byte) 0x01, // LOGICAL_MAXIMUM (1)

(byte) 0x75, (byte) 0x01, // REPORT_SIZE (1)

(byte) 0x95, (byte) 0x08, // REPORT_COUNT (8)

(byte) 0x81, (byte) 0x02, // INPUT (Data,Var,Abs)

(byte) 0x95, (byte) 0x01, // REPORT_COUNT (1)

(byte) 0x75, (byte) 0x08, // REPORT_SIZE (8)

(byte) 0x81, (byte) 0x03, // INPUT (Cnst,Var,Abs)

(byte) 0x95, (byte) 0x05, // REPORT_COUNT (5)

(byte) 0x75, (byte) 0x01, // REPORT_SIZE (1)

(byte) 0x05, (byte) 0x08, // USAGE_PAGE (LEDs)

(byte) 0x19, (byte) 0x01, // USAGE_MINIMUM (Num Lock)

(byte) 0x29, (byte) 0x05, // USAGE_MAXIMUM (Kana)

(byte) 0x91, (byte) 0x02, // OUTPUT (Data,Var,Abs)

(byte) 0x95, (byte) 0x01, // REPORT_COUNT (1)

(byte) 0x75, (byte) 0x03, // REPORT_SIZE (3)

(byte) 0x91, (byte) 0x03, // OUTPUT (Cnst,Var,Abs)

(byte) 0x95, (byte) 0x06, // REPORT_COUNT (6)

(byte) 0x75, (byte) 0x08, // REPORT_SIZE (8)

(byte) 0x15, (byte) 0x00, // LOGICAL_MINIMUM (0)

(byte) 0x25, (byte) 0x65, // LOGICAL_MAXIMUM (101)

(byte) 0x05, (byte) 0x07, // USAGE_PAGE (Keyboard)

(byte) 0x19, (byte) 0x00, // USAGE_MINIMUM (Reserved (no event indicated))

(byte) 0x29, (byte) 0x65, // USAGE_MAXIMUM (Keyboard Application)

(byte) 0x81, (byte) 0x00, // INPUT (Data,Ary,Abs)

(byte) 0xc0 // END_COLLECTION

};

}

上面的描述符只是适配键盘,可以不定义report id,如果是多个hid功能复合的设备,例如复合键盘鼠标,就需要再添加鼠标的报告描述符,同时每个功能都需要有对应的report id。

0x05, 0x01, // USAGE_PAGE (Generic Desktop)

0x09, 0x02, // USAGE (Mouse)

0xa1, 0x01, // COLLECTION (Application)

0x85, 0x01, // REPORT_ID (1)

0x75, 0x10, // REPORT_SIZE (16)

0x95, 0x01, // REPORT_COUNT (1)

0x15, 0x0b, // LOGICAL_MINIMUM (11)

0x25, 0x1c, // LOGICAL_MAXIMUM (28)

0x09, 0x30, // USAGE (X)

0x81, 0x22, // INPUT (Data,Var,Abs,NPrf)

0xc0, // END_COLLECTION

0x09, 0x06, // USAGE (Keyboard)

0xa1, 0x01, // COLLECTION (Application)

0x85, 0x02, // REPORT_ID (2)

0x75, 0x08, // REPORT_SIZE (8)

0x95, 0x01, // REPORT_COUNT (1)

0x15, 0x00, // LOGICAL_MINIMUM (0)

0x25, 0x40, // LOGICAL_MAXIMUM (64)

0x09, 0x31, // USAGE (Y)

0x81, 0x02, // INPUT (Data,Var,Abs)

0xc0

2.4 通过sendReport想host发送按键信息

第二个参数是report description中定义的report id,如果没有定义传入0。

第三个参数是按键数据,根据report description,总共有8字节,前2字节是功能键,后6字节是对应的键值信息

mHidDevice.sendReport(device, 2, new byte[]{0, 0, (byte) code, 0, 0, 0, 0, 0});

需要源码,请私信

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。