简体   繁体   中英

Android BLE Peripheral Mode: custom characteristics not detected

I am trying to implement a BluetoothGattServer on a Sony SmartWatch 3.

I can sucessfully open a Gatt server as well as advertise.

Using the BLE Scanner application , I have inconsistent results while discovering my custom services and its custom characteristics.

  1. On a Samsung Galaxy Note 8 - Android 4.4 - I can detect correctly the custom service and the custom characteristics ;
  2. On a Nexus 7 - Android 5.0.1 - I can detect my custom service but only a characteristic with weird UUID : 00000000-0000-1000-8000-00805f9b34fb
  3. On a Samsung Galaxy Note 8 - CynaogenMod Marshmallow - same as Nexus 7.

Here is the code I run on the Wear device :

public final class BluetoothServer extends BluetoothGattServerCallback{
    private final static String TAG = BluetoothServer.class.getSimpleName();
    private final static String BASE_UUID = "0000%s-0000-1000-8000-00805f9b34fb";


    public final static UUID MAIN_SERVICE = UUID.fromString(String.format(BASE_UUID, "FEE0"));
    public final static UUID CHARAC_REQUEST = UUID.fromString(String.format(BASE_UUID, "FEE01"));
    public final static UUID CHARAC_RECORDING = UUID.fromString(String.format(BASE_UUID, "FEE02"));


    private final BluetoothGattServer gattServer;

    private final BluetoothGattService mainServer;
    private final BluetoothGattCharacteristic requestCharacteristic;
    private final BluetoothGattCharacteristic recordingCharacteristic;

    public BluetoothServer(@NonNull final Context context) {
        final BluetoothManager btManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
        final BluetoothAdapter btAdapter = btManager.getAdapter();

        this.gattServer = btManager.openGattServer(context.getApplicationContext(), this);

        this.mainService= new BluetoothGattService(MAIN_SERVICE, BluetoothGattService.SERVICE_TYPE_PRIMARY);


    this.requestCharacteristic = new BluetoothGattCharacteristic(CHARAC_REQUEST, BluetoothGattCharacteristic.PROPERTY_READ, BluetoothGattCharacteristic.PERMISSION_READ);
    this.recordingCharacteristic = new BluetoothGattCharacteristic(CHARAC_RECORDING, BluetoothGattCharacteristic.PROPERTY_READ, BluetoothGattCharacteristic.PERMISSION_READ);

        this.mainService.addCharacteristic(this.requestCharacteristic);
        this.mainService.addCharacteristic(this.recordingCharacteristic);

        this.gattServer.addService(this.mainService);

        final BluetoothLeAdvertiser advertiser = btAdapter.getBluetoothLeAdvertiser();
        btAdapter.setName("Test Wear");
        final AdvertiseSettings settings = new AdvertiseSettings.Builder()
                .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
                .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
                .setConnectable(false)
                .build();

        final ParcelUuid pUuid = new ParcelUuid(MAIN_SERVICE);
        final AdvertiseData data = new AdvertiseData.Builder()
                .setIncludeDeviceName(true)
                .addServiceUuid(pUuid)
                .build();

        final AdvertiseCallback advertisingCallback = new AdvertiseCallback() {
            @Override
            public final void onStartSuccess(final AdvertiseSettings settingsInEffect) {
                super.onStartSuccess(settingsInEffect);
                Log.i(TAG, "Started advertisement with success");
            }

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

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

    //[... the rest of the callbacks implementation ...]
}

I also tried using custom generated UUID from https://www.uuidgenerator.net/ but doing so is even worse : either I cannot advertise with name included or if I don't inclue the name, then BLE Scanner app won't pickup my custom service on all devices .

What am I doing wrong ?

Did you check onStartFailure() Method?

And one more thing, try not to add UUID in AdvertiseData, adding code here..!

public BluetoothServer(@NonNull final Context context) {
    final BluetoothManager btManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
    final BluetoothAdapter btAdapter = btManager.getAdapter();

   this.mainService= new BluetoothGattService(MAIN_SERVICE, BluetoothGattService.SERVICE_TYPE_PRIMARY);


this.requestCharacteristic = new BluetoothGattCharacteristic(CHARAC_REQUEST, BluetoothGattCharacteristic.PROPERTY_READ, BluetoothGattCharacteristic.PERMISSION_READ);
this.recordingCharacteristic = new BluetoothGattCharacteristic(CHARAC_RECORDING, BluetoothGattCharacteristic.PROPERTY_READ, BluetoothGattCharacteristic.PERMISSION_READ);

    this.mainService.addCharacteristic(this.requestCharacteristic);
    this.mainService.addCharacteristic(this.recordingCharacteristic);

    this.gattServer.addService(this.mainService);

    final BluetoothLeAdvertiser advertiser = btAdapter.getBluetoothLeAdvertiser();
    btAdapter.setName("Test Wear");
    final AdvertiseSettings settings = new AdvertiseSettings.Builder()
            .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
            .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH)
            .setConnectable(true) //Set it true
            .build();

    final ParcelUuid pUuid = new ParcelUuid(MAIN_SERVICE);
    final AdvertiseData data = new AdvertiseData.Builder()
            .setIncludeDeviceName(true)
    //Remove this line
            .addServiceUuid(pUuid)
            .build();

    final AdvertiseCallback advertisingCallback = new AdvertiseCallback() {
        @Override
        public final void onStartSuccess(final AdvertiseSettings settingsInEffect) {
            super.onStartSuccess(settingsInEffect);
            Log.i(TAG, "Started advertisement with success");
        }

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

   //Line 1 Changed
   this.gattServer = btManager.openGattServer(context.getApplicationContext(), this);

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM