Android Bluetooth: Get Uuids Of Discovered Devices
Solution 1:
The documentation on this states...
Always contains the extra field
BluetoothDevice.EXTRA_UUID
However, just like you, I have found this not to be true.
If you call fetchUuidsWithSdp()
while device discovery is still taking place BluetoothDevice.EXTRA_UUID
can be null.
You should wait until you receive BluetoothAdapter.ACTION_DISCOVERY_FINISHED
before you make any calls to fetchUuidsWithSdp()
.
Solution 2:
NOTE: This solution applies to
CLASSIC
bluetooth and notBLE
. ForBLE
check how to send manufacturer specific Data in advertiser on the peripheral side
The problem with fetching Uuids is that you have only one bluetooth adapter, and we cannot have parallel api calls which uses adapter for its purpose.
As Eddie pointed out, wait for BluetoothAdapter.ACTION_DISCOVERY_FINISHED
and then call fetchUuidsWithSdp()
.
Still this cannot guarantee uuids to be fetched for all devices. In addition to this one must wait for each subsequent call to fetchuuidsWithSdp()
to complete, and then give a call to this method for another device.
See the code below --
ArrayList<BluetoothDevice> mDeviceList = new ArrayList<BluetoothDevice>();
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
publicvoidonReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device);
} elseif (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
// discovery has finished, give a call to fetchUuidsWithSdp on first device in list.if (!mDeviceList.isEmpty()) {
BluetoothDevice device = mDeviceList.remove(0);
boolean result = device.fetchUuidsWithSdp();
}
} elseif (BluetoothDevice.ACTION_UUID.equals(action)) {
// This is when we can be assured that fetchUuidsWithSdp has completed.// So get the uuids and call fetchUuidsWithSdp on another device in list
BluetoothDevice deviceExtra = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
System.out.println("DeviceExtra address - " + deviceExtra.getAddress());
if (uuidExtra != null) {
for (Parcelable p : uuidExtra) {
System.out.println("uuidExtra - " + p);
}
} else {
System.out.println("uuidExtra is still null");
}
if (!mDeviceList.isEmpty()) {
BluetoothDevice device = mDeviceList.remove(0);
boolean result = device.fetchUuidsWithSdp();
}
}
}
}
UPDATE: Latest android versions (mm & above) would result in triggering a pairing process with each device
Solution 3:
Here is a good example of how to get UUIDs of service characteristics from a service that I did for getting heart rate devices:
privateclassHeartRateBluetoothGattCallbackextendsBluetoothGattCallback {
@OverridepublicvoidonConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
logMessage("CONNECTED TO " + gatt.getDevice().getName(), false, false);
gatt.discoverServices();
} elseif(newState == BluetoothProfile.STATE_DISCONNECTED) {
logMessage("DISCONNECTED FROM " + gatt.getDevice().getName(), false, false);
if(mIsTrackingHeartRate)
handleHeartRateDeviceDisconnection(gatt);
}
}
@OverridepublicvoidonServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
logMessage("DISCOVERING SERVICES FOR " + gatt.getDevice().getName(), false, false);
if(mDesiredHeartRateDevice != null &&
gatt.getDevice().getAddress().equals(mDesiredHeartRateDevice.getBLEDeviceAddress())) {
if(subscribeToHeartRateGattServices(gatt)) {
mIsTrackingHeartRate = true;
setDeviceScanned(getDiscoveredBLEDevice(gatt.getDevice().getAddress()), DiscoveredBLEDevice.CONNECTED);
broadcastHeartRateDeviceConnected(gatt.getDevice());
} else
broadcastHeartRateDeviceFailedConnection(gatt.getDevice());
} else {
parseGattServices(gatt);
disconnectGatt(getDiscoveredBLEDevice(gatt.getDevice().getAddress()));
}
}
}
@OverridepublicvoidonCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
if(characteristic.getUuid().equals(UUID.fromString(HEART_RATE_VALUE_CHAR_READ_ID))) {
intflag= characteristic.getProperties();
intformat= -1;
if ((flag & 0x01) != 0)
format = BluetoothGattCharacteristic.FORMAT_UINT16;
elseformat= BluetoothGattCharacteristic.FORMAT_UINT8;
IntegerheartRateValue= characteristic.getIntValue(format, 1);
if(heartRateValue != null)
broadcastHeartRateValue(heartRateValue);
else
Log.w(SERVICE_NAME, "UNABLE TO FORMAT HEART RATE DATA");
}
};
};
privatevoidparseGattServices(BluetoothGatt gatt) {
booleanisHeartRate=false;
for(BluetoothGattService blueToothGattService : gatt.getServices()) {
logMessage("GATT SERVICE: " + blueToothGattService.getUuid().toString(), false, false);
if(blueToothGattService.getUuid().toString().contains(HEART_RATE_DEVICE_SERVICE_CHARACTERISTIC_PREFIX))
isHeartRate = true;
}
if(isHeartRate) {
setDeviceScanned(getDiscoveredBLEDevice(gatt.getDevice().getAddress()), DiscoveredBLEDevice.IS_HEART_RATE);
broadcastHeartRateDeviceFound(getDiscoveredBLEDevice(gatt.getDevice().getAddress()));
} else
setDeviceScanned(getDiscoveredBLEDevice(gatt.getDevice().getAddress()), DiscoveredBLEDevice.NOT_HEART_RATE);
}
privatevoidhandleHeartRateDeviceDisconnection(BluetoothGatt gatt) {
broadcastHeartRateDeviceDisconnected(gatt.getDevice());
gatt.close();
clearoutHeartRateData();
scanForHeartRateDevices();
}
privatevoiddisconnectGatt(DiscoveredBLEDevice device) {
logMessage("CLOSING GATT FOR " + device.getBLEDeviceName(), false, false);
device.getBlueToothGatt().close();
device.setBlueToothGatt(null);
mInDiscoveryMode = false;
}
privatebooleansubscribeToHeartRateGattServices(BluetoothGatt gatt) {
for(BluetoothGattService blueToothGattService : gatt.getServices()) {
if(blueToothGattService.getUuid().toString().contains(HEART_RATE_DEVICE_SERVICE_CHARACTERISTIC_PREFIX)) {
mHeartRateGattService = blueToothGattService;
for(BluetoothGattCharacteristic characteristic : mHeartRateGattService.getCharacteristics()) {
logMessage("CHARACTERISTIC UUID = " + characteristic.getUuid().toString(), false, false);
for(BluetoothGattDescriptor descriptor :characteristic.getDescriptors()) {
logMessage("DESCRIPTOR UUID = " + descriptor.getUuid().toString(), false, false);
}
if(characteristic.getUuid().equals(UUID.fromString(HEART_RATE_VALUE_CHAR_READ_ID))) {
gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptordescriptor= characteristic.getDescriptor(UUID.fromString(HEART_RATE_VALUE_CHAR_DESC_ID));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
return gatt.writeDescriptor(descriptor);
}
}
break; //break out of master for-loop
}
}
returnfalse;
}
Solution 4:
I suppose you need to be paired with the device in order to receive the uuids. At least, this is what happened to me.
Solution 5:
device.getUuids() use this to get all the uuid of that paired device in the form of ParcelUuid; Example code below:-
privatevoidget_uuid_from_paired_devices(){
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
for (BluetoothDevicedevice: pairedDevices){
for (ParcelUuiduuid: device.getUuids()){
String uuid_string = uuid.toString();
Log.d(TAG, "uuid : "+uuid_string);
}
}
}
Post a Comment for "Android Bluetooth: Get Uuids Of Discovered Devices"