2010-11-24 61 views
6

我已經編寫了一個連接到藍牙鍵盤的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)。

回答

4

所有正常的藍牙鍵盤都實現了需要L2CAP連接的HID配置文件。迄今爲止,Android僅提供使用RFCOMM連接的能力。您需要使用本地開發工具包,並使用C編寫您的鍵盤代碼以實現您的目標。看看使用任天堂WiiMote的應用程序。 WiiMote還實現了HID配置文件。

+0

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

1

有些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支持。

2

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協議在所有設備上都不可用,因此目前無法在所有設備上運行解決方案。