简体   繁体   中英

BLE Services never discovered

I want to send a message to a BLE device. In my understanding one first has to discover the devices services and then send the message to a service characteristic. So here is what I did:

public class BluetoothLeService extends Service {

private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private BluetoothGatt mBluetoothGatt;

private String macAddress;
private String serviceUuid;
private String characteristicUuid;
private Application app;
private int transmissionValue = 450;     

public BluetoothLeService(String address, String serviceUuid, String characteristicUuid) {
    this.macAddress = address;
    this.serviceUuid = serviceUuid;
    this.characteristicUuid = characteristicUuid;
}


private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        System.out.println("connectionStateChange: " + status);
        if (STATE_CONNECTED == newState) {
            gatt.discoverServices();
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if(gatt.getDevice().getName().equals("MyDeviceName")) {
            sendMessageAfterDiscovery(gatt);
        }
    }

};

public boolean initialize(Application app) {
    this.app = app;
    if (mBluetoothManager == null) {
        mBluetoothManager = (BluetoothManager) app.getSystemService(Context.BLUETOOTH_SERVICE);
        if (mBluetoothManager == null) {
            return false;
        }
    }

    mBluetoothAdapter = mBluetoothManager.getAdapter();
    if (mBluetoothAdapter == null) {
        return false;
    }
    return true;
}


public boolean connect() {
    return connect(macAddress);
}

public boolean connect(final String address) {
    this.macAddress = address;
    if (mBluetoothAdapter == null || macAddress == null) {
        return false;
    }

    final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);
    if (device == null) {
        Log.w(TAG, "Device not found.  Unable to connect.");
        return false;
    }
    mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
    return true;
}

public void writeCharacteristic(int value) {
    this.transmissionValue = value;
    BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice(this.macAddress);
    BluetoothGatt mBG = mDevice.connectGatt(app.getApplicationContext(), true, mGattCallback);
    System.out.println("device name: " + mBG.getDevice().getName());

}

private void sendMessageAfterDiscovery(BluetoothGatt gatt) {
    BluetoothGattService mSVC = gatt.getService(UUID.fromString(serviceUuid));

    BluetoothGattCharacteristic mCH = mSVC.getCharacteristic(UUID.fromString(characteristicUuid));
    mCH.setValue(transmissionValue, BluetoothGattCharacteristic.FORMAT_UINT16, 0);
    System.out.println("characteristic writable: " + isCharacteristicWriteable(mCH));

    System.out.println("success? " + gatt.writeCharacteristic(mCH));
}

public static boolean isCharacteristicWriteable(BluetoothGattCharacteristic pChar) {
    return (pChar.getProperties() & (BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) != 0;
}

}

And here is the code where I want to send the message:

private void sendMessage() {
    BluetoothLeService ble = new BluetoothLeService("B0:00:00:00:00:C0", "0000fff0-1111-0000-0000-00805f9b34fb","0000fff1-1111-0000-0000-00805f9b34fb");
    ble.initialize(app);
    ble.connect();,
    ble.writeCharacteristic(450)
 }

Now whenever I want to connect to the device and send a message to it, the onServiceDiscovered method is never called although the device is recognized because I can get the name of the device. Also no error is thrown.

Why is this method never called? Am I doing something wrong? I already checked the permissions and I added the class as a Service in the manifest.

Thanks for your help...

You need to call discoverServices from within the onConnectionStateChange method of your GATT callback. Documentation of the discoverServices method:

Discovers services offered by a remote device as well as their characteristics and descriptors.

This is an asynchronous operation. Once service discovery is completed, the onServicesDiscovered(BluetoothGatt, int) callback is triggered. If the discovery was successful, the remote services can be retrieved using the getServices() function.

In your case, updating your code as follows should do the trick:

@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
    System.out.println("connectionStateChange: " + status);

    if (STATE_CONNECTED == newState) {
        gatt.discoverServices();
    }
}

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