I am trying to connect my bluetooth app to my PC using Android Java. After I have connected my app to the PC socket then I can send a message such as Say Hello. My app is successful in scanning for Bluetooth Devices in range using the location and bluetooth API. It discovers my PC and I grab the UUID of my PC from the Bluetooth Device profile discovered for my PC. I expose the UUID of my PC as a Bluetooth Device on the logcat and it looks like device.getUUIDs does not return null as long as you cancel discovery before calling it. Here is the UUID string printed on my logcat
BluetoothClient.BluetoothClient D/UUID: 0000110a-0000-1000-8000-00805f9b34fb
The code below shows how I attempt to connect to the PC Bluetooth device socket
//check if the device is already bonded and attempt to connect to its socket if it is exposed
if (dev.BondState == Bond.Bonded){
//device is a bluetooth device on my list I grabbed from the broadcast receiver
//grab the UUID of the discovered bluetooth device
UUID MYUUID = dev.GetUuids()[0].Uuid;
//create a bluetooth socket using the UUID for connection purposes
BluetoothSocket socket = dev.CreateRfcommSocketToServiceRecord(MYUUID);
//connect to the socket
socket.Connect();
}
The code written does not throw any exceptions nor does the app crash, this information is printed on my logcat.
D/BluetoothUtils: isSocketAllowedBySecurityPolicy start : device null
// I do not know what the above is and what device is null
I/BluetoothSocket: connect() for device F894C2 called by pid: 2822
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
//if a bluetooth manager callback is needed for the socket creation, how do attach the callback to my code to make this work, Thank You.
See section 5.5.3 in the README.md documentation here for bare-bones code https://github.com/petzval/btferret.
The functions instream.read and outstream.write exchange serial data.
byte[] dat;
String s;
int len;
dat = new byte[32];
s = "Hello\n";
len = s.length();
for(n = 0 ; n < len ;++n)
dat[n] = s.charAt(n);
outstream.write(dat,0,len);
Related
I have to develop an Android app to connect to a Bluetooth module that is connected to a board. My goal is to send and receive data to this board.
I'm currently able to enable the Bluetooth on my phone, to pair to the Bluetooth module but I don't know how to connect and send/receive data to this module.
Most of examples explain how to create a server and a client to communicate via sockets. Is it the good way for me? As described here : https://developer.android.com/guide/topics/connectivity/bluetooth.html#java
Following is a method:
create service class which communicate every time when it is
connected to that device.
register that service into your main activity through broadcast update.
then scan you Bluetooth devices(after validating permissions) and connect it,
note that connection code must be in your serviceclass(all communication with device is through service class).
after that you can sent data to and from the Bluetooth device.
Here attaching an example for you for working with BLE,Created by Nordic Semiconductor
Click Here
Do it like in the Example: https://developer.android.com/guide/topics/connectivity/bluetooth.html#example_1
Note that you will probably need to know what kind of service/profile the module provides. Often, generic modules/devices use the Serial Port Profile (SPP).
You use createInsecureRfcommSocketToServiceRecord() or createRfcommSocketToServiceRecord() to connect.
Which UUID you need depends on the actual service the module provides. For SPP see e.g. How to find the UUID of serial port Bluetooth device?:
The short, 16-bit UUID for SPP is
0x1101
the full UUID is
"00001101-0000-1000-8000-00805f9b34fb"
So, on Android, you'd use
final UUID SPP_SERVICE_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
final BluetoothSocket socket = device.createRfcommSocketToServiceRecord( SPP_SERVICE_UUID );
socket.connect();
final InputStream is = socket.getInputStream();
final OutputStream os = socket.getOutputStream();
// Send data to output stream and/or receive data from input stream
// ...
socket.close(); // Disconnect
I am trying to read simple ASCII from a Bluetooth device connected to an Android Galaxy Table or S6 Phone. The app was working about 3 months ago and now it times out when trying to connect to the standard serial port even with a previously known working device.
mmSocket.connect(); throws"java.io.IOException: read failed, socket might closed, read ret: -1"
Debug log shows this before the connect timesout:
D/BluetoothUtils: isSocketAllowedBySecurityPolicy start : device null
D/BluetoothSocket: connect(): myUserId = 0
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
I/art: Starting a blocking GC Instrumentation
D/BluetoothSocket: connect(): myUserId = 0
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
I’m trying a new device (a scanner). The devices pair properly and I can connect/read using the play store’s BlueTooth Serial Controller app. The BT Controller app also can’t connect to either device just like my app but when I scan a bar code the data is transmitted and displayed in the BT Controller app’s console. I added an edit field to my app and sure enough the data showed up in the edit field without running any of my code. The OS settings show the scanner is "connected".
One thing I noticed is that in the OS BT device settings there is a switch to “Use For Input Device” which is on. Turning it off doesn’t make the device connect and scanning into the BT Controller as well as my app stops working.
Of note is that Android u[dated 2 or 3 times when I picked the project up and is currently at V NMF26X.P55. SDK API 25 Android 7.1.1 Build Tools 26.0.2
Current permissions include only the following (I tried course location entitlements without luck):
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
I’m wondering if there isn’t a different method to programmatically read from the serial port or way to connect. Any help would be appreciated. Here’s a snippet of what I tried and was working:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
InputStream mmInputStream;
try
{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // Standard SerialPortService ID
// UUID uuid = UUID.fromString(mmDevice.getUuids()[0].toString());
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
if (!mmSocket.isConnected())
mmSocket.connect();
}
catch (IOException e)
{
try
{
// Try an alternate way of connecting (mmPort==1 not standard -1)
if (!mmSocket.isConnected())
{
mmSocket = (BluetoothSocket) mmDevice.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(mmDevice, 1);
mmSocket.connect();
}
}
catch (Exception ce)
{
showExcept(ce);
}
}
// Start reading if all went well
if (mmSocket.isConnected())
{
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
beginListenForData();
}
So as it turns out the scanner does not support direct connections without a firmware update. Above code is good.
Problem
How can I differentiate between being unable to establish a Bluetooth connection with a remote Android device because:
scenario 1: the remote device is out of range, or its Bluetooth is disabled.
scenario 2: the remote device is in range, but there is no server socket on the remote device to accept my connection.
What I've tried
I could not differentiate between exceptions thrown when connecting because it threw the identical exceptions in both cases:
java.io.IOException: read failed, socket might closed or timeout, read ret -1
I could not use fetchUuidsWithSdp() to check if my UUID supported by the remote device because it behaves the same way in either scenario...according to the documentation:
This API is asynchronous and {#link #ACTION_UUID} intent is sent, with the UUIDs supported by the remote end. If there is an error in getting the SDP records or if the process takes a long time, {#link #ACTION_UUID} intent is sent with the UUIDs that is currently present in the cache...
it's behaviour also seems sort of unpredictable according to this SO thread.
lastly, I didn't want to use sdpSearch to differentiate between the two, because that was added in API 23, and I want to be able to support down to API 19.
You can determine if a device is in range by trying to connect to a standard UUID that is usually available on Android devices. If the call to connect:
fails, then remote device is out of range or its Bluetooth is disabled.
succeeds, then the remote device is in range and you should close the connection and then try to connect to your app's UUID...if that fails, then there was no listening socket...if it succeeds, then all is well.
Example code:
public BluetoothSocket connect(BluetoothDevice remoteDevice) throws IOException
{
OPP_UUID = UUID.fromString("00001105-0000-1000-8000-00805f9b34fb");
// check if remote device is in range...throw exception if out of range
try
{
BluetoothSocket socket = remoteDevice
.createRfcommSocketToServiceRecord(OPP_UUID);
socket.connect();
socket.close();
}
catch(IOException ex)
{
throw new IOException("out of range",ex);
}
// try to connect to service on remote device...throw exception if UUID
// is not available
try
{
BluetoothSocket socket = remoteDevice
.createRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
return socket;
}
catch(IOException ex)
{
throw new IOException("no listening server socket",ex);
}
}
I used BluetoothDevice.getUuids() to get the UUIDs available on one of my Android devices. It gave me this list:
0000110a-0000-1000-8000-00805f9b34fb - Advanced Audio Distribution Profile (0x110a)
00001105-0000-1000-8000-00805f9b34fb - Object Push Profile (0x1105) // least invasive one...it seems
00001115-0000-1000-8000-00805f9b34fb - Personal Area Networking Profile (0x1115)
0000112f-0000-1000-8000-00805f9b34fb - Phonebook Access (0x112f) // this works!
00001112-0000-1000-8000-00805f9b34fb - Headset - Audio Gateway (0x1112)
0000111f-0000-1000-8000-00805f9b34fb - Handsfree Audio Gateway (0x111f)
00001132-0000-1000-8000-00805f9b34fb - Message Access Profile (0x1132) // this works too!
00000000-0000-1000-8000-00805f9b34fb - Base UUID (0x0000) // couldn't get this to work :(
Standard UUIDs from Bluetooth spec.
Im using a bluetooth printer which i connect to my device using BlueToothSocket, etc. I've been successful with most of the devices but as of this week I have a new device which i just cant get the printer to connect to (open the socket that is, since it's successfully paired). I've used this two methods (used first one with both secure and insecure way):
mmSocket = device.createRfcommSocketToServiceRecord(uuid);
AND
m = device.getClass().getMethod("createRfcommSocket",new Class[] { int.class });
mmSocket = (BluetoothSocket) m.invoke(device, Integer.valueOf(1));
Followed by mmSocket.connect();
The problem is, that neither are working and the error shown is the one stated at the question: java.io.IOException: bt socket connect failed
What'd be causing this? I've tried this on a HTC ONE, a Sony Xperia, a Galaxy Tablet, Motorola phone etc.. But now im using this ACUBE 7 Phablet and it's not working. I have a feeling it's got to be something on the device build that's causing it to fail but cant figure out which way to work something out. Any ideas? Are there any other methods used to initiate a Bluetooth connection programmatically between paired devices?
Im doing bluetooth based application, I want to connect other devices like nokia devices, and printer.
I refer the android bluetooth documentation http://developer.android.com/guide/topics/connectivity/bluetooth.html. It demonstrates all the fundamental Bluetooth API capabilites, And I did these all the things
Scanning for other Bluetooth devices
Querying the local Bluetooth adapter for paired Bluetooth devices
Establishing RFCOMM channels/sockets
Connecting to a remote device
Transfering data over Bluetooth
i get reference from BluetoothChat, samples of android.
BluetoothChat This application send data to another android device but for that this application must be installed in both the devices.
Like this How to send file from Android device to other device through Bluetooth by code
What i want is
I want to send file from one device to another device from my application and that also works even another device not running our application. i.e. Receiver device also able to receive file using default Bluetooth.
Is this possible in android?
I think this is not possible.
in fact, when you create a bluetooth socket, you have to use createRfcommSocketToServiceRecord(UUID)
This function requires an UUID that is a string shared between the applications on the two devices so the connection can be established.
Without a bluetooth socket listening on the other device, with the exact same UUID, you won't be able to share data.
You can do connection between two BT devices easily.
You just need to call
createRfcommSocketToServiceRecord(UUID)
with UUID that understand receiver device.
For file transfer action UUID must be equal (for example) to 00001106-0000-1000-8000-00805F9B34FB (File transfer service)
So you connection code might looks like code below
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice("00:0A:94:16:77:A0");
BluetoothSocket clientSocket;
try {
log(TAG, "Remote device " + device);
ParcelUuid[] uuids = device.getUuids();
boolean isFileTransferSupported = false;
UUID ftpUID = UUID.fromString("00001106-0000-1000-8000-00805F9B34FB");
// Check if remote device supports file transfer
for (ParcelUuid parcelUuid: uuids) {
if (parcelUuid.getUuid().equals(ftpUID)) {
isFileTransferSupported = true;
break;
}
}
if (!isFileTransferSupported) {
log(TAG, "Remote bluetooth device does not supports file transfer ");
return;
}
clientSocket = device.createRfcommSocketToServiceRecord(ftpUID);
clientSocket.connect();
} catch (IOException e) {
return;
}