Android Bluetooth: получить UUID обнаруженных устройств
Поскольку я сейчас работаю над небольшой библиотекой bluetooth для Android, я пытаюсь получить все служебные uuids устройств, которые я обнаружил в своих окружающих.
Когда мой вещательный приемник получает намерение BluetoothDevice.ACTION_FOUND
, я извлекаю устройство и вызываю:
device.fetchUuidsWithSdp();
Это приведет к BluetoothDevice.ACTION_UUID
намерениям для каждого найденного устройства, и я обрабатываю их с одним и тем же получателем:
BluetoothDevice d = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
if(uuidExtra == null) {
Log.e(TAG, "UUID = null");
}
if(d != null && uuidExtra != null)
Log.d(TAG, d.getName() + ": " + uuidExtra.toString());
Дело в том, что uuidExtra
всегда null
.
Как я могу получить все UUID окружающих устройств?
EDIT:
Im работает над Nexus 7. Я попробовал код, который я нашел в Интернете, и это также дает мне NullPointerException: http://digitalhacksblog.blogspot.de/2012/05/android-example-bluetooth-discover-and.html
Спасибо.
Ответы
Ответ 1
документация об этом состоянии...
Всегда содержит дополнительное поле BluetoothDevice.EXTRA_UUID
Однако, как и вы, я обнаружил, что это не так.
Если вы вызываете fetchUuidsWithSdp()
, пока обнаружение устройства все еще происходит, BluetoothDevice.EXTRA_UUID
может быть нулевым.
Подождите, пока вы не получите BluetoothAdapter.ACTION_DISCOVERY_FINISHED
, прежде чем делать какие-либо вызовы fetchUuidsWithSdp()
.
Ответ 2
ПРИМЕЧАНИЕ. Это решение применяется к CLASSIC
bluetooth, а не к BLE
. Для BLE
проверьте, как отправить данные производителя в рекламодателях на периферийной стороне
Проблема с выборкой Uuids заключается в том, что у вас есть только один адаптер bluetooth, и мы не можем иметь параллельные вызовы api, которые используют адаптер для своей цели.
Как заметил Эдди, дождитесь BluetoothAdapter.ACTION_DISCOVERY_FINISHED
, а затем вызовите fetchUuidsWithSdp()
.
Тем не менее это не может гарантировать выборку uuids для всех устройств. В дополнение к этому нужно дождаться завершения каждого последующего вызова fetchUuidsWithSdp()
, а затем вызвать вызов этого метода для другого устройства.
Смотрите код ниже -
ArrayList<BluetoothDevice> mDeviceList = new ArrayList<BluetoothDevice>();
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(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);
} else if (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();
}
} else if (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:. Последние версии для Android (мм и выше) приведут к запуску процесса сопряжения с каждым устройством.
Ответ 3
Я предполагаю, что вам нужно быть сопряженным с устройством, чтобы получить uuids.
По крайней мере, это то, что случилось со мной.
Ответ 4
Вот хороший пример того, как получить UUID от характеристик службы из службы, которую я сделал для получения устройств с ЧСС:
private class HeartRateBluetoothGattCallback extends BluetoothGattCallback {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
logMessage("CONNECTED TO " + gatt.getDevice().getName(), false, false);
gatt.discoverServices();
} else if(newState == BluetoothProfile.STATE_DISCONNECTED) {
logMessage("DISCONNECTED FROM " + gatt.getDevice().getName(), false, false);
if(mIsTrackingHeartRate)
handleHeartRateDeviceDisconnection(gatt);
}
}
@Override
public void onServicesDiscovered(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()));
}
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
if(characteristic.getUuid().equals(UUID.fromString(HEART_RATE_VALUE_CHAR_READ_ID))) {
int flag = characteristic.getProperties();
int format = -1;
if ((flag & 0x01) != 0)
format = BluetoothGattCharacteristic.FORMAT_UINT16;
else
format = BluetoothGattCharacteristic.FORMAT_UINT8;
Integer heartRateValue = characteristic.getIntValue(format, 1);
if(heartRateValue != null)
broadcastHeartRateValue(heartRateValue);
else
Log.w(SERVICE_NAME, "UNABLE TO FORMAT HEART RATE DATA");
}
};
};
private void parseGattServices(BluetoothGatt gatt) {
boolean isHeartRate = 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);
}
private void handleHeartRateDeviceDisconnection(BluetoothGatt gatt) {
broadcastHeartRateDeviceDisconnected(gatt.getDevice());
gatt.close();
clearoutHeartRateData();
scanForHeartRateDevices();
}
private void disconnectGatt(DiscoveredBLEDevice device) {
logMessage("CLOSING GATT FOR " + device.getBLEDeviceName(), false, false);
device.getBlueToothGatt().close();
device.setBlueToothGatt(null);
mInDiscoveryMode = false;
}
private boolean subscribeToHeartRateGattServices(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);
BluetoothGattDescriptor descriptor = 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
}
}
return false;
}
Ответ 5
Ниже я работал для получения записей с удаленного устройства
-0-
registerReceiver(..,
new IntentFilter(BluetoothDevice.ACTION_UUID));
-1-
device.fetchUuidsWithSdp();
-2 - из приемника в широкополосном режиме
if (BluetoothDevice.ACTION_UUID.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] uuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
for (Parcelable ep : uuids) {
Utilities.print("UUID records : "+ ep.toString());
}
}
Вы также можете получить автономные кэшированные записи UUID с помощью
BluetoothDevice.getUuids();