Some time ago I started developing to Android.
I'm trying to create a BluetoothServerSocket.
I have this code:
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
NAME is the name of my server (I can give here what i want) or not?
And I don't known what is MY_UUID. Where can I get MY_UUID from?
You can get the UUID by utilizing the getUuids() method of the BluetoothDevice class. See this excellent thread that describes this very process, along with examples and the resulting output:
Android - Get Bluetooth UUID for this device
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'm relatively new to Android and am creating a Bluetooth App on a Nexus 9 that will connect to a Bluetooth device application my coworker has written on an Arduino processor. I'm following this doc, which is very helpful:
http://developer.android.com/guide/topics/connectivity/bluetooth.html
However, to connect as a client I have to use this code, which uses this MY_UUID symbol.
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
In the text the doc says: "The UUID passed here must match the UUID used by the server device when it opened its BluetoothServerSocket (with listenUsingRfcommWithServiceRecord(String, UUID)). Using the same UUID is simply a matter of hard-coding the UUID string into your application and then referencing it from both the server and client code."
This is confusing to me... does it mean it must match a UUID specified in the Arduino firmware?? My coworker who wrote the firmware doesn't know what that would be. When I sniff his firmware advertising, it has ID "RNBT-DFBC", but when I use that as a UUID I get an exception :
java.lang.IllegalArgumentException: RNBT-DFBC is not a valid Bluetooth address
And none of the sample Bluetooth projects I've looked at seem to explain the basis of this UUID value, they're just "magic numbers."
So... what on earth do I use as the parameter for my createRfcommSocketToServiceRecord() function? I feel like I am misunderstanding this, because a Bluetooth client cant possibly generally have such "intimate" knowledge of a server it wants to connect to. So sorry if it's a dumb question, but any help is appreciated.
Here is a nice way that tells you how to get UUID for your app.
You should use a pre-shared UUID that both your device and the Arduino device knows. For example:
public static final java.util.UUID MY_UUID
= java.util.UUID.fromString("DEADBEEF-0000-0000-0000-000000000000");
The String is in a format according to RFC 4122. You can find more information about the specifics for Android in the Android UUID documentation .
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...
I'm starting to work on Bluetooth in Android recently.
I want to build an application that can read the data recorded by a sensor through bluetooth.
I have some sample code, but looks like I need another UUID of a different device.It looks like this:
private static final UUID MY_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
Later on in the code, it uses this UUID to make a connection:
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
I have done some research online, like [here][1]. I think I need a different UUID number for the new device I'm working on. How do I get the UUID number?
On the device, there are two lines of number saying:
SN: 1201L0023
BT: 10:00:E8:C5:16:85
Thanks in advance!
Jake
UUIDs are not tied to particular devices. They identify software services. Some UUIDs for defined profiles are set by BT. The UUIDs used with RFCOMM sockets like your example are arbitrary. You just need both sides to use the same one. In general, devices connect and then use service discovery protocol to find out what services (UUIDs) are supported on the remote device.
Is there any way for Android to connect to a Bluetooth device using a specific port instead of using service UUID?
I know this option is available in other platforms which provide Bluetooth support (Java ME for example by specifying a "btspp://" style URL).
Thanks!
Ok, it's been a while, but I found a solution to the problem. I actually intended to give up and use UUID, but I kept getting a Service Discovery Failed (IO)exception, and when I tried to find a solution to the service discovery issue, I found the solution to my original question... Ain't life something?:)
Anyways, this is the link I stumbled upon, though you should note there is a mistake in the answer (they actually simply connected to port 1, instead of using a service UUID).
And after this short history lesson, here is the solution:
Using reflection, it is possible to create the Rfcomm socket connecting to a port number instead of UUID:
int bt_port_to_connect = 5; // just an example, could be any port number you wish
BluetoothDevice device = ... ; // get the bluetooth device (e.g., using bt discovery)
BluetoothSocket deviceSocket = null;
...
// IMPORTANT: we create a reference to the 'createInsecureRfcommSocket' method
// and not(!) to the 'createInsecureRfcommSocketToServiceRecord' (which is what the
// android SDK documentation publishes
Method m = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] {int.class});
deviceSocket = (BluetoothSocket) m.invoke(device,bt_port_to_connect);
A few things to notice:
since we're using Invoke, the first parameter is the object we're invoking the method on, the second parameter of invoke is actually the first function parameter)
There is also a secure version available ('createRfcommSocket'), which accepts a bluetooth channel number as a single parameter (again, since this is invoke style, you'll need to pass the object to invoke the method on, as mentioned in -1- )
I found what appears to be a link to these functions' prototypes
Good luck to all.
Bluetooth Android connections are exclusively done via UUID. Each Bluetooth device has a UUID for every service it runs (see Bluetooth SDP).
You just give Android the UUID to watch for and, in client mode, it will find a socket to connect to automatically (including port). In server mode, it will wait for the specified device to initiate a connection using the specified UUID.
The BluetoothSocket object is also valid when connection is established (use getInput/Output Stream)
See Server Socket documentation and Client Socket documentation.
If you really want to check everything, you can see what Android decodes from the other device's SDP and the UUID you provided.
Use this tutorial to get the Bluetooth interface (very easy to do).
Then the code should look something like this:
IBluetooth ib =getIBluetooth();
Int otherDevicePort = ib.getRemoteServiceChannel(otherDeviceAddress, UUID);
I'm using bluecove which allow me to do so with the function Connector.open().
I use the following url:
btspp://" + phoneID + ":" + phonePort
N.b.: Some options can be added (e.g.: authenticate=false; or encrypt=false;).
With phoneID being the the being the Bluetooth address and phonePort the port number.
How to find the Bluetooth address?
From this link:
From the Home screen, open the app drawer, then open “Settings“.
Select “System“. (Skip this step on some models)
Scroll down to the bottom and tap “About Phone“, “About device“, or “About tablet“.
Scroll down to the bottom and tap “Status“.
Scroll down and the “Bluetooth address” will be shown in the list.
How to find the port number?
I haven't been able to find which port is supposed to be used yet...
I used 5 and it works but I need to research why and if I want to change the phone I will need to know if I also need to change the port.