I want to connect 3 devices via Bluetooth.
As for example I use BluetoothChat. So How I understand I should use different UUID for this devices. I have been trying to connect via such UUID=766c82f0-e1b4-11df-85ca-0800200c9a66, which I 've get it from Web UUID generator. But it doesn't work at all.
I have succesfully connected (to 1 device) if I used UUID=00001101-0000-1000-8000-00805F9B34FB
Where can I get UUID?
if you are using linux or mac, enter "uuidgen" this command without quotes in terminal, you will get an unique UUID, use that in your android project.
UUid is used to uniquely identify applications.Each application have a unique uuid .so use the same uuid for each device
In order to connect with your targetted devices, you need to know what are you connecting to. It'll be more helpful to list your device targets.
The UUID can be obtained from this link, http://www.bluecove.org/bluecove/apidocs/javax/bluetooth/UUID.html
Here you need to know what bluetooth profile is being used in each of your target device. You mentioned that "UUID=00001101-0000-1000-8000-00805F9B34FB" works.
This is due to your device is having a SPP Bluetooth profile. SPP stands for Serial Port Profile.
You could also lookup on Bluetoothdevice.getuuids
http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#getUuids()
You must get the Bluetooth UUID to establish a connection to the device,
you can invoke the method getUuids() using reflection:
try {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Method getUuidsMethod = BluetoothAdapter.class.getDeclaredMethod("getUuids", null);
ParcelUuid[] uuids = (ParcelUuid[]) getUuidsMethod.invoke(adapter, null);
if(uuids != null) {
for (ParcelUuid uuid : uuids) {
Log.d(TAG, "UUID: " + uuid.getUuid().toString());
}
}else{
Log.d(TAG, "Uuids not found, be sure to enable Bluetooth!");
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Don´t forget to add the permission:
<uses-permission android:name="android.permission.BLUETOOTH"/>
and you must enable bluetooth to get Uuids, for example:
UUID: 0000110f-0000-1000-8000-00805f9b12fb
UUID: 0000111d-0000-1000-8000-00805f9b12fb
UUID: 0000111a-0000-1000-8000-00805f9b12fb
Imagine, that u have a one or more services. Each service have its own UUID.
UUID=00001101-0000-1000-8000-00805F9B34FB is special one for SPP. Some devices (for example, Bluetooth serial board) will not work if u not set SPP UUID.
But for peer-to-peer connection between Android devices such as smartphones u may use your own generated UUID.
Devices must set same UUID to found each other and connect.
UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx where x=[0,...,9]|[A,...,F].
Good idea is to set xxxxxxxx-xxxx-xxxx-xxxx- to Your generated unique id.
Second part xxxxxxxxxxxx may be set to Your server MAC address without ":".
On client side u may construct UUID from known generated unique id (embedded to Your app) and server MAC address without ":". You can get server MAC address during Bluetooth device discovery.
you have to do a service discovery with the device you are trying to connect with, Get the UUID that it returns (which will be corresponding to the service that is running on the device and accepting connections) and then connect to it.
Related
My understanding is that the SDP is a list of UUIDs that other devices can fetch.
According to this PDF from MIT, "A more general way to think of
SDP is as an information database." Does this mean I can add multiple values to SDP? Since Android has BluetoothDevice.fetchUuidsWithSdp(), how do I set the UUIDs of a device?
Also, what does each section of an UUID mean? UUIDs look like 00000000-0000-1000-8000-00805F9B34FB, but what information does this convey?
An UUID identifies a service that is available on a particular device. So if you call BluetoothDevice.fetchUUidsWithSdp() your BroadcastReceiver will receive the relevant Intent ACTION_UUID containing the device and the service UUID.
The bluetooth specification defines some common UUIDs.
If you don't want to connect to one of these well known services but intent to implement your own bluetooth application, then you have to just generate your own UUID (use uuidgen from a unix console or an online generator) that identifies your application/service.
You can create an UUID instance in java like this UUID uuid = UUID.fromString("785da8ea-1220-11e5-9493-1697f925ec7b");.
So if you create the server side for your bluetooth application on Android you typically do this
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
BluetoothServerSocket serverSocket = adapter.listenUsingRfcommWithServiceRecord("YourHumanReadableServiceName", uuid);
And this is where you "set" your UUID. The Android bluetooth API creates the SDP-entry consisting of YOUR application's UUID and name for you. Other devices can now retrieve this entry. Androids bluetooth stack will now associate a bluetooth channel to your BluetoothServerSocket. If you want to connect to this ServerSocket, the connecting side usually connects doing this:
// you will most likely already have this instance from a discovery or paired device list
BluetoothDevice serverDevice = adapter.getRemoteDevice(bluetoothMacAddress);
// connect to your ServerSocket using the uuid
BluetoothSocket socket = serverDevice.createRfcommSocketToServiceRecord(uuid);
socket.connect();
Android will again do the heavy lifting for you: It checks the SDP-Records on the remote device, looks up the bluetooth channel that corresponds to your service's UUID and connects using this information.
There is a common code snippet spooking around here on SO that advices you to use "reflection" to get to a hidden API looking similar to this code:
try {
// this is the way to go
socket = device.createRfcommSocketToServiceRecord(uuid);
socket.connect( );
} catch ( IOException exception ) {
// don't do that! You will bypass SDP and things will go sideways.
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
socket = (BluetoothSocket) m.invoke(device, 1);
socket.connect();
}
Most people try this and it "just works" in their dev environment but you should know what you do using this. You actively bypass the SDP lookup that retrieves the right bluetooth channel to be used with your service and you will end up connecting to channel 1. If you have more than one Service running on the device, things WILL go sideways in this cases and you will end up in debugging hell ;-)
I developed a small middleware called Blaubot to create small networks using bluetooth/wifi/nfc and experienced all sorts of problems on the devices I used to test with (12 models). It was often the case that the bluetooth stack was not fully functional anymore in cases where it got some load or after many connects/disconnects (which you usually will have, if you are developing your app). In these cases the device.createRfcommSocketToServiceRecord(uuid) would occasionally fail and only turning the bluetooth adapter off and on again helped to bring the bluetooth adapters back to life (in some cases only after a full power cycle). If this happens and you use the reflection method, you will probably not have much fun with bluetooth.
But if you know this and keep concurrent calls to the BluetoothAdapter within bounds, bluetooth connections and the adapters will be pretty stable.
I use CoreBluetooth to connect my iPhone with a device equipped with Bluetooth 4.0.
I print its (as a peripheral) UUID :
<CBPeripheral: 0x1742fca80, identifier = B148AD69-1FC7-498C-016F-33BA3BE041A3, name = HMSoft, state = disconnected>
I wonder whether this identifier is an inherent attribute of a device.
Since I use the following code in android to get its UUID which is different from what I get using CoreBluetooth in iPhone:
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
for (ParcelUuid uuid : device.getUuids()) {
Log.d("UUID", uuid.getUuid().toString());
}
( I connect with the same device but the print UUID is different).
Identifier in CBPeripheral is a randomly generated Unique identifier. This gets varied over time. In case of a CBPeripheral, we need to know about two kinds of UUIDs. One is ServiceUUID and other is CharacteristicUUID. Each peripheral broadcast data over each service. A single service can have more than one characteristics. For eg. a device information service can have device name, device version etc as its characteristics.
See the following image for a better understanding CBPeripheral. The Apple docs speaks well on this.
My first answer, so I hope I won't make a fool of myself ;-)
BluetoothDevice.getUuids():
Returns the supported features (UUIDs) of the remote device. I.e. UUIDs of services advertised by the device, not UUID of the device itself.
I'm currently looking myself for an Android way to get the UUID of a discovered BLE device...
My android app requires connecting to a bluetooth printer (Zebra Bt Printer) to print tickets, this printer doesn't require authentication (it's set Authentication:OFF), but i cant create a connection with it because the app asks to make pairing by entering a pin, i've tried default values like 0000 and 1234 but any of them works.
This is the code i use to create a connection with the printer:
Set<BluetoothDevice> devices = bluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : devices) {
if (device.getAddress().equals(PRINTER_DEVICE_MAC_ADDRESS)) {
bluetoothDevice = bluetoothAdapter.getRemoteDevice(PRINTER_DEVICE_MAC_ADDRESS);
if (bluetoothDevice != null) {
try {
clientSocket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
clientSocket.connect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
When it executes the line :
clientSocket.connect();
is where appears the dialog for entering the pin for making the connection with the device, but i dont know what code to enter or how to avoid this dialog.
-I'm using Galaxy Tab 3 with Android 4.1.2
-Developing in Api 14
Zebra offers Android SDKs for use with their printers. Specifically, There's a BluetoothConnectionInsecure class that allows you to connect to your printers without having to provide pairing information: http://www.zebra.com/us/en/products-services/software/link-os/link-os-sdk.html. Full samples are included in the JavaDoc.
If you cannot use the SDK, then BitBank's suggestion of using CreateInsecureRfCommSocket() is a good choice to make. Here are some articles concerning its usage:
http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createInsecureRfcommSocketToServiceRecord(java.util.UUID)
How to create Insecure RFCOMM Socket in Android?
I use this code
luugiathuy.com/2011/02/android-java-bluetooth/
The server side is the PC
the client is the device, with the app based on bluetooth chat example
The device (galaxy tab 7.0) can establish connection with the PC.
However the PC server (written in java and bluecove) did nothing, as nothing is connected.
The loop for trying to find connected device is
while(true) {
try {
System.out.println("waiting for connection...");
connection = notifier.acceptAndOpen();
Thread processThread = new Thread(new ProcessConnectionThread(connection));
processThread.start();
} catch (Exception e) {
e.printStackTrace();
return;
}
Output on PC:
uuid: 0000110100001000800000805f9b34fb
waiting for connection...
EDIT: source downloadhttps://github.com/luugiathuy/Remote-Bluetooth-Android
Same issue I got when I was trying in linux. But the reason (still not sure) when you run the bluetooth android application without turning on the Java server using bluecove, It will try to connect with the already installed bluetooth software. You may see the bluetooth icon asking for granting access to the mobile device.
To solve this, I just changed the uuid in the server and application (say from 1103 to 1101 and vice versa) and then started the server first and then the android application. Java server part started listening.
The reason I think may be the uuid when it did not found the bluecove stack service server, it got connected to the device server listening on same uuid. So after changing the uuid and making sure that the server is running before launching the android application should solve the issue.
If you are getting connected to the bluetooth system application and not to the Java bluecove server,
1) First change the uuid both server and android application.
2) Second make sure your server is running and listening on same uuid.
3) Launch the android application which try to communicate on same rfcomm connection uuid.
Server part code I took from : http://www.jsr82.com/jsr-82-sample-spp-server-and-client/
Library : http://code.google.com/p/bluecove/downloads/list
Yes, it happens with me too, I suggest you to fire following commend on shell, when it shows waiting for connection.
hcitool cc 58:C3:8B:D7:FA:F4
here 58:C3:8B:D7:FA:F4 is my device's bluetooth address, which should be replaced by your device's bluetooth address.
To get your device's bluetooth address, just start bluetooth in your device with discoverable mode and execute hcitool scan command, it will display all the active device with their name and bluetooth address.
Well you may run the above hcitool cc 58:C3:8B:D7:FA:F4 command via Java code as follows,
try
{
Process p=Runtime.getRuntime().exec("hcitool cc 58:C3:8B:D7:FA:F4");
}
catch ( Exception e )
{
}
The output from your program says it listens on UUID 0x1101. Is that true? The sample you reference shows it listening on a different UUID. Its Service Class Id is 0x04c6093b and is set as follows:
34 UUID uuid = new UUID(80087355); // "04c6093b-0000-1000-8000-00805f9b34fb"
35 String url = "btspp://localhost:" + uuid.toString() + ";name=RemoteBluetooth";
36 notifier = (StreamConnectionNotifier)Connector.open(url);
The two need to match on client and server.
I'm trying to use my Android phone as a handsfree kit (like the one for cars) in order to connect to another phone (any phone) and perform some handsfree functionality like (answer an incoming call, reject,.. etc) which can be done using the AT commands for handsfree profile.
For that, I'm using the well-known Bluetooth chat App, and reflection work around in order to establish a connection with any device:
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmp = (BluetoothSocket) m.invoke(device,1);
However, in order to achieve the handsfree functionality and understand the AT commands that I'm sending, the connected phone needs to be over the handsfree profile which uses the UUID: "0000111f-0000-1000-8000-00805F9B34FB"
Therefore, is there a way to achieve a connection to the handsfree profile?
Thanks!
You should only use this code when you have no other choice. The 1 in this code is the RFCOMM port. Each service has it's own RFCOMM port. This port is usually random between 1 and 31. You need to know which port the service (here handsfree profile) is using on the device that you want to connect to. You have to use the createRfcommSocketToServiceRecord method from the BluetoothDevice object to do this:
try { clientSocket = bluetoothDevice.createRfcommSocketToServiceRecord( serviceUUID ); }
catch (IOException e)
{
// handle error
}
This code is the correct way to use Bluetooth and should replace the one you're using.