kai-morich / SimpleBluetoothTerminal

Android terminal app for Bluetooth classic devices using SPP profile
MIT License
447 stars 166 forks source link

Your example use append and this work, but, if you need use setText a one day, you will fail #6

Closed LukeDaniel16 closed 4 years ago

LukeDaniel16 commented 4 years ago

I have researched and i saw that your method divide byte array data in two parts, is purposeful? Bluetooth have a problem with receive data because he divide, really, data in parts, do you think that could to make the data to be received in a only part? I'm tring it now, send me news when you can.

kai-morich commented 4 years ago

which file/line are you refering to?

LukeDaniel16 commented 4 years ago

Mainly the class "Serial_Socket" This methods: ` void write(byte[] data) throws IOException { if (!connected) throw new IOException("not connected"); socket.getOutputStream().write(data);

}

@Override
public void run() { // connect & read
    try {
        socket = device.createRfcommSocketToServiceRecord(BLUETOOTH_SPP);
        socket.connect();
        if(listener != null)
            listener.onSerialConnect();
    } catch (Exception e) {
        if(listener != null)
            listener.onSerialConnectError(e);
        try {
            socket.close();
        } catch (Exception ignored) {
        }
        socket = null;
        return;
    }
    connected = true;
    try {
        byte[] buffer = new byte[1024];
        int len;
        //noinspection InfiniteLoopStatement
        while (true) {
            len = socket.getInputStream().read(buffer);
            byte[] data = Arrays.copyOf(buffer, len);
            if(listener != null)
                listener.onSerialRead(data);
        }
    } catch (Exception e) {
        connected = false;
        if (listener != null)
            listener.onSerialIoError(e);
        try {
            socket.close();
        } catch (Exception ignored) {
        }
        socket = null;
    }
}

}`

When you called metho OnSerialRead in class Terminal_Fragment the output is: First letter from data and the remainder of data, example: Hello World is data sended from Bluetooth, your app receive

'H' 'ello World'

This is worked while we using append, but, if use setText, the first letter will be lost.

kai-morich commented 4 years ago

very likely your remote device has split the data into multiple Bluetooth packets. There is typically no guarantee that a logical message arrives in a single packet.

LukeDaniel16 commented 4 years ago

You already test with method setText for your example? If you can and verify if return is equal i'll be grateful.

LukeDaniel16 commented 4 years ago

Is it possible to get all received data, even separated, in a single variable?

Maybe adding package by package each time the function is called.

mmuir-ca commented 4 years ago

You can do whatever you like in the data that comes in. the data arrives as a byte array in onSerialRead. At that point, you can do what you wish with the incoming data.

SetText would set the TextView to just the last packet of data you received. Append just adds the data to the existing data that came before.

LukeDaniel16 commented 4 years ago

So how can I get or get complete (uncut) data and present this fact in my setText? Since the serialOnRead method holds the byte as a parameter.

mmuir-ca commented 4 years ago

Why would you want to use setText in the first place? By appending into the TextView, you get the complete data as it comes in. If you need to get the current contents of the TextView you can use getText. If you wanted to use setText, you would need to use another object (StringBuilder maybe) to store the incoming messages and then when you know you received the complete data, then use setText. But... how do you know you have the complete message?

LukeDaniel16 commented 4 years ago

The app receives "weights" coming from a scale via bluetooth, they are sent one at a time every approximately 30 seconds.

Each time they change, I need to show them in the same place on the screen, replacing the previous one. Append goes "throwing" text forward.

kai-morich commented 4 years ago

your "weights" very likely use a specific protocol either with fixed length or terminated with a special character. When this condition is reached you should take the data collected in the StringBuilder and show with setText

LukeDaniel16 commented 4 years ago

It's can work really, thanks, i'll close issue.

LukeDaniel16 commented 4 years ago

    private void receive(byte[] data) {
        peso.append(new String(data));
        receiveText.setText(peso);
        Log.i("VAL OF APPEND", String.valueOf(peso));
        if(peso.length() >= 3)
            peso.setLength(0);

    }

This perfect worked for me, very thanks for you attetion! StringBuilder peso = new StringBuilder();

LukeDaniel16 commented 4 years ago

Sorry to bother again, not a problem, just wanted to understand how you inserted the line break (CR + LF || LF) so I can remove it to test if the text resizes.