react-native-bluetooth-serial
react-native-bluetooth-serial copied to clipboard
Unable to set a READ listener
Hi there,
First of all I love this library and it works like a treat.
I'm able to easily pair, connect, write and read data of 2 BT devices but I'm not able to set a listener for reading data asynchronously after the connection has been established.
So far I read through most of the threads here and found that snippet that supposed to be used to set up the reading listener but it doesn't work
BluetoothSerial.withDelimiter('\r\n').then((res)=>{
BluetoothSerial.on('read', (data) => {
console.log('Reading data: ', data)
})
})
I also tried the event namesdata
and rawData
but the listener doesn't get invoked.
If I invoke BluetoothSerial.readFromDevice()
after some time I can read any message but I don't want to poll it all the time.
Can you please let me know how it set the listener correctly?
Thank you, Thomas
Did you ever find a way to do this without polling? We're thinking of using readEvery and checking whether any data came in but it's not a great solution.
Does the data you're looking for have the delimiter within each message? For example, when I'm requested data from my device > "ri\r" the data comes back in streams, with multiple lines separated by \r\n. Because of this, I only get the first line back - and now I'm in a loop of always being X lines behind my expected data. For example, if there are 10 lines/delimiters in the buffer then when I actually scan something I'll get the next line of info, instead of my scanned data.
To resolve this I had to update the onData to:
- add to the buffer (like it does)
- While(readUntilDelimiter()) returns data
- fire the OnRead event.
This way my javascript listener stays current. Otherwise I was getting some funky issues where the application was not reading properly. Anyhow, if this isn't your particular symptom, I apologize for hijacking.
/**
* Handle read
* @param data Message
*/
void onData (String data) {
mBuffer.append(data);
String completeData = readUntil(this.delimiter);
if (completeData != null && completeData.length() > 0) {
WritableMap params = Arguments.createMap();
params.putString("data", completeData);
sendEvent(DEVICE_READ, params);
}
}
private String readUntil(String delimiter) {
String data = "";
int index = mBuffer.indexOf(delimiter, 0);
if (index > -1) {
data = mBuffer.substring(0, index + delimiter.length());
mBuffer.delete(0, index + delimiter.length());
}
return data;
}
Read events weren't working for me either so I took a look at the code and it only sends events when a delimiter is set, otherwise readUntil will just return "" and data length will be 0 so read event won't get triggered. My data had no delimiter but was prefixed with a length byte. I just ended up adding this to the top of the readUntil function:
if(delimiter == "") {
String data = mBuffer.toString();
mBuffer.delete(0, mBuffer.length());
return data;
}
So either will need to do something like this for Android/iOS code or make sure delimiter is set to the correct character for your data.
Thanks for your help. was good to mention the location of this function .. anyway it is here : ..\node_modules\react-native-bluetooth-serial\android\src\main\java\com\rusel\RCTBluetoothSerial\RCTBluetoothSerialModule.java This solves the problem but what is the default delimiter ? And the String data is already defined .. so the corrector one is as bellow :
if(delimiter == "") {
data = mBuffer.toString();
mBuffer.delete(0, mBuffer.length());
return data;
}
put this code after definition of the data .