2013-02-11 51 views
20

Vì hiện tại tôi đang làm việc trên một thư viện bluetooth nhỏ cho Android, tôi đang cố gắng tận dụng tất cả các dịch vụ của thiết bị mà tôi phát hiện được ở xung quanh mình.Android Bluetooth: Nhận UUID của thiết bị được phát hiện

Khi thu phát sóng của tôi nhận được BluetoothDevice.ACTION_FOUND ý định, tôi chiết xuất thiết bị và gọi:

device.fetchUuidsWithSdp(); 

Điều này sẽ dẫn BluetoothDevice.ACTION_UUID intents cho mỗi thiết bị tìm thấy và tôi là xử lý chúng với cùng một người nhận:

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

Điều này là uuidExtra luôn là null.

Làm cách nào tôi có thể nhận tất cả UUID của thiết bị xung quanh?

EDIT:

Im làm việc trên Nexus 7. Tôi đã thử mã tôi tìm thấy trên internet và điều này cũng mang lại cho tôi một NullPointerException: http://digitalhacksblog.blogspot.de/2012/05/android-example-bluetooth-discover-and.html

Cảm ơn bạn.

+1

Im phải đối mặt với chính xác tình hình! bạn đã tìm ra được giải pháp nào chưa ? Bạn có thể giúp tôi không. –

+0

Bạn đã giải quyết vấn đề này chưa? –

Trả lời

14

Các documentation về điều này khẳng định ...

Luôn chứa các trường bổ sung BluetoothDevice.EXTRA_UUID

Tuy nhiên, giống như bạn, tôi đã tìm thấy đây không phải là sự thật.

Nếu bạn gọi fetchUuidsWithSdp() trong khi khám phá thiết bị vẫn đang diễn ra BluetoothDevice.EXTRA_UUID có thể là rỗng.

Bạn nên đợi cho đến khi bạn nhận được BluetoothAdapter.ACTION_DISCOVERY_FINISHED trước khi thực hiện bất kỳ cuộc gọi nào tới fetchUuidsWithSdp().

+3

Tôi nhận được cùng một vấn đề, ngay cả khi tôi đợi khám phá thiết bị kết thúc trước khi gọi 'fetchUuidsWithSdp()'. – Kevin

+0

Điều này làm việc cho tôi trong một số trường hợp. Khi khám phá các thiết bị từ Samsung Galaxy Nexus 2 của tôi, tôi chỉ có thể nhận các dịch vụ trên HTC One (M7), không phải từ MacBook Pro của tôi (sau đó kết quả là null). –

+0

EDIT: nó có vẻ hoàn toàn ngẫu nhiên nếu 'fetchUuidsWithSdp()' hoạt động hay không, không có vấn đề mà tại đó điểm trong quá trình tôi gọi nó. –

3

Tôi cho rằng bạn cần phải ghép nối với thiết bị để nhận các uuids. Ít nhất, đây là những gì đã xảy ra với tôi.

-1

Dưới đây làm việc cho tôi để lấy hồ sơ từ các thiết bị từ xa

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

-1- device.fetchUuidsWithSdp();

-2-từ bên trong máy thu 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()); 
         } 
        } 

Bạn cũng có thể lấy hồ sơ ẩn cache UUID với

BluetoothDevice.getUuids(); 
+1

Tôi đã thử 'getUuids()' với ba thiết bị BLE khác nhau và tất cả trả về một mảng rỗng. –

2

Dưới đây là một ví dụ tốt về cách để có được UUIDs các đặc điểm dịch vụ từ một dịch vụ mà tôi đã làm để nhận các thiết bị nhịp tim:

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

Tôi tin rằng câu hỏi được đặt cho Bluetooth Classic, không phải Bluetooth LE ... như trường hợp của bạn đề cập đến "dịch vụ", "đặc điểm", "gatt" và các thiết bị có nhịp tim. – jschlepp

8

LƯU Ý: Giải pháp này áp dụng cho CLASSIC bluetooth chứ không phải BLE.Đối với BLE kiểm tra làm thế nào để gửi dữ liệu cụ thể nhà sản xuất trong quảng cáo ở phía bên ngoại vi

Vấn đề với lấy UUIDs là bạn chỉ có một bộ chuyển đổi bluetooth, và chúng tôi không thể có cuộc gọi api song song trong đó sử dụng bộ chuyển đổi cho mục đích của nó.

Khi Eddie chỉ ra, hãy đợi BluetoothAdapter.ACTION_DISCOVERY_FINISHED và sau đó gọi fetchUuidsWithSdp().

Tuy nhiên, điều này không thể đảm bảo các uuids được tìm nạp cho tất cả các thiết bị. Ngoài việc này phải chờ cho mỗi cuộc gọi tiếp theo đến fetchuuidsWithSdp() để hoàn thành, sau đó thực hiện cuộc gọi đến phương thức này cho một thiết bị khác.

Xem mã dưới đây -

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: phiên bản Android mới nhất (mm & trên) sẽ cho kết quả kích hoạt một quá trình ghép nối với mỗi thiết bị

+0

Thú vị tôi vẫn nhận được giá trị mặc dù: ( –

+1

Bạn có thể chia sẻ mã của bạn không? – Arunkumar

+1

Đảm bảo đăng ký các mục đích. –

Các vấn đề liên quan