I'm trying to connect a bluetooth device and to read out information from it.
I've used the Bluetooth chat example and changed the UUID tp SPP mode.
The connection works, but the Information that I get from the Inputstream is wrong.
The transmitted String is 20 signs long, but the Inputstream just returns a 7. The rest of the bufferstream is empty.
Does anyone has a clue?
After write try flushing the transmitter's stream.
And on the receiver you will need to wait till you receive the expected bytes.
SPP does not have packet boundaries. So you can receive the packets in multiple chunks and you need have some logic to determine packet boundaries.
Related
i'm trying to receive advertising data without connect to ble sensor, i used onScanResult function. I logcat the result and then i get:
ScanResult{mDevice=A4:34:F1:3A:AF:XX, mScanRecord=ScanRecord
[mAdvertiseFlags=6, mServiceUuids=null, mManufacturerSpecificData={},
mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=XXXX],
mRssi=-67, mTimestampNanos=1445086508079000}
the mDevice and mDeviceName and mRssi is correct, then i try to get the mScanRecord, it in byte array format, i try to convert it to hex representation: then i have this result
02010606094D734F6E65000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000
the first problem that the data change just for first time and then stay like this, and the data that i received is not like the original data that i tested in RPI using python script , this is the result of scanning in RPI
a4:34:f1:3a:af:ab,54540400201818000e00000000000000,-74
a4:34:f1:3a:af:ab,5252040313061f015500050000020001,-84
thank you for helping me
The first thing I noticed is 6E in your packet says that ADV packet has 110 bytes of payload data, which is not technically possible or it does not make sense. That is assuming when 0201 is your header (2 bytes) and 0606094D734F is the device address (6 bytes) is correct. You can double check it by scanning your packet using another scanner like your raspberry pi.
See this answer for how;
https://stackoverflow.com/a/22569917/1505341
Something is wrong with the received packet structure there. I'd also check it with a BLE scanner app on android or even on iOS as well just to be sure. Nordic had a good one as far as I can remember. Not sure what's the best app out there these days for scanning raw BLE packets.
I'm still new to Android studio and I'm having a lot of trouble with Bluetooth, I'm currently making an app where I need to send data between devices. I'm letting the phone's default Bluetooth setup do the pairing but now I need to know how to send the data, I know I need to use input and output streams but I don't know exactly how.
And yes I have searched all over Google, I've followed a lot of Bluetooth tutorials but none of them seem to really explain how to send data from one device to another.
Thanks in advance.
After you establish a secure/insecure connection via bluetooth the rest is just socket programming simply. That is lets think about sending a text. We convert the text to byte and send that by Java OutputStream. In the same manner for the data received we can get it by InputStream.
But remember you need to maintain bunch of code and thread/handler to maintain state and others. Though the basic thing is simply socket programming over Bluetooth socket using the Bluetooth adapter. Have a look at the below repository in github. This creates a chatroom over bluetooth. i.e it sends and receives string data
https://github.com/zahansafallwa/Android-bluetooth-chat-with-emoji/tree/master/app/src/main/java/com/zahan/safallwa/donttalk
Specially have a look at the BluetoothChatService class. That contains codes related to sending data. BluetoothChatService
Edit:
As per your comment lets think that your devices are paired and also connected. Now you only need to send the text. Declare a outputstream
private final OutputStream mmOutStream;
Suppose you have a string. We convert it to byte. Then get our socket outputstream and send data by write() method
String message="this is test data";
byte[] send = message.getBytes();
mmOutStream = socket.getOutputStream(); // here socket is the bluetooth socket you establish
mmOutStream.write(send);//this is what sends the message
Remember:
Edited code is for your understanding only. It is prescribed to use separate thread for sending data.
We are facing one issue when reading characteristics from remote BLE device.
This issue happen in Android OS 5.0 and above.
Points are below to generate issue :
Make one peripheral device with one service and one characteristics.
Characteristics will have only read permission. Now set the value of this characteristics with more than 20 characters i.e. 20 bytes.
Now let peripheral device broadcast itself with one service and one characteristics.
Now launch any BLE scanner app from market and connect with this peripheral device.
Once successfully connected with peripheral device just try to read characteristics.
In this case it will not show any data and when debugging the app it show that it returns null data.
The above same case not working in the Android OS 5.0 and above.
Same case working in android 4.4.
So there is something change in Android OS 5.0 and above that internally disable readblob() request that can read data having more that 20 characters.
This can be simply achievable by splitting your data into 20 byte packets and implementing a short delay (i.e. using sleep()) between sending each packet.
You can use BluetoothGatt.requestMtu(). See the Official document of BluetoothGatt.requestMtu
Request an MTU size used for a given connection.
When performing a write request operation (write without response), the data
sent is truncated to the MTU size. This function may be used to request a larger MTU size to be able to send more data at once.
A onMtuChanged(BluetoothGatt, int, int) callback will indicate whether this operation was successful.
Requires BLUETOOTH permission.
If you want send more 20 bytes, you should define array byte[] include how many packet you want.
There is an example Android: Sending data >20 bytes by BLE
Also there is another example How to send more than 20 bytes data over ble in android?
I just try to use the recieve() method of the socket.
When I send the data of a short String,as "send data",for 100
times,the recieve() function performs well.
While I send the data of a long String,as "send data to the
client,send data to the client,send data to the client,send data to
the client,send data to the client,send data to the client,send data
to the client,send data to the client",for 100 times,the recieve()
function cannot performs well.
In android project:
It just recieved about 30 packets, that is, other 70 packets are lost when I use another computer to send pakcets. But I checked the recieve buffer size, it is adequate to contain 100 packets above.
It recieves all the 100 packets when I use the localhost address to test. And I used the capturing tool named wireshark to capture the packets and the capturing tool can capture all the 100 packets everytime.
So I can eliminate the possibility of that another computer did not send all the packets.So I included that the problem exists in the emulator.
The above two cases both happened in android project,so the recieve buffer size is the same,
why in the former it will lose packets??
In java project:It recieves all the 100 packets too.
If you need all the packets then you should use TCP/IP protocol. In UDP protocol you can lose data because it is doesnot support reliable connection like Tcp/ip. UDP is designed to be faster at transferring data at the cost of unreliable connection. Based on network routing the packets you received could also arrive in different order.
Emulator TCP/IP stack's udp buffer size is smaller than the computer. So if the UDP buffer fills up, the emulator TCP/IP stack starts dropping packet. The PC TCP/IP stack pushes data at faster rate which the emulator can't handle. You can try reducing the rate at sender end to avoid filling the emulator buffer or increase the receive socket buffer size of android app to higher value by using the SO_RCVBUF socket option.
Im trying to determine if data was successfully sent to the server through a TCP socket using the OutputStream object. for testing purposes i disable network communications in the phone and OutputStream.write(); doesn't throw an exception, all the methods in the socket class return as though the socket is active and working. Is there anything i'm doing wrong here?
is there any socket implementation or stream implementation i can use to get an exception or error when the stream / socket doesn't actually send the data in the buffer?
also setting SetSoTimeout() on the socket doesn't seem to do anything.
Thanks,
Totem
If you're using the emulator this is a known bug, data can still be sent after enabling airplane mode.