我正在使用
Android应用程序,它使用蓝牙连接在我的Android智能手机和非Android蓝牙模块之间传输数据,使用SPP配置文件.我使用Android开发者网站上的蓝牙聊天示例作为参考.
我已经成功地使两个设备相互连接,并将简单的字符串从智能手机发送到蓝牙模块.但是,从模块发回的数据读取有一些错误.我使用以下代码,这与蓝牙聊天示例完全相同,从InputStream读取数据
while (true) { try { // Read from the InputStream bytes = mmInStream.read(buffer); String str = new String(buffer); Log.i(TAG,"mmInStream - " + str); // Send the obtained bytes to the UI Activity mHandler.obtainMessage(BluetoothChat.MESSAGE_READ,bytes,-1,buffer) .sendToTarget(); } catch (IOException e) { Log.e(TAG,"disconnected",e); connectionLost(); break; } }
当我的蓝牙模块向手机发送一个简单的字符串时,该字符串未正确接收.它以随机的方式分成几块.例如,如果我向手机发送三次“1234567890abcdef1234567890abcdef0123456789”,则Eclipse上的Logcat将记录以下内容:
mmInstream - 12345678910abcdef��������(continuing null) mmInstream - 1��������(continuing null) mmInstream - 2345678910abcdef0123456789��������(continuing null)
首次.在第二次和第三次传送数据时,以差分方式接收数据:
mmInstream - 1234567891�������(continuing null) mmInstream - 0abcdef012�������(continuing null) mmInstream - 3456789���������(continuing null) mmInstream - 1234567891����������������(continuing null) mmInstream - 0abcdef0123456789������������(continuing null)
我不知道为什么会这样发生,如何解决这个问题.如果以这样的任意方式收到数据,则无法获得必要的数据来处理.我如何得到它一块?
任何帮助将不胜感激.
非常感谢.
解决方法
有两件我注意到的代码:
>首先向你的应用程序发送一个对您读取的缓冲区的引用并不总是一个很好的解决方案:如果同时缓冲区被覆盖了怎么办? See this bug on stackoverflow for example
您可以通过复制您从蓝牙读取的数据(例如使用buffer.clone()),或者如果您不喜欢使用太多内存,可以使读取缓冲区成为循环缓冲区,从而绕过此过程.
>即使在单独的数据包中接收到数据(但在短时间内收到数据包),您也可以重新编译数据.例如,您可以启动/停止标志.它仍然取决于您通过蓝牙发送的对象的类型…
如果以前的2条警告没有用,现在可以解决这个问题:
而不是无限循环调用.read – 一个阻塞调用 – 你可以这样做:
while(true) { if mmInStream.getAvailable()>0 { -your read code here- } else SystemClock.sleep(100); }
这是一个黑客,它可能仍然只会读取信息的一部分 – 但这将是非常罕见的!
如果有用,请投票/正确