Трудность чтения данных из пакета BLE на Android

Я проектирую сенсорную систему с сенсором и устройством Android на принимающей стороне:

На данный момент, поскольку датчик недоступен, я использую другое устройство Android в качестве рекламодателя BLE. Обратите внимание, что я не подключаюсь к устройству, я просто прочитал рекламный пакет.

На стороне передатчика я создаю пакет, который содержит имя устройства, UUID и данные конкретного UUID:

private void advertise() {
    BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();

    AdvertiseSettings settings = new AdvertiseSettings.Builder()
            .setAdvertiseMode( AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY )
            .setTxPowerLevel( AdvertiseSettings.ADVERTISE_TX_POWER_HIGH )
            .setConnectable(false)
            .build();

    ParcelUuid pUuid = new ParcelUuid( UUID.fromString( getString( R.string.ble_uuid ) ) );
    byte[] mdata = "Hello".getBytes(Charset.forName("UTF-8"));

    AdvertiseData data = new AdvertiseData.Builder()
            .setIncludeDeviceName( true )
            .addServiceUuid( pUuid )
            .addServiceData( pUuid, mdata )
            .build();

    AdvertiseCallback advertisingCallback = new AdvertiseCallback() {
        @Override
        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
            super.onStartSuccess(settingsInEffect);
        }

        @Override
        public void onStartFailure(int errorCode) {
            Log.e( "BLE", "Advertising onStartFailure: " + errorCode );
            super.onStartFailure(errorCode);
        }
    };

Эта часть хорошо работает, потому что я хочу отправлять исходные данные, которые я получаю с помощью приложения сканера BLE.

Проблема на принимающей стороне. Вот что я делаю:

private void discover() {
    List<ScanFilter> filters = new ArrayList<ScanFilter>();

    ScanFilter filter = new ScanFilter.Builder()
            .setServiceUuid( new ParcelUuid(UUID.fromString( getString(R.string.ble_uuid ) ) ) )
            .build();
    filters.add( filter );

    ScanSettings settings = new ScanSettings.Builder()
            .setScanMode( ScanSettings.SCAN_MODE_LOW_LATENCY )
            .build();

    mBluetoothLeScanner.startScan(filters, settings, mScanCallback);

    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            mBluetoothLeScanner.stopScan(mScanCallback);
        }
    }, 10000);
}

Моя функция scanCallBack выглядит следующим образом:

private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            if( result == null
                    || result.getDevice() == null
                    || TextUtils.isEmpty(result.getDevice().getName()) )
                return;

        StringBuilder builder = new StringBuilder( result.getDevice().getName());
        for(int j = 0; j < result.getScanRecord().getServiceUuids().size(); j++){
            builder.append("\n");
            builder.append("Result no. " + j);
            builder.append("\n");
            builder.append(result.getScanRecord().getServiceUuids().get(j));
            builder.append("\n");
            builder.append("Service data: ");
            builder.append("\n");
            builder.append(result.getScanRecord().getServiceData(result.getScanRecord().getServiceUuids().get(j)));
        }
        mText.setText(builder.toString());
    }

Этот код всегда возвращает ноль, в тот момент, когда я пытаюсь прочитать мои данные.

В целом, я могу прочитать имя устройства и UUID устройства, но не данные.

Пожалуйста, дайте мне немного мудрости по этому вопросу.

1 ответ

Решение

Я обнаружил, что Android использует 16-битный UUIDS, а это означает, что он переводит 128-битный UUID следующим образом:

Это оригинальный 128-битный UUID:01122334-4556-6778-899A-ABBCCDDEEFF0,

Данные отправляются с использованием этого UUID.

Как только этот UUID получен от android, android сохраняет только 2334 и сбрасывает остальные.

Затем он создает новый 128-битный UUID по умолчанию:

0000XXXX-0000-1000-8000-00805f9b34fb,

Где XXXX - это мой 16-битный UUID 2334.

Поэтому для доступа к моим данным мне нужно найти 128-битный UUID, который android дал моим данным, в этом случае:

00002334-0000-1000-8000-00805f9b34fb,

Так что в моем случае было очень удобно отправлять мои данные по 128-битному UUID, который Android назначил мне.

Я не уверен, почему это происходит, но теперь это работает отлично.

Другие вопросы по тегам