简体   繁体   English

如何从 BLE 设备接收数据?

[英]How can I receive data from a BLE Device?

So, I am developing a Java BLE Android Module using Eclipse (to code the module and Appcelerator (to make the Android App). I am trying to receive data from a BLE Device and show it on an Android Phone. I can scan the device and connect to it.因此,我正在使用 Eclipse 开发 Java BLE Android 模块(对模块和 Appcelerator 进行编码(以制作 Android 应用程序)。我正在尝试从 BLE 设备接收数据并将其显示在 Android 手机上。我可以扫描设备并连接到它。

But I really, really can't receive any data from it.但我真的,真的无法从中接收任何数据。 I have tried at least 10 different stuff but... The main problem is that I don't know the BLE API very well, and I am a little noobie in Java.我已经尝试了至少 10 种不同的东西,但是......主要问题是我不太了解 BLE API,而且我在 Java 方面有点菜鸟。 Can anyone please help a poor soul to actually read the data from the device?任何人都可以帮助一个可怜的人真正从设备中读取数据吗?

The main problem is setting the Bluetooth Characteristic UUID (which I have).主要问题是设置蓝牙特性 UUID(我有)。 I just don't know how to do it... Bellow are the codes for the Module...我只是不知道该怎么做……下面是模块的代码……

public class AndroidbleModule extends KrollModule {
    
  public static final String LCAT = "BLE";
  private BluetoothManager btManager;
  private BluetoothAdapter btAdapter;
  private BluetoothDevice btDevice;
  private TiApplication appContext;
  private Activity activity;
  private KrollFunction onFound;
  private KrollFunction onConnections;
  private BluetoothLeScanner btScanner;
  private UUID uuid;

  BluetoothGatt bluetoothGatt;
  BluetoothGattCharacteristic btChar;
  BluetoothGattCallbackHandler btData;
  KrollDict kd;
  Boolean isConnected = false;
  BluetoothGatt connectedGatt;
        
  private ScanCallback scanCallback = new ScanCallback() {
  @Override
  public void onScanResult(int callbackType, ScanResult result) {

  BluetoothDevice device = result.getDevice();
    if (device != null) {
    BluetoothDeviceProxy btDeviceProxy = new 
  BluetoothDeviceProxy(device);
    if (device.getName() != null) {
      Log.d(LCAT, "Found: " + device.getName() + " " + 
  device.getAddress());  
    ArrayList<String> ids = new ArrayList<String>();    
    if (device.getUuids() != null) {
             for (ParcelUuid id1 : device.getUuids()) {
    ids.add(id1.toString());
    }
    }
    btDevice = device;
    kd = new KrollDict();
    kd.put("name", btDevice.getName());
    kd.put("macaddress", btDevice.getAddress());
    fireEvent("nb_DevicesFound", kd); 
                     
    btScanner.stopScan(scanCallback);
      }
     }
    }
  };
    
  @Kroll.method
  public boolean connect()
  {
   try {
    bluetoothGatt = btDevice.connectGatt(appContext, true,
    new BluetoothGattCallbackHandler(AndroidbleModule.this));
    if (bluetoothGatt != null) {
    System.out.println("*****     *****     Connected to: =====>>>>>    " + btDevice.getAddress() + " " + btDevice.getName());
    this.fireEvent("nb_onConnect",null);
    isConnected = true;
    bluetoothGatt = connectedGatt;
        }
  } catch (Exception e) {
    isConnected = false;
    this.fireEvent("nb_NoConnection", null);
    }
   return true;
  };
    
  @Kroll.method
  public void readData() 
  {
  System.out.println("WHAT THE HELL DO I DO????");
  }

}

public final class BluetoothGattCallbackHandler extends 
  BluetoothGattCallback {

private static final String LCAT = AndroidbleModule.LCAT;
private KrollProxy proxy;
private static final String UUID_SERVICE_TS002004 = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E";
private static final String UUID_CHARACTERISTIC_WRITE_TS002004 = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E";
private static final String UUID_CHARACTERISTIC_NOTIFY_TS002004 = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E";
BluetoothGattCharacteristic btCharacteristic;

public BluetoothGattCallbackHandler(KrollProxy proxy) {
    super();
    this.proxy = proxy;
  }

  @Override
  public void onConnectionStateChange(final BluetoothGatt gatt,
    final int status, final int newState) {
    KrollDict kd = new KrollDict();
    kd.put("newState", newState);
    kd.put("status", status);
    if (proxy.hasListeners("didConnectionStateChange")) {
        proxy.fireEvent("didConnectionStateChange", kd);
    }
    gatt.discoverServices();
    }

  @Override
  public void onServicesDiscovered(BluetoothGatt gatt, int status) {
       super.onServicesDiscovered(gatt, status);
       Log.i(LCAT,"onServicesDiscovered");
       if (status != BluetoothGatt.GATT_SUCCESS) return;
       btCharacteristic = 
gatt.getService(UUID.fromString(UUID_SERVICE_TS002004)).getCharacteristic(UUID.fromString(UUID_CHARACTERISTIC_NOTIFY_TS002004));
       gatt.setCharacteristicNotification(btCharacteristic,true);

       BluetoothGattDescriptor descriptor = btCharacteristic.getDescriptor(UUID.fromString(UUID_CHARACTERISTIC_WRITE_TS002004));
        
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
       gatt.writeDescriptor(descriptor);
  }

  @Override
  public void onCharacteristicChanged(BluetoothGatt gatt,
    final BluetoothGattCharacteristic characteristic) {
    byte[] data = characteristic.getValue();
    Log.i(LCAT, "Char changed " + data.toString());
    for (BluetoothGattDescriptor descriptor : 
 characteristic.getDescriptors()) {
 descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
    }
  }
    
  @Override
  public void onCharacteristicRead(BluetoothGatt gatt, 
  BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicRead(gatt, characteristic, status);
        Log.i(LCAT,"onCharacteristicRead");
    }
    
  @Override
  public void onDescriptorRead(BluetoothGatt gatt, 
  BluetoothGattDescriptor descriptor, int status) {
       super.onDescriptorRead(gatt, descriptor, status);
       Log.i(LCAT,"onDescriptorRead");
  }
}

I expect to some good soul that will go to Heaven to have mercy on me and help me get those sweet bytes of data.我希望有一些善良的灵魂会去天堂怜悯我并帮助我获得那些甜蜜的数据。

One of the things that is missing in your code, is to Set Notifications, so the Central can listen to the Peripheral's response.您的代码中缺少的一件事是设置通知,以便 Central 可以收听 Peripheral 的响应。 Try something like this:尝试这样的事情:

public void setNotifications() {
    BluetoothGattService service = bluetoothGatt.getService(SERVICE_UUID);
    BluetoothGattCharacteristic characteristic = service.getCharacteristic(CHARACTERISTIC_UUID);

    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(DESCRIPTOR_UUID);
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
    characteristic.addDescriptor(descriptor);
    characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
    bluetoothGatt.writeDescriptor(descriptor);

    bluetoothGatt.setCharacteristicNotification(characteristic, true);
}

After that, you can send commands to the device and hear it's return.之后,您可以向设备发送命令并听到它的返回。

public void returnData(String data) {
    BluetoothGattService service = bluetoothGatt.getService(SERVICE_UUID);
    BluetoothGattCharacteristic characteristic = service.getCharacteristic(CHARACTERISTIC_UUID);
    String dataString = data;
    dataString.getBytes();
    writeCharacteristic.setValue(dataString);
    writeCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
    bluetoothGatt.writeCharacteristic(writeCharacteristic);
}

First of all, read the bluetooth overview .首先,阅读蓝牙概述 Check if bluetooth permissions have been added to the project.检查蓝牙权限是否已添加到项目中。

One thing that is wrong here is that isConnected=true is set too early, because you can consider that you are connected after ble services has been discovered and (status == BluetoothGatt.GATT_SUCCESS) .这里错误的一件事是isConnected=true设置得太早,因为您可以认为您是在发现 ble 服务和(status == BluetoothGatt.GATT_SUCCESS) Otherwise, you can't read and write characteristics.否则无法读写特性。

A good starting point can be this repo from google.一个很好的起点可以是来自谷歌的这个 repo It is old project and I'm not sure if you have to update some dependency to make it compile, but nothing important.这是旧项目,我不确定您是否必须更新某些依赖项以使其编译,但没有什么重要的。

Establish a connection and start reading bytes is easy, but if you want establish a reliable connection with ble device, due to android fragmentation and manufacturerers that don't follow the bluetooth specs, it can be super difficult, almost imposible to make a bluetooth low energy that works perfect for all devices.建立连接并开始读取字节很容易,但是如果您想与 ble 设备建立可靠的连接,由于 android 碎片化和不遵循蓝牙规范的制造商,这可能非常困难,几乎不可能使蓝牙低适用于所有设备的能量。

Once you have started to read some bytes, I suggest this video to learn some important tricks about.一旦你开始阅读一些字节,我建议你通过这个视频来学习一些重要的技巧。 If you want go deeper, read carefully this fantastic resource about ble .如果你想更深入,请仔细阅读这个关于 ble 的奇妙资源

Once you start to get desperate with ble, probably it will be a good moment to read this list of known issues一旦您开始对 ble 感到绝望,可能是阅读此已知问题列表的好时机

Finally, you will discover that the best thing that you can do with ble low energy in android is use open source libraries like the Nordic semiconductor ble library or RxAndroid Ble .最后,您会发现在 android 中使用 ble low energy 可以做的最好的事情是使用开源库,如Nordic Semiconductor ble 库RxAndroid Ble

But before use a ble library, it is a good practice understand what is doing the library and understand why you need it.但是在使用 ble 库之前,最好先了解该库在做什么,并了解您为什么需要它。

EDIT: I have never used appcelerator, but here you have a bluetooth module for appcelerator titanium.编辑:我从未使用过 appcelerator,但这里有一个用于 appcelerator 钛的蓝牙模块

You have the wrong uuid for the Client Characteristic Configuration Descriptor.客户端特征配置描述符的 uuid 错误。 It should be 00002902-0000-1000-8000-00805f9b34fb but you have written 6E400002-B5A3-F393-E0A9-E50E24DCCA9E.它应该是 00002902-0000-1000-8000-00805f9b34fb 但你写的是 6E400002-B5A3-F393-E0A9-E50E24DCCA9E。

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

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