文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-10-27 05:13

关注

目录

一,背景介绍

二,技术方案

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() {        @Override        public void onServiceDisconnected(int profile) {            Log.e(TAG, "hid onServiceDisconnected");            if (profile == BluetoothProfile.HID_DEVICE) {                mHidDevice.unregisterApp();            }        }        @SuppressLint("NewApi")        @Override        public 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});


 

需要源码,请私信

来源地址:https://blog.csdn.net/allen_xu_2012_new/article/details/131973441

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯