设置蓝牙信标设备的UUID无法正常工作

问题描述 投票:1回答:1

我与我的设备配对,我使用此代码连接到它

   //this will try  to connect to our bluetooth device
public void connectGatt(Context context, BluetoothDevice btDevice) {
    this.btDevice = btDevice;
    mBluetoothGatt = btDevice.connectGatt(context, false, mGattCallback);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mBluetoothGatt != null) {
        mBluetoothGatt.requestMtu(512);
    }
}

这是我的GATT回调:

 private final BluetoothGattCallback mGattCallback =
        new BluetoothGattCallback() {
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                                int newState) {
                if (newState == BluetoothProfile.STATE_CONNECTED) {
                    tryToConnect = false;
                    Log.i("BluetoothService", "BluetoothService onConnectionStateChange CONNECTED");
                    if (back != null)
                        back.onResponse(REMOVE_CALLBACKS);
                    Log.i("", "Connected to GATT server.");
                    boolean discover = mBluetoothGatt.discoverServices();
                    Log.i("", "Attempting to start service discovery:" + discover);
                } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                    Log.i("BluetoothService", "BluetoothService onConnectionStateChange STATE_DISCONNECTED");
                    if (tryToConnect) {
                        if (back != null)
                            back.onResponse(REMOVE_CALLBACKS);
                        stopMonitoringBeacons();
                        stopListeningForBeacons();
                        mBluetoothAdapter.disable();
                        setSleep(1500);
                        mBluetoothAdapter.enable();
                        setSleep(1500);
                        Log.i("BluetoothService", "BluetoothService onConnectionStateChange WILL TRY CONNECT");
                        if (back != null)
                            back.onResponse(CONNECT);
                        tryToConnect = false;
                    }
                }
            }

            @Override
            // New services discovered
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                tryToConnect = false;
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    Log.i("BluetoothService", "BluetoothService onConnectionStateChange onServicesDiscovered GATT_SUCCESS" + status);
                    Log.w("", "onServicesDiscovered GATT_SUCCESS: " + status);
                    List<BluetoothGattService> listBGS = mBluetoothGatt.getServices();
                    Log.i("", "list size: " + listBGS.size());
                    if (listBGS.size() > 0) {
                        if (back != null)
                            back.onResponse(CONFIGURE);
                        String character = "FF05";
                        if (justName)
                            character = "FF01";
                        setCharacteristic(gatt, character);
                    } else {
                        Log.i("BluetoothService", "BluetoothService onConnectionStateChange onServicesDiscovered GATT_SUCCESS but ZERO SERVICES: " + btDevice.getBondState());
                        if (btDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
                            setSleep(500);
                            if (btDevice.getBondState() == BluetoothDevice.BOND_BONDED)
                                mBluetoothGatt.discoverServices();
                        } else if (btDevice.getBondState() == BluetoothDevice.BOND_NONE) {
                            askPairDevice();
                        }
                    }
                } else {
                    askPairDevice();
                    Log.w("BluetoothService", "BluetoothService onServicesDiscovered received: " + status);
                }
            }

            @Override
            // Result of a characteristic read operation
            public void onCharacteristicRead(final BluetoothGatt gatt,
                                             final BluetoothGattCharacteristic characteristic,
                                             int status) {
                handler.removeCallbacksAndMessages(null);
                Log.i("BluetoothService", "BluetoothService onCharacteristicRead");
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    Log.i("BluetoothService", "BluetoothService onCharacteristicRead GATT_SUCCESS");
                    Log.w("", "BGC onCharacteristicRead GATT_SUCCESS: " + status + " / char: " + characteristic);
                    if (characteristic.getUuid().toString().toUpperCase().contains("FF05")) {
                        final String value = toHexadecimal(characteristic.getValue());
                        if (newBeacon == null || newBeacon.getName() == null) {
                            checkIfNeedsToChangeUUID(gatt, value);
                        } else if (newBeacon != null && (newBeacon.getUuid() != null || justName)) {
                            Log.i("BluetoothService", "BluetoothService new Beacon UUID is: " + value);
                            newBeacon.setUuid(Identifier.parse(value).toString());
                            if (back != null)
                                back.onResponse(CHANGED);
                        } else {
                            changeUUID(gatt, characteristic, value);
                        }
                    } else if (characteristic.getUuid().toString().toUpperCase().contains("FF01")) {
                        changeName(gatt, characteristic);
                    }
                } else {
                    Log.i("", "");
                }
            }
        };

我感兴趣的部分在这里:

   public void changeUUID(final BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, String value) {
    int size = value.length();
    RandomString gen = new RandomString(size, new SecureRandom());
    String uuid = gen.nextString();
    Log.i("", "BluetoothService BGC value NEW UUID: " + uuid);
    boolean change = characteristic.setValue(hexStringToByteArray(uuid));
    Log.i("", "BluetoothService BGC value after: " + toHexadecimal(characteristic.getValue()) + " / has changed: " + change);
    boolean statusWrite = gatt.writeCharacteristic(characteristic);
    Log.i("", "BluetoothService BGC value after statusWRITE: " + statusWrite);
    if (statusWrite) {
        newBeacon.setUuid(Identifier.parse(toHexadecimal(characteristic.getValue())).toString());
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                setCharacteristic(gatt, "FF05");
            }
        });
    } else {
        if (back != null)
            back.onResponse(ERROR);
    }
}

这将称之为:

       try {
        Log.i("BluetoothService", "BluetoothService set characteristic: " + characteristic);
        BluetoothGattCharacteristic btChar = null;
        for (BluetoothGattService bgs : gatt.getServices()) {
            for (final BluetoothGattCharacteristic bgc : bgs.getCharacteristics()) {
                if (bgc.getUuid().toString().toUpperCase().contains(characteristic)) {
                    btChar = bgc;
                    gatt.readCharacteristic(bgc);
                    break;
                }
            }
        }
        final BluetoothGattCharacteristic btF = btChar;
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (btF != null)
                    gatt.readCharacteristic(btF);
            }
        }, 1000);
    } catch (Exception e) {
        Log.i("BluetoothService", "BluetoothService set characteristic ERROR: " + e.getMessage());
        setCharacteristic(gatt, characteristic);
    }
}

这可行,但不是100%,我可以说它只适用于不到50%的情况。而且我不明白为什么。有人可以帮忙吗?

我的意思是boolean statusWrite = gatt.writeCharacteristic(characteristic);总是返回给我“TRUE”所以如果在“changeUUID函数我做了另一个调用之后,尝试记录它,为什么它没有改变?还有其他应用程序,如果我检查,我的UUID不是改变了,这真的很奇怪。如果值相同,为什么写入为TRUE?

android bluetooth bluetooth-lowenergy beacon bluetooth-gatt
1个回答
1
投票

如果你看看documentationwriteCharacteristic,你会看到:

如果写操作已成功启动,则返回布尔值true

以上重点是我的。仅仅因为你成功启动了写入并不意味着它成功完成,事实上,在我的应用程序中,我经常看到它没有。

您需要做的是实现回调public void onCharacteristicWrite (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status),然后检查状态以查看它是否是BluetoothGatt.GATT_SUCCESS。如果没有,您将需要重试写入。我通常会生成重试最多10次的代码,然后在此之后放弃,触发向用户显示错误的代码。

大多数其他Android蓝牙API以这种方式工作 - 发现服务,发现特征等。这些异步操作中的每一个都可能失败,您必须实现回调以确定它们是否实际成功,并添加重试策略。

© www.soinside.com 2019 - 2024. All rights reserved.