【问题标题】:BLE Services never discoveredBLE 服务从未被发现
【发布时间】:2017-09-05 12:39:18
【问题描述】:

我想向 BLE 设备发送消息。据我了解,首先必须发现设备服务,然后将消息发送到服务特征。所以这就是我所做的:

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

}

这是我要发送消息的代码:

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

现在,每当我想连接到设备并向其发送消息时,尽管设备已被识别,但永远不会调用 onServiceDiscovered 方法,因为我可以获得设备的名称。也不会抛出错误。

为什么从不调用这个方法?难道我做错了什么? 我已经检查了权限,并将该类作为服务添加到清单中。

感谢您的帮助...

【问题讨论】:

    标签: android bluetooth-lowenergy


    【解决方案1】:

    您需要在 GATT 回调的 onConnectionStateChange 方法中调用 discoverServicesdiscoverServices 方法的文档:

    发现远程设备提供的服务及其 特征和描述符。

    这是一个异步操作。一旦服务发现 完成后,onServicesDiscovered(BluetoothGatt, int) 回调为 触发。如果发现成功,远程服务可以 使用getServices() 函数检索。

    在您的情况下,如下更新您的代码应该可以解决问题:

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

    【讨论】:

    • 我刚试过;但是当我在onConnectionStateChange中调用它时,这个方法永远不会被调用,但是在connectGatt之后我仍然得到了deviceName;我更新了代码
    • 您是否确认连接状态恢复为STATE_CONNECTED
    • 永远不会调用 onConnectionStateChange;所以没有要检查的连接状态。
    • 好吧对不起我的错;我忘了调用 connect mBG.connect();现在连接状态 0 回来了,但没有成功
    • 如果连接失败,则可能是您尝试连接的设备无法访问,但这超出了本问题的范围。
    猜你喜欢
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 2023-03-17
    • 2015-08-19
    相关资源
    最近更新 更多