android - 在 Android 上通过蓝牙从 InputStream 读取数据时出错

标签 android bluetooth inputstream

我正在开发一个 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;
    }
}

当我的蓝牙模块向手机发送一个简单的字符串时,该字符串没有被正确接收。它以随机方式分成几部分。例如,如果我向手机发送 3 次“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())来绕过它,或者如果您不喜欢使用太多内存,您可以将读取缓冲区设为循环缓冲区。

  • 您应该能够重新编译您的数据,即使它是在单独的数据包中接收的(但数据包是在很短的时间跨度内接收的)。例如,您可以制作开始/停止标志。 Ofc 它仍然取决于您通过蓝牙发送的对象类型......

如果之前的 2 个警告没有用,现在可能的解决方案是:

代替调用 .read 的无限循环 - 阻塞调用 - 你可以这样做:

while(true) {
     if mmInStream.getAvailable()>0 { 
          -your read code here-
     }
     else SystemClock.sleep(100);
}

这是一种 hack,有时它可能仍然只读取消息的一部分 - 但这种情况非常罕见!

如果有用,请投票/更正!

关于android - 在 Android 上通过蓝牙从 InputStream 读取数据时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12294705/

相关文章:

无论分辨率如何,Android 都在特定位置打印

android - MediaCodec signalEndOfInputStream() 错误

C++ 输入字符串包含 ASCII 26(替换)字符。如何摆脱它?

android - 互联网连接丢失时不停止读取 Inputstream

java - 我想模拟一个扩展InputStream的专有类,模拟读取,验证关闭

java - Google API - getLastKnownLocation 的 NULL 指针

java - 如何灵活使用泛型对象?

android - 在 Android 1.6 上使用 backport-android-bluetooth

bluetooth - 蓝牙 LE 中的单模和双模如何进行配对

ios - 用于 ANCS iPhone 的 BLE Shield