Hid是Human Interface Device的缩写,由其名称可以了解HID设备是直接与人交互的设备,例如键盘、鼠标与游戏手柄等。
我们知道在手机设置--蓝牙功能界面可以手动搜索蓝牙HID设备并进行连接,这篇博客就是介绍如何在android代码中实现HID设备的连接。最后会给出完整的代码工程。一个前提条件是android4.0以上才支持HID设备。
android手机与蓝牙HID设备连接的步骤:
1.开启蓝牙功能
2.手机搜索蓝牙HID设备
3.得到BluetoothDevice,配对HID设备
4.连接HID设备
了解过蓝牙开发的同学相信前面3个步骤都不是问题,本文会重点介绍第四个步骤,前面的步骤简单列出来。
1.开启蓝牙功能

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {Toast.makeText(this,"不支持蓝牙功能",0).show();//不支持蓝牙return;
}
//如果没有打开蓝牙
if (!mBluetoothAdapter.isEnabled()) {mBluetoothAdapter.enable();
}

2.手机搜索蓝牙HID设备

//扫描蓝牙设备
if (!mBluetoothAdapter.isDiscovering()) {mBluetoothAdapter.startDiscovery();
}

3.配对HID设备
搜索到蓝牙设备后系统会发送这个广播
BluetoothDevice.ACTION_FOUND
通过监听这个广播就可以得到BluetoothDevice
//通过广播接收到了BluetoothDevice

final BluetoothDevice localBluetoothDevice = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

然后通过反射配对BluetoothDevice

/*** 配对* @param bluetoothDevice*/
public void pair(BluetoothDevice bluetoothDevice) {device = bluetoothDevice;Method createBondMethod;try {createBondMethod = BluetoothDevice.class.getMethod("createBond");createBondMethod.invoke(device);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}

相信以上步骤大家都十分了解了,下面最重要的部分来了。
4.连接HID设备
找遍所有公开的api中是没用方法可以直接连接HID设备的,既然手机设置-蓝牙界面可以连接HID设备,说明系统是可以做到的,那是不是把这个方法隐藏了,我们带着这个疑问去源码看看。
1)首先我们找到android/bluetooth/BluetoothProfile.class这个类
为什么是先找到这个类?
Bluetooth的一个很重要特性,就是所有的Bluetooth产品都无须实现全部的Bluetooth规范。为了更容易的保持Bluetooth设备之间的兼容,Bluetooth规范中定义了Profile。Profile定义了设备如何实现一种连接或者应用,你可以把Profile理解为连接层或者应用层协议。
所以我们要先确认HID设备属于哪种Profile。

/*** Input Device Profile* @hide*/
public static final int INPUT_DEVICE = 4;

找到定义的INPUT_DEVICE,这就是我们HID设备的Profile,字面意思就是输入设备。
2)找到BluetoothProfile的子类BluetoothInputDevice
查看到该类里面的connect方法,入参BluetoothDevice,我们通过步骤三已经得到BluetoothDevice,我们大胆猜想是不是调用这个方法就可以实现连接了呢。

/*** Initiate connection to a profile of the remote bluetooth device.** <p> The system supports connection to multiple input devices.** <p> This API returns false in scenarios like the profile on the* device is already connected or Bluetooth is not turned on.* When this API returns true, it is guaranteed that* connection state intent for the profile will be broadcasted with* the state. Users can get the connection state of the profile* from this intent.** <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}* permission.** @param device Remote Bluetooth Device* @return false on immediate error,*               true otherwise* @hide*/
public boolean connect(BluetoothDevice device) {if (DBG) log("connect(" + device + ")");if (mService != null && isEnabled() && isValidDevice(device)) {try {
            return mService.connect(device);} catch (RemoteException e) {Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
            return false;}}if (mService == null) Log.w(TAG, "Proxy not attached to service");
    return false;
}

我们再来看下该类的说明

/*** This class provides the public APIs to control the Bluetooth Input* Device Profile.**<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth* Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get* the BluetoothInputDevice proxy object.**<p>Each method is protected with its appropriate permission.*@hide*/

首先注意到该类是个隐藏类并不能直接调用,调用方法已经进行说明了。通过BluetoothAdapter#getProfileProxy方法得到隐藏类BluetoothInputDevice

3)BluetoothAdapter#getProfileProxy方法

* @param context Context of the application* @param listener The service Listener for connection callbacks.* @param profile The Bluetooth profile; either {@link BluetoothProfile#HEALTH},*                {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#A2DP}.*                {@link BluetoothProfile#GATT} or {@link BluetoothProfile#GATT_SERVER}.* @return true on success, false on error*/
public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,int profile)

第一个参数就不用说了,我们先看第三个参数 int profile,前面介绍了INPUT_DEVICE,这就是我们HID设备的Profile,我们看到也是隐藏字段,所以我们必须先通过反射获得这个参数。方法如下:

public static int getInputDeviceHiddenConstant() {Class<BluetoothProfile> clazz = BluetoothProfile.class;for (Field f : clazz.getFields()) {int mod = f.getModifiers();if (Modifier.isStatic(mod) && Modifier.isPublic(mod)&& Modifier.isFinal(mod)) {try {if (f.getName().equals("INPUT_DEVICE")) {return f.getInt(null);}} catch (Exception e) {}}}return -1;
}

那我们再看第二个参数BluetoothProfile.ServiceListener,这个参数可以回调出BluetoothInputDevice,然后再反射connect方法。

/***查看BluetoothInputDevice源码,connect(BluetoothDevice device)该方法可以连接HID设备,但是查看BluetoothInputDevice这个类* 是隐藏类,无法直接使用,必须先通过BluetoothProfile.ServiceListener回调得到BluetoothInputDevice,然后再反射connect方法连接**/
private BluetoothProfile.ServiceListener connect = new BluetoothProfile.ServiceListener() {@Overridepublic void onServiceConnected(int profile, BluetoothProfile proxy) {//BluetoothProfile proxy这个已经是BluetoothInputDevice类型了try {if (profile == getInputDeviceHiddenConstant()) {if (device != null) {//得到BluetoothInputDevice然后反射connect连接设备Method method = proxy.getClass().getMethod("connect",new Class[] { BluetoothDevice.class });method.invoke(proxy, device);}}} catch (Exception e) {// TODO Auto-generated catch block// e.printStackTrace();}}@Overridepublic void onServiceDisconnected(int profile) {}
};

最后HID设备连接成功,事实证明我们的猜想是正确的。
项目下载地址:
https://github.com/liushenwenyuan/HIDConnect
http://download.csdn.net/detail/szydwy/9546246

Android HID设备的连接相关推荐

  1. android设备如何苹果,Android安卓设备如何连接Mac的方法

    Android安卓设备如何连接Mac的方法 本篇文章主要给大家总结了安卓设备连接MAC电脑的方法以及中间遇到连接问题以后的处理办法. 平时大家用到最多的就是安卓手机和苹果电脑互连,由于安卓系统应用广泛 ...

  2. android拷贝设备断连接,android – Firebase Messaging Inactivity,断开与AppMeasurementService的连接[复制]...

    参见英文答案 > V/FA: Processing queued up service tasks: 1 followed by V/FA: Inactivity,disconnecting f ...

  3. android byte[] 转string 好多问号_#WIPI# Android使用HID设备

    哈罗大家好.生活总是这样计划赶不上变化,今天为大家分享一下新加的小功能--使用Android设备连接HID设备. 安卓内部已经内置了丰富的驱动,所以一般的设备我们只需要简单是设置就可灵活使用. 首先对 ...

  4. android获取wifi连接状态,获取android设备wifi连接状态

    本文将介绍如何获取android设备wifi连接状态! 添加访问权限(AndroidManifest.xml文件里) Java代码(MainActivity.java文件) package com.e ...

  5. android ble 实现自动连接,Android:自动重新连接BLE设备

    经过多次试验和磨难之后,这就是我最好让Android自动连接的唯一用户操作是首先选择设备(如果使用设置菜单然后首先配对). 您必须将配对事件捕获到BroadcastReceiver中并执行Blueto ...

  6. 路由器有一个android设备连接不上,Android http连接 – 多个设备无法连接同一台服务器...

    我真的需要帮助-- 我有一个简单的Android应用程序连接到我的服务器以通过HTTPS获取数据. 一切正常,直到我从另一台设备(iOS或Android)连接到同一台服务器.我开始得到超时或连接被拒绝 ...

  7. android跳过网络连接,绕过Android Android的Wi-Fi热点5设备连接限制 | MOS86

    几乎每个智能手机都提供的Wi-Fi个人热点功能非常有用,但是大多数的小提供商都可以连接到Wi-Fi热点的设备数量上限.通常,连接限制最多可提供3到5个设备连接,但是如果您发现自己处于需要超过最大设备分 ...

  8. android 多个蓝牙连接电脑,Android BLE蓝牙多设备连接

    多设备连接的问题很典型,一方面实际应用中存在同时和多个设备通信的场景,另一方面蓝牙连接较耗时,如果能尽可能保持连接,则可省去不少时间,用户体验更好. 然而多设备连接也有一些问题要注意,有以下几点: 一 ...

  9. android 外接扫码枪_Android手机(设备)连接扫描枪扫码遇到的问题

    以下内容以我发布前的时间为准,可能之后厂商给设备改进后都没有这些问题. 1.android手机连接扫描枪有些手机显示不了系统键盘 2.连接扫描枪使用的是百度输入法,条码是字母数字组合的扫码会出现乱码( ...

最新文章

  1. BZOJ1202: [HNOI2005]狡猾的商人
  2. CF908D New Year and Arbitrary Arrangement
  3. 计算机二级考试Access教程
  4. 【Qt教程】1.6 - Qt5信号与槽、Single Slot emit、自定义信号、自定义槽
  5. Layui图片上传限制一张的问题
  6. 陈纪修老师《数学分析》 第01章:集合与映射 笔记
  7. Springboot项目整合JSP模板引擎
  8. 高等数学第六版上册答案
  9. 未受信任的企业级开发者怎么设置
  10. c语言中特殊符号怎么定义,C语言特殊符号意义
  11. 杰奇 v1.7去限制版橙色模板小说源码
  12. TalkingData的移动大数据探索:联合Kochava发布移动广告监测国际版
  13. 短信验证码接收不到原因和解决方案分析
  14. PDPS软件:3D空间扫描功能介绍与使用方法
  15. mysql查看表存不存在
  16. jFreeChart+itext生成带统计图的pdf文件
  17. 模型训练之决策树、随机森林、提升树
  18. 天梯选拔:先序序列创建二叉树,输出先序序列、中序序列、后序序列并输出叶子结点数
  19. 中兴U880 完美版2.3.7第三弹炫目登场,你还在为刷机而烦恼?来吧!它值得你拥有!!!!
  20. 开学返校学生党耳机推荐,连接稳定的无线蓝牙耳机分享

热门文章

  1. SQLStudio下载
  2. Ai智能语音机器人系统搭建和私有云部署
  3. 大O表示法初学者指南
  4. Java数组:一维数组的定义和赋值
  5. java小基础之代码块的霸道
  6. MFC中CreateCompatibleDC的作用
  7. rabbitmq用户及vhost配置
  8. 计算机硬件更新快,频繁更新电脑硬件驱动程序到底好不好?真相在此
  9. 3NF、BCNF和4NF基本概念和分解
  10. 测试sd卡读写速度与判断是否是扩容的假货