android 藍牙通信常見異常 Service discovery failed ,conn...

用Android 開發一個應用,其中想使用藍牙來作數據交換。服務器

先查了一下資料,感受還算簡單,因而就開始了一成天的痛苦歷程。socket

基本上用discover之類的可以很快的發現對方的藍牙設備,可是在spa

創建socket的時候,就出了一堆問題。剛開始,服務端用server

adapter.listenUsingRfcommWithServiceRecordip

加上某個UUID來監聽,同時得到serverSocket,客戶端用 開發

serverDevice.createRfcommSocketToServiceRecordget

來獲取socket,而後就在 socket.connect的時候,出了不少it

奇怪的錯誤。io

最開始是 Service discovery failed ,class

而後是 connection refused,

而後是 File descriptor in bad state

總之搜索了一下,確實千奇百怪的錯誤都有。後來看到有人用

Method m = serverDevice.getClass().getMethod( "createRfcommSocket", new Class[]{int.class});

BluetoothSocket socket = (BluetoothSocket) m.invoke( serverDevice, Integer.valueOf( 1));


聽說能解決,嘗試了一下,也是有時成功有時失敗,極不穩定。

再後來,仔細考慮了一下,其實 createRfcommSocket 這個方法,指定鏈接的是 1號端口,
而服務端則仍是用UUID來啓動服務,至於其綁定了哪一個端口,實際上是不可知的。
最開始客戶端用 createRfcommSocketToServiceRecord 這個方法,實際上是利用UUID去找到
相應的服務,只不過不知道是否是個人UUID的問題,致使它找不到,因此報 service discovery failed這個錯。
而直接用反射的方法去訪問 1號端口,若是湊巧服務端也是在1號端口監聽,那就沒問題。若是不是,
而且沒有服務在監聽,就會報connection refused這個錯。若是有別的服務在監聽,而後又不理解
個人這個協議,就會報 File descriptor in bad state 這個錯。

想明白了,解決起來也就容易。辦法是在啓動服務的時候,也用反射

Method listenMethod = btClass.getMethod("listenUsingRfcommOn", new Class[]{int.class});
BluetoothServerSocket returnValue = ( BluetoothServerSocket) listenMethod.invoke(btAdapter, new Object[]{ 29});

我在服務器和客戶端都用29端口,而後就穩定下來了。
花了一成天的時間,真是無語。
相關文章
相關標籤/搜索