I am making an app where I need to have my PC and phone communicate via Bluetooth. I have gotten the app and my PC to successfully connect, and my app is receiving an input stream when I send "Hello World" from my PC. However, I cannot seem to figure out how to get a readable string from my input stream. Here is the code I have so far:
private static class BluetoothAcceptThread extends Thread {
private final Context CONTEXT;
private final BluetoothAdapter BLUETOOTH_ADAPTER = BluetoothAdapter.getDefaultAdapter();
private final BluetoothServerSocket BLUETOOTH_SERVER_SOCKET;
private final java.util.UUID UUID;
public BluetoothAcceptThread(Context context, java.util.UUID uuid) {
this.CONTEXT = context;
this.UUID = uuid;
BluetoothServerSocket tmp = null;
try {
tmp = BLUETOOTH_ADAPTER.listenUsingRfcommWithServiceRecord(
CONTEXT.getString(R.string.app_name), UUID);
} catch (IOException e) {
e.printStackTrace();
}
BLUETOOTH_SERVER_SOCKET = tmp;
}
@Override
public void run() {
while (true) {
BluetoothSocket socket = null;
try {
System.out.println("Accepting incoming connections");
socket = BLUETOOTH_SERVER_SOCKET.accept();
System.out.println("Found connection!");
} catch (IOException e) {
System.out.println(1);
e.printStackTrace();
}
if (socket != null) {
manageConnectedSocket(socket);
}
try {
assert socket != null;
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void cancel() {
try {
BLUETOOTH_SERVER_SOCKET.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void manageConnectedSocket(BluetoothSocket socket) {
try {
InputStream inputStream = socket.getInputStream();
while(inputStream.read() == -1) {
inputStream = socket.getInputStream();
}
String string = CharStreams.toString( new InputStreamReader(inputStream, "UTF-8"));
System.out.println(string);
} catch (IOException e) {
e.printStackTrace();
}
}
}
In case it is relevant, here is the test code I am running from my PC:
import bluetooth
import pydbus
def list_connected_devices():
bus = pydbus.SystemBus()
mngr = bus.get('org.bluez', '/')
mngd_objs = mngr.GetManagedObjects()
connected_devices = []
for path in mngd_objs:
con_state = mngd_objs[path].get('org.bluez.Device1', {}).get('Connected', False)
if con_state:
addr = mngd_objs[path].get('org.bluez.Device1', {}).get('Address')
name = mngd_objs[path].get('org.bluez.Device1', {}).get('Name')
connected_devices.append({'name': name, 'address': addr})
return connected_devices
def main():
address = list_connected_devices()[0]["address"]
uuid = "38b9093c-ff2b-413b-839d-c179b37d8528"
service_matches = bluetooth.find_service(uuid=uuid, address=address)
first_match = service_matches[0]
port = first_match["port"]
host = first_match["host"]
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect((host, port))
message = input("Enter message to send: ")
sock.send(message)
if __name__ == '__main__':
main()
EDIT:
Tried using the solution suggested by Sajeel by using IO utils, and I am getting the error:
W/System.err: java.io.IOException: bt socket closed, read return: -1
W/System.err: at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:550)
at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:88)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:291)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:355)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:181)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.Reader.read(Reader.java:140)
at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2369)
W/System.err: at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:2348)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:2325)
at org.apache.commons.io.IOUtils.copy(IOUtils.java:2273)
at org.apache.commons.io.IOUtils.toString(IOUtils.java:1041)
at com.example.app.BluetoothSyncService$BluetoothAcceptThread.manageConnectedSocket(BluetoothSyncService.java:278)
at com.example.app.BluetoothSyncService$BluetoothAcceptThread.run(BluetoothSyncService.java:251)
EDIT 2:
I motherflipping got it! Here is the code that got it to work:
public void manageConnectedSocket(BluetoothSocket socket) {
try {
InputStream inputStream = socket.getInputStream();
while(inputStream.available() == 0) {
inputStream = socket.getInputStream();
}
int available = inputStream.available();
byte[] bytes = new byte[available];
inputStream.read(bytes, 0, available);
String string = new String(bytes);
System.out.println(string);
} catch (IOException e) {
e.printStackTrace();
}
2
Answers
Finally figured out the solution. You need to create a Byte Array of the same length of the inputstream's available bytes, then call the .read() method of the inputstream. The input stream will then write the bytes it received to the byte array, which you can then decode into a string.
Try
In order to use
IOUtils.toString()
add the following thingsIn
build.gradle
app moduleAfter that
import