25

私は現在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を取得するにはどうすればよいですか?

編集:

Nexus 7で作業しています。インターネットで見つけたコードを試しましたが、NullPointerExceptionも発生します:http://digitalhacksblog.blogspot.de/2012/05/android-example-bluetooth-discover-and.html

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

4

6 に答える 6

15

この状態に関するドキュメント...

常に余分なフィールドが含まれていますBluetoothDevice.EXTRA_UUID

しかし、あなたと同じように、私はこれが真実ではないことを発見しました.

fetchUuidsWithSdp()デバイスの検出がまだ行われているときに呼び出すと、 BluetoothDevice.EXTRA_UUIDnull になる可能性があります。

BluetoothAdapter.ACTION_DISCOVERY_FINISHEDを呼び出す前に、を受信するまで待つ必要がありますfetchUuidsWithSdp()

于 2013-03-12T22:11:58.470 に答える
10

注:CLASSICこの解決策はBluetooth に適用され、 BLE. BLEペリフェラル側のアドバタイザーでメーカー固有のデータを送信する方法を確認するには

Uuid の取得に関する問題は、Bluetooth アダプターが 1 つしかないことと、その目的のためにアダプターを使用する並列 API 呼び出しを行うことができないことです。

Eddie が指摘したように、 を待って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();
            }
        }
    }
}

更新: Android の最新バージョン (mm 以上) では、各デバイスとのペアリング プロセスがトリガーされます。

于 2016-05-06T10:54:37.283 に答える
3

心拍数デバイスを取得するために行ったサービスからサービス特性の 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;
}
于 2015-04-09T20:20:27.187 に答える
2

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

于 2014-06-18T14:47:21.193 に答える
0

以下は、リモートデバイスからレコードを取得するために機能しました

-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();
于 2014-10-14T01:06:32.667 に答える