1 Hid简介

HID设备(Hunman Interface Device Profile),即人机交互设备,常见的有鼠标,键盘,游戏手柄,等等。一般有线方式都是通过USB连线连接到机器设备,作为用户输入设备。在蓝牙技术中,HID设备的接入就是无线的了。

网上查资料说hid从android4.0开始支持(可能是usb hid),不过蓝牙hid应该从android4.2开始支持的,如下图所示:

android4.1.2中的Bluetooth应用中没有hid的相关代码,而android4.2源码中Bluetooth应用中才有hid的代码。

Android 蓝牙Hid 开发_java

   Android 蓝牙Hid 开发_java_02

 


2 主要代码

 

连接hid设备步骤:

  1. 开启蓝牙

  2. 获得inputDevice profile

  3. 扫描

  4. 配对

  5. 连接

 

 

2.1 开启蓝牙,注册广播接收者监听蓝牙相关状态。

Android 蓝牙Hid 开发_java_03

 

2.2 获得inputDevice profile

// 4.2以上才支持HID模式

if (Build.VERSION.SDK_INT >= 17) {

    mHidUtil = HidUtil.getInstance(this);

}

Android 蓝牙Hid 开发_java_04

通过BluetoothAdapter对象调用getProfileProxy()函数获取代理蓝牙输入设备代理对象。

其中参数mListener必须实现BluetoothProfile.ServiceListener()。获取代理对象成功或失败都会回调该Listener。

 

Android 蓝牙Hid 开发_java_05

当连接代理服务成功,回调onServiceConnected()函数,失败则回调onServiceDisconnected()函数。
其中onServiceConnected()中的参数proxy类型为BluetoothProfile,这里因为获取BluetoothHeadset、BluetoothA2dp对象也要使用该回调函数,所以参数类型设置为BluetoothInputDevice、BluetoothHeadset、BluetoothA2dp的父类。这里可以将其转换成BluetoothInputDevice类型(BluetoothInputDevice是BluetoothProfile的子类)。
获取到输入设备的代理对象,之后就可以进行连接操作了。

 

2.3 扫描(点击连接按钮开始扫描蓝牙设备)

mBluetoothAdapter.startDiscovery(); 

 

2.4 配对

广播接收者监听扫描到的蓝牙设备,过滤出所需蓝牙设备进行配对,如果之前配对过则直接连接。

Android 蓝牙Hid 开发_java_06

HidUtil类中的配对方法:

Android 蓝牙Hid 开发_java_07

 

2.5 连接(配对成功后)

Android 蓝牙Hid 开发_java_08

判断是否是要连接的输入设备,如果符合条件则进行连接。

HidUtil中connect 方法:

Android 蓝牙Hid 开发_java_09

BluetoothInputDevice中的connect方法是隐藏的,所以需要通过反射机制获取该方法进行调用。

 

2.6 监听连接状态 

通过广播接收者监听连接状态。

Android 蓝牙Hid 开发_java_10

 

2.7 断开连接

HidUtil中disconnect方法

Android 蓝牙Hid 开发_java_11

注意:手机端断开连接后,重新连接会提示“只能有鼠标发起重新连接请求,请使用鼠标重新连接”。

 


3 接收数据

adb shell;

getevent -l

通过getevent查看原始输入事件。

当连接成功后,会看到如下内容:

could not get driver version for /dev/input/mouse1, Not a typewriter
add device 7: /dev/input/event6
  name:     "Bluetooth Mouse"

这表示蓝牙鼠标成为一个输入设备。

左击鼠标:

/dev/input/event6: EV_MSC       MSC_SCAN             00090001   
/dev/input/event6: EV_KEY       BTN_MOUSE            DOWN        
/dev/input/event6: EV_SYN       SYN_REPORT           00000000  
/dev/input/event6: EV_MSC       MSC_SCAN             00090001  
/dev/input/event6: EV_KEY       BTN_MOUSE            UP
/dev/input/event6: EV_SYN       SYN_REPORT           00000000

我们应用中打印

03-13 12:08:36.526 I/MainActivity(23670): dispatchTouchEvent ev:MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=269.7555, y[0]=543.9628, toolType[0]=TOOL_TYPE_MOUSE, buttonState=BUTTON_PRIMARY, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=16788085, downTime=16788085, deviceId=39, source=0x2002 }
03-13 12:08:36.653 I/MainActivity(23670): dispatchTouchEvent ev:MotionEvent { action=ACTION_UP, actionButton=0, id[0]=0, x[0]=269.7555, y[0]=543.9628, toolType[0]=TOOL_TYPE_MOUSE, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=16788216, downTime=16788085, deviceId=39, source=0x2002 }

表示在屏幕中某位置处点击了一下。

 

右击鼠标:

/dev/input/event6: EV_MSC       MSC_SCAN             00090002  
/dev/input/event6: EV_KEY       BTN_RIGHT            DOWN          
/dev/input/event6: EV_SYN       SYN_REPORT           00000000  
/dev/input/event6: EV_MSC       MSC_SCAN             00090002  
/dev/input/event6: EV_KEY       BTN_RIGHT            UP                  
/dev/input/event6: EV_SYN       SYN_REPORT           00000000

//下面是在代码中加的一点打印,便于看事件。

03-13 12:09:48.147 I/MainActivity(23670): dispatchKeyEvent event:KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0x0, hwFlags=0x0, repeatCount=0, eventTime=16859701, downTime=16859701, deviceId=39, source=0x2002 }
03-13 12:09:48.147 I/MainActivity(23670): onKeyDown keyCode=4
03-13 12:09:48.308 I/InputDispatcher(  996): touch process [23670], send to pg
03-13 12:09:48.327 I/MainActivity(23670): dispatchKeyEvent event:KeyEvent { action=ACTION_UP, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0x0, hwFlags=0x0, repeatCount=0, eventTime=16859870, downTime=16859870, deviceId=39, source=0x2002 }
03-13 12:09:48.327 I/MainActivity(23670): onKeyUp keyCode=4
03-13 12:09:48.337 I/MainActivity(23670): onBackPressed

表示点击了一下返回键,程序退出。

移动鼠标会发现屏幕上小光标在移动,滑动鼠标也会触发相应事件。

 


 

4 其他

现在大部分手机是支持hid的,并且也将该功能打开状态。

如果是做系统开发,就需要注意将Bluetooth中的hid开关打开。

将源码中的packages/apps/Bluetooth/res/values/config.xml的profile_supported_hid 修改为true。

<bool name="profile_supported_hid">true</bool>

 

demo下载地址:http://download.csdn.net/detail/vnanyesheshou/9815127。

https://mp.weixin.qq.com/s/l4YRHoCHVDZvRxBf8yhPdQ