7

I'm advertising an Android device over Bluetooth Low Energy with the below code:

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[] messageToSend = "Data".getBytes(Charset.forName("UTF-8"));

    AdvertiseData data = new AdvertiseData.Builder()
            .addServiceUuid(pUuid)
            .addServiceData(pUuid, messageToSend)
            .build();

    AdvertiseCallback advertisingCallback = new AdvertiseCallback() {
        @Override
        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
            Log.d("Successful", "start");
            super.onStartSuccess(settingsInEffect);
        }

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

    advertiser.startAdvertising(settings, data, advertisingCallback);
}

The plan is this: send a message (in this case "Data") to every BLE-compatible device nearby with Bluetooth turned on with advertising. I've tested it, and the other device received the "Data" string successfully in the AdvertiseData object. But as I know there are limitations of this approach (maybe I'm wrong on any of the next points, please feel free to correct me ;) ):

  • The total size of the advertising data (AdvertiseData object) can be maximum 32 bytes
  • From this structure 20 bytes can be used to send custom advertising data

If I understand correctly the last point, it means that I can send 20 ASCII characters encoded by UTF-8 with one AdvertiseData object (I would like to approach this situation similar to the answer of this question to send more than 20 bytes). However, currently I can send up to 9 ASCII characters - if I want to send one more, the callback's onStartFailure() method is returning with errorCode 1 (ADVERTISE_FAILED_DATA_TOO_LARGE according to the documentation of AdvertiseCallback class). Of course this 'limit' is even smaller when I'm using non-ASCII characters (for example accented characters - é, ű, and so on)...

It is possible that my approach is not the best, because I've found different examples on the web to send advertising data... so maybe I'm constructing the AdvertiseData object with some unnecessary object which are occupying free space in data. So basically I would like to find out:

  1. How many bytes is the size of the AdvertiseData object?
  2. How is this object splitted? What are the parts which I have to think about during calculation, and how big are they?

Could you help me in my experiment? :D


My AdvertiseData object looks like this:

AdvertiseData 
  [mServiceUuids=
    [bdc7950d-731f-4d4d-8e47-c090502dbd63], 
  mManufacturerSpecificData={}, 
  mServiceData=
    {bdc7950d-731f-4d4d-8e47-c090502dbd63=[68, 97, 116, 97]}, 
  mIncludeTxPowerLevel=false,
  mIncludeDeviceName=false]
Geryson
  • 719
  • 2
  • 8
  • 25
  • Have you found any solution? To me, it returns the error with just one letter.... I don't know what's going to happen, I'm pretty lost. – Daniel RL Aug 07 '18 at 11:32

0 Answers0