Итак, я разрабатываю Android-модуль Java BLE с использованием Eclipse (для кодирования модуля и Appcelerator (для создания приложения для Android). Я пытаюсь получить данные с устройства BLE и показать их на телефоне Android. Я могу сканировать устройство и подключитесь к нему.
Но я действительно, действительно не могу получить от него никаких данных. Я пробовал по крайней мере 10 различных вещей, но... Основная проблема в том, что я не очень хорошо знаю BLE API и немного новичок в Java. Может ли кто-нибудь помочь бедняге действительно прочитать данные с устройства?
Основная проблема заключается в настройке UUID характеристики Bluetooth (который у меня есть). Я просто не знаю, как это сделать... Ниже приведены коды модуля...
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");
}
}
Я ожидаю, что какая-нибудь добрая душа отправится на Небеса, чтобы сжалиться надо мной и помочь мне получить эти сладкие байты данных.
Прежде всего, прочитайте файл обзор блютуз. Проверьте, добавлены ли в проект разрешения bluetooth.
Одна вещь, которая здесь неверна, заключается в том, что isConnected=true
установлен слишком рано, потому что вы можете считать, что вы подключены после того, как сервисы ble были обнаружены и (status == BluetoothGatt.GATT_SUCCESS)
. В противном случае вы не сможете читать и записывать характеристики.
Хорошей отправной точкой может быть это репо от Google. Это старый проект, и я не уверен, что вам нужно обновить какую-то зависимость, чтобы он скомпилировался, но ничего важного.
Установить соединение и начать чтение байтов легко, но если вы хотите установить надежное соединение с устройством ble, из-за фрагментации Android и производителей, которые не следуют спецификациям Bluetooth, может быть очень сложно, почти невозможно сделать Bluetooth низким. энергия, которая работает идеально для всех устройств.
Как только вы начали читать несколько байтов, я предлагаю это видео изучить некоторые важные приемы. Если хотите углубиться, внимательно прочитайте этот фантастический ресурс о ble.
Как только вы начнете отчаиваться с ble, возможно, это будет хороший момент, чтобы прочитать этот список известных проблем
Наконец, вы обнаружите, что лучшее, что вы можете сделать с низким энергопотреблением в Android, — это использовать библиотеки с открытым исходным кодом, такие как Северная полупроводниковая библиотека ble или RxAndroid Бле.
Но прежде чем использовать библиотеку ble, рекомендуется понять, что делает библиотека, и понять, зачем она вам нужна.
Обновлено: я никогда не использовал appcelerator, но здесь у вас есть блютуз модуль для титана appcelerator.
Попробуйте проверить характеристики с помощью НрфкКоннект. С помощью этого инструмента вы сможете подключить свое устройство и проверить характеристики и услуги с устройства ble.
У вас неправильный UUID для дескриптора конфигурации характеристик клиента. Это должно быть 00002902-0000-1000-8000-00805f9b34fb, но вы написали 6E400002-B5A3-F393-E0A9-E50E24DCCA9E.
Одной из вещей, которых не хватает в вашем коде, является установка уведомлений, чтобы центральный сервер мог прослушивать ответ периферийного устройства. Попробуйте что-то вроде этого:
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);
}
После этого вы можете отправлять команды на устройство и слышать его ответ.
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);
}
Спасибо за ответ. Я прочитал то, что вы указали, скачал предложенный вами модуль, но я действительно не могу заставить его работать. Мне не хватает чего-то, чего я просто не знаю. Вы правы, isConnected слишком рано, и я не подключаюсь должным образом к устройству. Я снова попробовал еще одну кучу вещей, но в итоге получил в основном тот же код, что и выше... Похоже на бег по кругу.