2013-02-11 2 views
20

Поскольку я сейчас работаю над небольшой библиотекой bluetooth для Android, я пытаюсь получить все сервисные утилиты устройств, которые я обнаружил в своей окружающей среде.Android Bluetooth: Получить UUID обнаруженных устройств

Когда мой радиовещательный приемник получает 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

Im обращенного к точному ситуация! вы нашли какое-нибудь решение? не могли бы вы мне помочь. –

+0

Вы решили эту проблему? –

ответ

14

documentation на этом говорится ...

всегда содержит дополнительное поле BluetoothDevice.EXTRA_UUID

Однако, так же как и вы, я нашел, что это не правда.

Если вы звоните fetchUuidsWithSdp(), пока обнаружение устройства все еще имеет место BluetoothDevice.EXTRA_UUID может быть пустым.

Прежде чем звонить, вы должны дождаться, пока не получите fetchUuidsWithSdp().

+3

Я получаю ту же проблему, даже если дожидаться завершения обнаружения устройства до вызова 'fetchUuidsWithSdp()'. – Kevin

+0

Это работает для меня в некоторых случаях. При обнаружении устройств от Samsung Galaxy Nexus 2 я могу получать услуги только на своем HTC One (M7), а не на моем MacBook Pro (тогда результат равен нулю). –

+0

EDIT: кажется совершенно случайным, если 'fetchUuidsWithSdp()' работает или нет, независимо от того, в какой момент процесса я его вызываю. –

3

Я полагаю, вам нужно быть в паре с устройством, чтобы получить uuids. По крайней мере, это то, что случилось со мной.

-1

Ниже работал для меня, чтобы извлечь записи из удаленного устройства

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

Я попробовал 'getUuids()' с тремя различными устройствами BLE, и все вернули нулевой массив. –

2

Вот хороший пример того, как получить 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

Я считаю, что этот вопрос ориентирован на Bluetooth Classic, а не на Bluetooth LE ... как и в случае с вашими упоминаниями о «услугах», «характеристиках», «гаттах» и устройствах с сердечным ритмом. – jschlepp

8

ПРИМЕЧАНИЕ: Данное решение применяется к 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: Последних андроид версии (мм & выше) приведет к срабатыванию процесса сопряжения с каждым устройством

+0

Интересно, я все еще получаю null, хотя :( –

+1

Можете ли вы рассказать вам код? – Arunkumar

+1

Обязательно зарегистрируйтесь. –

Смежные вопросы