web-dev-qa-db-fra.com

Android Bluetooth: Obtenez les UUID des appareils découverts

Comme je travaille actuellement sur une petite bibliothèque Bluetooth pour Android, j'essaie d'obtenir tous les uuids de service des appareils que j'ai découverts dans mon environnement.

Lorsque mon récepteur de diffusion obtient le BluetoothDevice.ACTION_FOUND intention, j'extrais l'appareil et appelle:

device.fetchUuidsWithSdp();

Il en résultera BluetoothDevice.ACTION_UUID intentions pour chaque appareil trouvé et je les gère avec le même récepteur:

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());

Le fait est que uuidExtra est toujours null.

Comment puis-je obtenir tous les UUID des appareils environnants?

ÉDITER:

Je travaille sur un Nexus 7. J'ai essayé du code que j'ai trouvé sur Internet et cela me donne également une exception NullPointerException: http://digitalhacksblog.blogspot.de/2012/05/Android-example-bluetooth-discover-and .html

Je vous remercie.

23
tellob

Le documentation sur ces états ...

Contient toujours le champ supplémentaire BluetoothDevice.EXTRA_UUID

Cependant, tout comme vous, j'ai trouvé que ce n'était pas vrai.

Si vous appelez fetchUuidsWithSdp() alors que la découverte de périphérique est toujours en cours, BluetoothDevice.EXTRA_UUID Peut être nul.

Vous devez attendre de recevoir BluetoothAdapter.ACTION_DISCOVERY_FINISHED Avant d'appeler fetchUuidsWithSdp().

15
Eddie

REMARQUE: Cette solution s'applique à CLASSIC bluetooth et non BLE. Pour BLE vérifiez comment envoyer des données spécifiques au fabricant dans l'annonceur du côté périphérique

Le problème avec la récupération des Uuids est que vous n'avez qu'un seul adaptateur Bluetooth, et nous ne pouvons pas avoir d'appels API parallèles qui utilisent l'adaptateur à sa fin.

Comme l'a souligné Eddie, attendez BluetoothAdapter.ACTION_DISCOVERY_FINISHED Puis appelez fetchUuidsWithSdp().

Cela ne garantit toujours pas la récupération des uuids pour tous les appareils. En plus de cela, vous devez attendre la fin de chaque appel ultérieur à fetchuuidsWithSdp(), puis appeler cette méthode pour un autre périphérique.

Voir le code ci-dessous -

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();
            }
        }
    }
}

MISE À JOUR: Dernières Android (mm et supérieures) entraîneraient le déclenchement d'un processus de couplage avec chaque appareil

8
Arunkumar

Je suppose que vous devez être jumelé avec l'appareil pour recevoir les uuids. C'est du moins ce qui m'est arrivé.

3
The Good Giant

Voici un bon exemple de la façon d'obtenir des UUID de caractéristiques de service à partir d'un service que j'ai fait pour obtenir des appareils de fréquence cardiaque:

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;
}
2
Droid Chris

device.getUuids () utilisez ceci pour obtenir tous les uuid de cet appareil apparié sous la forme de ParcelUuid; Exemple de code ci-dessous: -

private void get_uuid_from_paired_devices(){
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
        for (BluetoothDevice device: pairedDevices){

            for (ParcelUuid uuid: device.getUuids()){
                String uuid_string = uuid.toString();
                Log.d(TAG, "uuid : "+uuid_string);
            }
        }
    }
0
Biplob Das