所以,我一直在努力使用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;
}
}
}
答案 0 :(得分:0)
首先,我的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
这里到底是什么东西失踪或出问题了?
答案 1 :(得分:0)
因此,在浪费大量时间后,我想出了办法。 setNotifications只是第一步。我们必须告诉设备开始流数据,以便App可以收集数据。这是通过bluetoothGatt.writeCharacteristic(characteristic)完成的 当然,在我们适当地设定了作品之后。 完成此操作后,字节就一直存在! =)