1

我修改了具有发送图像功能的示例蓝牙聊天应用程序。我遇到了一个我无法弄清楚的问题。示例应用程序需要一个字符串来发送和接收数据。我正在起诉 Base64 将位图转换为字节然后转换为字符串,以便我可以发送带有所选图像的文本。如果我发送一个小图像(例如,4kb 大小的全黑图像),它会被发送和接收并显示在列表视图中。但是当我发送更大的图像时,它们会被分成许多包。这意味着,我得到的不是一张图像,而是大量文本,并且我用来填充列表视图的数组大小将大于 1,具体取决于包的数量,因此我的列表视图中填充了很多文本。

事实证明,这取决于图像的大小。我尝试了许多图像。对于长度(作为字符串)为 50096 的照片,我在接收方收到 51 个包裹。如果是另一个长度为 77896 的图像,我会得到 81 个包。所以我决定尝试一个非常小的图像。我在Paint中创建了一个黑色图像,并且成功发送和接收。我测量了它的长度,是280。然后我尝试了一个白色的图像,带有一点黄色,它的长度为980。同样发送成功。然后我在图像中添加了一些黑色,长度为 1554。这次我收到了一些文本而不是图像。

所以我的结论是,通过蓝牙发送数据时字符串的长度受到限制,这对于熟悉该技术的人来说可能是显而易见的。

我能做些什么呢?如果我知道我可以在一个包裹中发送的最大字符数,我可以计算发送方的包裹数量,我可以连接接收方大小的所有包裹。

我在接收器端向您展示了两个图像来演示这种行为。第一个是正确的函数,第二个是错误的函数:

在此处输入图像描述

在此处输入图像描述

4

1 回答 1

0

您的问题出在接收器部分,可以在蓝牙聊天源代码中的此函数中找到:

    public void run() {
        Log.i(TAG, "BEGIN mConnectedThread");
        byte[] buffer = new byte[1024];
        int bytes;

        // Keep listening to the InputStream while connected
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);

                // 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();
                // Start the service over to restart listening mode
                BluetoothChatService.this.start();
                break;
            }
        }
    }

具体来说,请注意byte[] buffer = new byte[1024];. 您仅限于 1K。如果你想做更多,你需要增加缓冲区的大小,或者构建一个方法来检测文件是否超过了这个缓冲区大小。

有几点需要注意,您是否应该设计一个协议来处理这个问题。

  1. 您不需要在 base 64 中发送它,流接受二进制就好了。
  2. 放置一个包含文件类型、数据包编号和数据包总数的标头。如果你想真正花哨,包括某种校验和,以验证数据包是完整的。
  3. 您应该包括一种重新传输丢失数据包的机制。
  4. 您可能想要发送一个初始标头,解释即将发生的事情。
于 2012-12-01T15:51:03.660 回答