簡體   English   中英

如何從 BLE 設備讀取數據

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM