Android 如何通过低功耗蓝牙 (BLE) 链接发送数据?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23393010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:05:32  来源:igfitidea点击:

How to send data over a Bluetooth Low Energy (BLE) link?

androidbluetooth-lowenergyandroid-bluetoothgatt

提问by My God

I am able to discover, connect to bluetooth.

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

Source Code---

源代码 - -

Connect via bluetooth to Remote Device:

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

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

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

Gatt CallBack for Status:

状态的 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

    }
};

Now I want to send commands to Remote BLE device but don't know how to do that.

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

Once the command is sent to the BLE device, the BLE device will respond by broadcasting data which my application can receive.

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

采纳答案by Pararth

You need to break this process into a few steps, when you connect to a BLE device and discover Services:

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

  1. Display available gattServicesin onServicesDiscoveredfor your callback

  2. To check whether you can write a characteristic or not
    check for BluetoothGattCharacteristic PROPERTIES-I didn't realize that need to enable the PROPERTY_WRITE on the BLE hardware and that wasted a lot of time.

  3. When you write a characteristic, does the hardware perform any action to explicitly indicate the operation (in my case i was lighting an led)

  1. 可显示gattServicesonServicesDiscovered您的callback

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

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

Suppose mWriteCharacteristicis a BluetoothGattCharacteristicThe part where to check the PROPERTY should be like:

假设mWriteCharacteristic是一个BluetoothGattCharacteristic检查属性的部分应该是这样的:

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

And, to write your 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);  

Those are the useful parts of the code that you need to implement precisely.

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

Refer this github projectfor an implementation with just a basic demo.

请参阅此 github 项目以获取仅包含基本演示的实现。

回答by Martin Pfeffer

A noob-friendly guide to make Android interact with a LED-lamp.

让 Android 与 LED 灯交互的新手友好指南。

Step 1. Get an tool to scan your BLE device. I used "Bluetooth LE Lab" for Win10, but this one will do it as well: https://play.google.com/store/apps/details?id=com.macdom.ble.blescanner

步骤 1. 获取扫描 BLE 设备的工具。我为 Win10 使用了“Bluetooth LE Lab”,但这个也可以:https: //play.google.com/store/apps/details?id=com.macdom.ble.blescanner

Step 2. Analyse the behavior of the BLE device by entering data, I recommend to enter hex values.

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

Step 3. Get the sample of the Android docs. https://github.com/googlesamples/android-BluetoothLeGatt

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

Step 4. Modify the UUIDs you find in SampleGattAttributes

步骤 4. 修改您在其中找到的 UUID SampleGattAttributes

My config:

我的配置:

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

enter image description here

在此处输入图片说明

Step 5. In BluetoothService.java modify onServicesDiscovered:

步骤 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);
    }
}

Convert the byte-String using this function:

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

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: The above code is far away from production, but I hope it helps those, who are new to BLE.

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