如何与蓝牙键盘通话?

问题描述:

我已经编写了一个连接到蓝牙键盘的Android应用程序。它通过BT套接字连接到键盘并获取套接字的输入流。如何与蓝牙键盘通话?

InputStream inStrm = socket.getInputStream(); 

接下来我尝试读取输入流,但它说没有可用的字节。

int nBytesAvail = inStrm.available(); // always gives me 0 

或者

int dataByte = inStrm.read(); // always generates IOException 

异常说:软件导致连接中止

如果我尝试写流,我得到另一个异常:运输端点没有连接。

有两件事情可以发生。

  1. 我的第一个担心的是,没有要讲给键盘HID协议,直到我说出正确的咒语也不会泄露自己的秘密。那是对的吗?还是应该由BT套接字堆栈自动照顾?套接字流似乎是一个标准的串行流,我不确定这是否正确。我的第二个担心是,因为这是一个Galaxy Tab,我的问题可能只是三星已经删除了该操作系统的特定部分(但是我仍然会从套接字连接中获得有效的输入流吗?) 。据广泛报道,虽然BT文件传输确实工作正常,但美国版本的Tab无法使用标准Android BT实用程序连接到任何BT HID。

我想第三种可能性是,我只是在发生键盘输入时丢失了键盘。我不知道从HID传入的Java数据是如何缓冲Java的,但是如果套接字连接成功,数据应该出现在输入流中,不是吗?

我不愿意把更多的时间放在这里,以防万一我以完全错误的方式去讨论它(见#1),或者它注定要失败(见#2)。

所有正常的蓝牙键盘都实现了需要L2CAP连接的HID配置文件。迄今为止,Android仅提供使用RFCOMM连接的能力。您需要使用本地开发工具包,并使用C编写您的键盘代码以实现您的目标。看看使用任天堂WiiMote的应用程序。 WiiMote还实现了HID配置文件。

+0

你也可以使用反射和java代码,就像我在上面发布的例子。 – radhoo 2012-01-12 20:29:56

有些Galaxy Tabs支持HID协议,有些则不支持。这取决于运营商,而不是三星。即使T-Mobile手机拥有它,我的Verizon Galaxy Tab也没有支持HID。但今年4月,Verizon(不是三星)推出了包含HID支持的固件升级,所以我的BT键盘&鼠标开始工作。我使用的是Android 2.2,我的固件版本号是SCH-I800.EC02。

这是我的猜测,您正在尝试这样做,因为您的选项卡根本不会连接到BT键盘。这正是我在四月之前想要做的。从我记忆中看,魔咒部分应该由Android自动处理:当你制作HID连接时,Android弹出一个消息窗口在键盘上输入一个代码,然后套接字连接返回到你的程序中或者这个效果的东西)。

因此,如果您无法正常连接到键盘,那么您的HID配置文件已被禁用,并且(afaik)编程不会使其工作,除非可能重写Java中的HID配置文件。

我相信你已经试过了,但要测试它到设置>无线和网络>蓝牙设置,你应该看到列表中的键盘是否有HID支持。点击键盘输入,它应该立即连接。如果它只是无限期地延迟或者如果您收到错误消息,那么您没有HID支持。

mringwal的答案是正确的,除了NDK的方法,也可以使用反射在某些设备上,实现L2CAP连接:

public static BluetoothSocket createL2CAPBluetoothSocket(String address, int psm){ 
     return createBluetoothSocket(TYPE_L2CAP, -1, false,false, address, psm); 
    } 
    // method for creating a bluetooth client socket 
    private static BluetoothSocket createBluetoothSocket(
      int type, int fd, boolean auth, boolean encrypt, String address, int port){ 
     try { 
      Constructor<BluetoothSocket> constructor = BluetoothSocket.class.getDeclaredConstructor(
        int.class, int.class,boolean.class,boolean.class,String.class, int.class); 
      constructor.setAccessible(true); 
      BluetoothSocket clientSocket = (BluetoothSocket) 
       constructor.newInstance(type,fd,auth,encrypt,address,port); 
      return clientSocket; 
     }catch (Exception e) { return null; } 
    } 

其中TYPE_L2CAP是具有恒定值3

整数

请注意,这种方法只适用于某些android设备。

编写HID应用程序不是一项简单的任务。您需要实现报告描述符解析器,这是一个用于“发现”远程HID设备的功能(特殊键,功能)的组件。 您还需要学习HID协议和工作流程,副本,请访问: http://www.dawidurbanski.pl/public/download/projekty/bluepad/HID_SPEC_V10.pdf

已经有专业的方案正是这样做的,在Android上支持HID,例如参见该软件:http://teksoftco.com/index.php?section=product&pid=24

由于堆栈限制,L2CAP协议在所有设备上都不可用,因此目前无法在所有设备上运行解决方案。