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端口,而后就稳定下来了。
花了一成天的时间,真是无语。
相关文章
相关标签/搜索