[英]How to read data from BLE device
所以,我一直在為這個 BLE 苦苦掙扎一段時間。 我正在開發一個 Appcelerator 模塊,該模塊可以啟用與 Android 平板電腦的某些設備的通信(讀/寫數據)。 我能夠掃描、發現設備、連接到它並發現它的服務。 我無法做的是讀取數據。 正如您在下面的代碼中看到的,方法 readData() 的內容總是返回 false。 (writeDescriptor、readCharacteristic、readDescriptor)。 無論如何,這總是返回 false。 回調永遠不會被調用,我完全被卡住了。 我到底做錯了什么? 如何將 readData() 上的這些內容設置為 true,之后該怎么做? 謝謝大家!
我已經多次檢查 stackOverflow 並嘗試了很多這里提出的解決方案,但似乎沒有任何效果。 據我了解,我的步驟是正確的。 少了點什么……就是不知道是什么……
public class AndroidbleModule extends KrollModule {
private BluetoothManager btManager;
private BluetoothAdapter btAdapter;
private BluetoothDevice btDevice;
private TiApplication appContext;
private Activity activity;
private BluetoothLeScanner btScanner;
public AndroidbleModule() {
super();
appContext = TiApplication.getInstance();
activity = appContext.getCurrentActivity();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_UUID);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
appContext.registerReceiver(new BlutoothStateChangedBroadcastReceiver(AndroidbleModule.this, btAdapter),
filter);
}
private BluetoothGatt bluetoothGatt;
private BluetoothGattCallbackHandler btGattHandler = new BluetoothGattCallbackHandler(AndroidbleModule.this);
@Kroll.method
public void connectToDevice(String device) {
if (bluetoothGatt != null) {
bluetoothGatt.disconnect();
}
for (String devName : btDevices.keySet()) {
if(device.equals(devName)) {
BluetoothDevice deviceAddress = btDevices.get(devName);
bluetoothGatt = deviceAddress.connectGatt(appContext, false, btGattHandler);
bluetoothGatt.connect();
bluetoothGatt.discoverServices();
deviceAddress.createBond();
deviceAddress.getBondState();
btDevice = deviceAddress;
}
}
}
BluetoothGattCharacteristic charac;
BluetoothGattDescriptor desc;
@Kroll.method
public void setNotifications() {
List<BluetoothGattService> btGattServicesList = bluetoothGatt.getServices();
List<BluetoothGattCharacteristic> btGattCharList = btGattServicesList.get(2).getCharacteristics();
List<BluetoothGattDescriptor> btDescList = btGattCharList.get(1).getDescriptors();
BluetoothGattCharacteristic characteristic = btGattCharList.get(1);
BluetoothGattDescriptor descriptor = btDescList.get(0);
bluetoothGatt.setCharacteristicNotification(characteristic, true);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
charac = characteristic;
desc = descriptor;
}
@Kroll.method
public void readData() {
bluetoothGatt.writeDescriptor(desc);
bluetoothGatt.readCharacteristic(charac);
bluetoothGatt.readDescriptor(desc);
}
private Set<String> devSet = new LinkedHashSet<String>();
HashMap<String, BluetoothDevice> btDevices = new HashMap<String, BluetoothDevice>();
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device;
device = result.getDevice();
KrollDict kd = new KrollDict();
kd.put("name", device.getName());
kd.put("address", device.getAddress());
System.out.println("Devices Found on Scan: " + kd.toString());
btDevice = device;
devSet.add(device.getName());
btDevices.put(device.getName(), device);
}
};
@Kroll.method
public void startScanning(@Kroll.argument(optional = true) int _scanmode) {
if (btAdapter != null) {
btScanner = btAdapter.getBluetoothLeScanner();
btScanner.startScan(scanCallback);
isScanning = true;
}
}
}
首先,我的 connectToDevice() 方法,其中提到的更改:
public void connectToDevice(String device) {
if (bluetoothGatt != null) {
bluetoothGatt.disconnect();
}
for (String devName : btDevices.keySet()) {
if(device.equals(devName)) {
BluetoothDevice deviceAddress = btDevices.get(devName);
bluetoothGatt = deviceAddress.connectGatt(appContext, false, btGattHandler);
btDevice = deviceAddress;
}
}
}
onConnectionStateChanged() 回調方法:
public void onConnectionStateChange(final BluetoothGatt gatt,
final int status, final int newState) {
gatt.getDevice().createBond();
KrollDict kd = new KrollDict();
kd.put("newState", newState);
kd.put("status", status);
if (proxy.hasListeners("didConnectionStateChange")) {
proxy.fireEvent("didConnectionStateChange", kd);
}
gatt.discoverServices();
}
onServicesDiscovered() 回調方法:
public void onServicesDiscovered(final BluetoothGatt gatt, final int status) {
BluetoothDevice device = gatt.getDevice();
KrollDict kdServices = new KrollDict();
KrollDict kdCharacteristics = new KrollDict();
List<BluetoothGattService> services = gatt.getServices();
kdServices.put("device", device.getAddress());
kdCharacteristics.put("device", device.getAddress());
Log.i(LCAT, device.getAddress() + " services count: " + services.size());
ArrayList<Object> listServices = new ArrayList<>();
HashMap<String, Object> hashChar = new HashMap<String, Object>();
for (BluetoothGattService service : services) {
Log.i(LCAT,
"Service: " + service.getType() + " " + service.getUuid());
HashMap<String, Object> listService = new HashMap<String, Object>();
listService.put("serviceType", service.getType());
listService.put("serviceUuid", service.getUuid());
listServices.add(listService);
ArrayList<HashMap<String, Object>> listChars = new ArrayList<HashMap<String, Object>>();
List<BluetoothGattCharacteristic> characteristics = service
.getCharacteristics();
for (BluetoothGattCharacteristic btc : characteristics) {
Log.i(LCAT, "uuid: " + btc.getUuid());
HashMap<String, Object> listChar = new HashMap<String, Object>();
listChar.put("uuid", btc.getUuid());
listChar.put("value", btc.getValue());
listChars.add(listChar);
// TODO not needed at the moment
byte[] data = btc.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new
StringBuilder(data.length);
for (byte byteChar : data) {
stringBuilder.append(String.format("%02X ", byteChar));
}
Log.i(LCAT, "String val: " + btc.getUuid() + " " +
btc.getValue() + " " + stringBuilder.toString());
}
gatt.readCharacteristic(btc);
}
hashChar.put("serviceUuid", service.getUuid());
hashChar.put("chars", listChars);
}
if (proxy.hasListeners("didDiscoverServices"))
proxy.fireEvent("didDiscoverServices", kdServices);
if (proxy.hasListeners("didDiscoverCharacteristicsForService"))
proxy.fireEvent("didDiscoverCharacteristicsForService",
kdCharacteristics);
System.out.println("Services successfully discovered!");
}
setNotifications() 我沒有動過,正如你所看到的,它對所有東西都返回 true。 現在,當我調用 readData()(只剩下一個 gatt 調用,即 writeCharacteristic())時,它返回 false,如日志的最后一行所示。 一探究竟。
日志:
I/System.out: connectToDevice() called!
I/System.out: Device successfully connected!
BluetoothDevice: createBond() for device FA:45:B9:7C:86:7C called by pid: 6194 tid: 6207
BLE: (Binder:6194_2) [19078,19078] FA:45:B9:7C:86:7C services count: 3
BLE: (Binder:6194_2) [1,19079] Service: 0 00001800-0000-1000-8000-00805f9b34fb
BLE: (Binder:6194_2) [0,19079] uuid: 00002a00-0000-1000-8000-00805f9b34fb
BLE: (Binder:6194_2) [1,19080] uuid: 00002a01-0000-1000-8000-00805f9b34fb
BLE: (Binder:6194_2) [0,19080] uuid: 00002a04-0000-1000-8000-00805f9b34fb
BLE: (Binder:6194_2) [1,19081] uuid: 00002aa6-0000-1000-8000-00805f9b34fb
BLE: (Binder:6194_2) [0,19081] Service: 0 00001801-0000-1000-8000-00805f9b34fb
BLE: (Binder:6194_2) [0,19081] Service: 0 6e400001-b5a3-f393-e0a9-e50e24dcca9e
BLE: (Binder:6194_2) [0,19081] uuid: 6e400002-b5a3-f393-e0a9-e50e24dcca9e
BLE: (Binder:6194_2) [0,19081] uuid: 6e400003-b5a3-f393-e0a9-e50e24dcca9e
I/System.out: Services successfully discovered!
I/System.out: btGattServicesList - [android.bluetooth.BluetoothGattService@c893553, android.bluetooth.BluetoothGattService@5dd2e90, android.bluetooth.BluetoothGattService@6bce389]
I/System.out: btGattCharList - [android.bluetooth.BluetoothGattCharacteristic@b6cf8e, android.bluetooth.BluetoothGattCharacteristic@6e7d3af]
I/System.out: btDescList - [android.bluetooth.BluetoothGattDescriptor@b8ea3bc]
I/System.out: setCharacteristicNotification = true
I/System.out: Enable Notification Value = true
I/System.out: characteristic.addDescriptor(descriptor) = true
I/System.out: bluetoothGatt.writeCharacteristic(charac) false
這里到底缺少什么或出了什么問題?
所以,在浪費了很多時間之后,我想通了。 setNotifications 只是第一步。 我們必須告訴設備開始流式傳輸數據,以便應用程序可以收集它。 它是通過 bluetoothGatt.writeCharacteristic(characteristic) 完成的,當然,在我們正確設置文字之后。 完成此操作后,字節就會不斷出現! =)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.