Установка UUID устройства маяка Bluetooth не работает правильно - PullRequest
0 голосов
/ 17 сентября 2018

Я соединяюсь с моим устройством, я подключаюсь к нему, используя этот код

   //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); Всегда возвращает мне «ИСТИНА», поэтому, если в функции «changeUUID, которую я выполняю после этого другого вызова, чтобы попытаться зарегистрировать ее, почему она НЕ изменяется? Также с другими приложениями, если я проверяю, мой UUID не изменяется, что действительно странно. Зачем получать значение ИСТИНА для записи, если значение одинаково?

1 Ответ

0 голосов
/ 17 сентября 2018

Если вы посмотрите документацию для writeCharacteristic, вы увидите следующее:

Возвращает логическое значение true, если операция записи была инициировано успешно

Выше выделено мое.То, что вы успешно инициировали запись, не означает, что успешно завершено , и действительно, в моих приложениях я часто вижу, что это не так.

Что вам нужно сделать, это реализовать обратный вызовpublic void onCharacteristicWrite (BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status), затем проверьте состояние, чтобы узнать, является ли оно BluetoothGatt.GATT_SUCCESS.Если нет, вам нужно будет повторить запись.Я обычно делаю код, который повторяется до 10 раз, а затем отказывается, вызывая код, сообщающий пользователю об ошибке.

Большинство других API-интерфейсов Android Bluetooth работают таким образом - обнаружение служб, обнаружение характеристик и т. Д.Каждая из этих асинхронных операций может завершиться ошибкой, и вам нужно реализовать обратные вызовы, чтобы выяснить, действительно ли они выполнены успешно, и добавить стратегию повторных попыток.

...