简体   繁体   English

从未发现BLE服务

[英]BLE Services never discovered

I want to send a message to a BLE device. 我想向BLE设备发送消息。 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. 现在,无论何时我想连接到该设备并向其发送消息,尽管可以识别该设备,但从不调用onServiceDiscovered方法,因为我可以获取该设备的名称。 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. 您需要从GATT回调的onConnectionStateChange方法中调用discoverServices Documentation of the discoverServices method: discoverServices方法的文档:

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. 服务发现完成后,将onServicesDiscovered(BluetoothGatt, int)回调。 If the discovery was successful, the remote services can be retrieved using the getServices() function. 如果发现成功,则可以使用getServices()函数检索远程服务。

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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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