Bundling inputStream.read messages

2019-08-24 18:03发布

I am using the Android Bluetooth Chat sample code to chat (send commands + receive responses) with a bluetooth device. It is working fine when I send a command, and I receive a response from the device that is passed to message handler. The issue I am having is the response is cut up into pieces.

Example:

I send the string "{Lights:ON}\n" and my activity correctly displays Me: {Lights:ON}. The device lights turn on and it returns it's response "{FLash_Lights:ON}\n". However my activity displays DeviceName: {Fla, new line, DeviceName: sh_Lights:ON} (or some variation ect).

Now I am new to threading and bluetooth in general but I have traced the issue down to the connected thread class (in bluetoothchatservice), more specifically the public void run() to listen to incoming bytes.

     public void run() {
            Log.i(TAG, "BEGIN mConnectedThread");
            byte[] buffer = new byte[9000];
            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(BluetoothActivity.MESSAGE_READ, bytes, -1, buffer)
                            .sendToTarget();
                } catch (IOException e) {
                    Log.e(TAG, "disconnected", e);
                    connectionLost();
                    // Start the service over to restart listening mode
                    BluetoothThreading.this.start();
                    break;
                }
            }
        }

I understand that this was made to listen for any bytes coming in (as a chat service). However I know exactly what I am writing to the device and I know the response I should be receiving, what I would like to do is bundle this response before sending it back to the mHandler.

Any help with this would be amazing! Thank you!

Note: I know that using this sample as a way of sending a command to a device and receiving a response is a bit overkill (especially since I know exactly what I'm sending and need to receive directly afterwards). It would be great to be pointed to any simplified sample you may know of as well. At the end of the day I just need to search, connect to device, push button to send byte[] to device, receive byte[] response, print + store it.

1条回答
【Aperson】
2楼-- · 2019-08-24 18:06

The 'read()' is blocking call and returns when few bytes are received over bluetooth. The count of 'few' is not fixed, and that's the reason why incoming response appears to be broken into pieces. Therefore to retrieve complete response, all these pieces must be joined together.

Where the response stream is terminated with a specific character, then following code logic can accumulate the bytes arriving before the terminating character. And once terminating character is detected, the accumulated response is sent to main activity. (Note that in the code snippet below, the terminating character used is 0x0a).

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

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

        btInStream.write(Arrays.copyOf(buffer, bytes) );

        if (buffer[bytes - 1] == 0x0a){
            mHandler.obtainMessage(MainActivity.MESSAGE_READ, btInStream.size(), 0,btInStream.toByteArray());
            .sendToTarget();
            btInStream.reset();
        }
    } catch (IOException e) {
        Log.e(TAG, "disconnected", e);
        connectionLost();
        // Start the service over to restart listening mode
        BluetoothThreading.this.start();
        break;
    }
}
}

Also note that code is not tested but proposed as one approach to resolve the issue mentioned in the question. Mat be it will need corrections at few places. Please test and inform the results.

查看更多
登录 后发表回答