【问题标题】:How to send data over a Bluetooth Low Energy (BLE) link?如何通过蓝牙低功耗 (BLE) 链路发送数据?
【发布时间】:2014-06-17 01:32:39
【问题描述】:

我能够发现,连接到蓝牙。

源代码---

通过蓝牙连接到远程设备:

//Get the device by its serial number
 bdDevice = mBluetoothAdapter.getRemoteDevice(blackBox);

 //for ble connection
 bdDevice.connectGatt(getApplicationContext(), true, mGattCallback);

Gatt 状态回调:

 private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
    //Connection established
    if (status == BluetoothGatt.GATT_SUCCESS
        && newState == BluetoothProfile.STATE_CONNECTED) {

        //Discover services
        gatt.discoverServices();

    } else if (status == BluetoothGatt.GATT_SUCCESS
        && newState == BluetoothProfile.STATE_DISCONNECTED) {

        //Handle a disconnect event

    }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {

    //Now we can start reading/writing characteristics

    }
};

现在我想向远程 BLE 设备发送命令,但不知道该怎么做。

一旦命令发送到 BLE 设备,BLE 设备将通过广播进行响应 我的应用程序可以接收的数据。

【问题讨论】:

  • 我对 Android 不熟悉,对 iOS 更熟悉,我使用的是 BLE。但是你不能只写特征(如果允许的话)。所以你需要发现特征。逻辑是这样的:Peripheral -> Service(s) -> Characteristic(s)。
  • @Larme:这是否意味着苹果确实允许按照蓝牙规范中指定的 gatt 写入 - 特别是自定义 gatt 配置文件?您在没有 MFI 会员资格的情况下与 corebluetooth 进行 2 路通信成功了吗?
  • @andreas-manusm:是的,你可以。
  • 我有类似的疑问,谁能看到链接并回复stackoverflow.com/questions/38935479/…

标签: android bluetooth-lowenergy android-bluetooth gatt


【解决方案1】:

当您连接到 BLE 设备并发现服务时,您需要将此过程分解为几个步骤:

  1. onServicesDiscovered 中为您的callback 显示gattServices

  2. 检查是否可以编写特征
    检查BluetoothGattCharacteristic PROPERTIES -我没有意识到需要在BLE硬件上启用PROPERTY_WRITE,这浪费了很多时间。

  3. 当你编写一个特性时,硬件是否会执行任何动作来明确指示操作(在我的例子中,我正在点亮一个 LED)

假设mWriteCharacteristicBluetoothGattCharacteristic 检查属性的部分应该是这样的:

if (((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) |
     (charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) > 0) {
 // writing characteristic functions
 mWriteCharacteristic = characteristic;
  }

并且,写下你的特点:

// "str" is the string or character you want to write
byte[] strBytes = str.getBytes();
byte[] bytes = activity.mWriteCharacteristic.getValue();  
YourActivity.this.mWriteCharacteristic.setValue(bytes);
YourActivity.this.writeCharacteristic(YourActivity.this.mWriteCharacteristic);  

这些是您需要精确实现的代码中有用的部分。

请参阅 this github project 以获取仅包含基本演示的实现。

【讨论】:

  • 谢谢。我已经找到了BluetoothLeGatt github 源代码,并实现了其中的大部分功能,包括扫描和连接。现在将寻找Light_BLE 以匹配更改并进行更好的开发。
  • 还想知道我的远程 BLE 将接受诸如“开始”之类的命令来开始广播,以及“停止”来停止从 BLE 到客户端的广播。那么这些命令就是你在代码中所说的特性?
  • 是的,您还需要对 BLE 进行编程,开始和停止可以是“1”和“2”值或您从客户端写入的任何其他值,这将涉及 if- else 在 BLE 硬件编程端循环
  • charaProp 是什么变量?
  • YourActivity.this.mWriteCharacteristic.setValue(strBytes);
【解决方案2】:

一个让 Android 与 LED 灯交互的友好指南。

第 1 步。 获取一个工具来扫描您的 BLE 设备。我在 Win10 上使用了“蓝牙 LE 实验室”,但这个也可以:https://play.google.com/store/apps/details?id=com.macdom.ble.blescanner

第 2 步。 通过输入数据分析BLE设备的行为,我建议输入十六进制值。

第 3 步。 获取 Android 文档的示例。 https://github.com/googlesamples/android-BluetoothLeGatt

第 4 步。 修改你在SampleGattAttributes中找到的UUID

我的配置:

    public static String CUSTOM_SERVICE = "0000ffe5-0000-1000-8000-00805f9b34fb";
    public static String CLIENT_CHARACTERISTIC_CONFIG = "0000ffe9-0000-1000-8000-00805f9b34fb";

    private static HashMap<String, String> attributes = new HashMap();

    static {
        attributes.put(CUSTOM_SERVICE, CLIENT_CHARACTERISTIC_CONFIG);
        attributes.put(CLIENT_CHARACTERISTIC_CONFIG, "LED");
    }

第 5 步。 在 BluetoothService.java 中修改onServicesDiscovered:

@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {

        for (BluetoothGattService gattService : gatt.getServices()) {
            Log.i(TAG, "onServicesDiscovered: ---------------------");
            Log.i(TAG, "onServicesDiscovered: service=" + gattService.getUuid());
            for (BluetoothGattCharacteristic characteristic : gattService.getCharacteristics()) {
                Log.i(TAG, "onServicesDiscovered: characteristic=" + characteristic.getUuid());

                if (characteristic.getUuid().toString().equals("0000ffe9-0000-1000-8000-00805f9b34fb")) {

                    Log.w(TAG, "onServicesDiscovered: found LED");

                    String originalString = "560D0F0600F0AA";

                    byte[] b = hexStringToByteArray(originalString);

                    characteristic.setValue(b); // call this BEFORE(!) you 'write' any stuff to the server
                    mBluetoothGatt.writeCharacteristic(characteristic);

                    Log.i(TAG, "onServicesDiscovered: , write bytes?! " + Utils.byteToHexStr(b));
                }
            }
        }

        broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
    } else {
        Log.w(TAG, "onServicesDiscovered received: " + status);
    }
}

使用此函数转换字节字符串:

public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
    data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
            + Character.digit(s.charAt(i + 1), 16));
}
return data;
}

PS:上面的代码离生产还很远,但我希望它对那些不熟悉 BLE 的人有所帮助。

【讨论】:

  • characteristic.getUuid().toString().equals("0000ffe9-0000-1000-8000-00805f9b34fb") 是硬编码的,但我怀疑如果您将 BT 模块更改为另一个,这字符串将是另一个不同的。也许一些比较来检查该特性是否具有写入属性会更好
猜你喜欢
  • 2015-05-05
  • 2016-06-14
  • 2023-03-26
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
  • 2013-01-12
  • 2017-07-07
相关资源
最近更新 更多