2013-02-11 63 views
20

現在、Android用の小さなBluetoothライブラリを使用しているため、私は周囲で発見したデバイスのすべてのサービスを取得しようとしています。 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:

イムネクサス7に取り組んでは、私は私がインターネット上で見つけたコードを試してみましたが、これも私にはNullPointerExceptionを与える:http://digitalhacksblog.blogspot.de/2012/05/android-example-bluetooth-discover-and.html

ありがとうございました。

+1

イムでペアリング処理をトリガすることになります状況!何か解決策を見つけましたか?手伝ってくれませんか。 –

+0

あなたはこの問題を解決しましたか? –

答えて

14

この上documentationは...

を述べ、必ず余分なフィールドにBluetoothDevice.EXTRA_UUID

が含まれているが、ちょうどあなたのように、私は本当ではないことが、これを発見しました。

に電話をかけても、デバイス検出が行われている間にBluetoothDevice.EXTRA_UUIDにnullを設定できます。

fetchUuidsWithSdp()に電話をかける前に、BluetoothAdapter.ACTION_DISCOVERY_FINISHEDを受け取るまで待つ必要があります。

+3

'fetchUuidsWithSdp()'を呼び出す前にデバイス発見が完了するのを待っても、同じ問題が発生します。 – Kevin

+0

これは私にとってはうまくいくことがあります。私のSamsung Galaxy Nexus 2からデバイスを検出すると、自分のHTC One(M7)のみでサービスを受け取り、MacBook Proではサービスを受けることはできません(結果はnullです)。 –

+0

EDIT: 'fetchUuidsWithSdp()'が動作しているかどうかにかかわらず、プロセスのどこのポイントであっても完全にランダムなようです。 –

3

uuidsを受信するには、デバイスとペアリングする必要があるとします。 少なくとも、これは私に起こったことです。

-1

以下は、リモートデバイス

-0- 
registerReceiver(.., 
       new IntentFilter(BluetoothDevice.ACTION_UUID)); 

-1- device.fetchUuidsWithSdp()からレコードを取得するために私のために働きました。

-2-からbroadcaseレシーバ

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

内また、ここで

BluetoothDevice.getUuids(); 
+1

3つの異なるBLEデバイスで 'getUuids()'を試しましたが、すべてがnull配列を返しました。 –

2

とオフラインキャッシュされたUUIDのレコードを取得することができますから、サービス特性の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のクラシックではなく、Bluetooth LEに対応していると信じています。「サービス」、「特性」、「ガット」、および心拍デバイスについて言及しています。 – jschlepp

8

注:この解決方法はCLASSICブルートゥースに適用され、BLEには適用されません。末梢側

に広告主に メーカー固有のデータを送信する方法BLEチェックのためのUUIDを取得の問題は、あなたが唯一のBluetoothアダプタを持っていることであり、我々はその目的のためにアダプタを使用して並列API呼び出しを持つことはできません。

エディが指摘しているように、BluetoothAdapter.ACTION_DISCOVERY_FINISHEDを待ち、fetchUuidsWithSdp()に電話してください。

これでも、すべてのデバイスでUUIDを取得できるとは限りません。これに加えて、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バージョン(上記ミリ&)が正確に対向する各デバイス

+0

興味深いですが、まだヌルになっています:( –

+1

あなたはコードを共有できますか? – Arunkumar

+1

インテントを必ず登録してください。 –

関連する問題