Как пользоваться услугами UART в приложении BLE Android? - PullRequest
0 голосов
/ 17 марта 2019

Я разрабатываю приложение, которое подключается к micro: bit через Bluetooth LE и передает некоторую информацию. Я обработал соединение между приложением и micro: bit, но не могу отправить информацию. Когда я запускаю код ниже, я получаю вывод:

"connectFailure 2" (

Я не могу использовать отладку кстати: ((

Последняя функция в этом файле отправляет текст в микро: бит

Других java-файлов нет

public static UUID UART_UUID = UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
    public static UUID TX_UUID = UUID.fromString("6E400002-B5A3-F393-E0A9-E50E24DCCA9E");
    public static UUID RX_UUID = UUID.fromString("6E400003-B5A3-F393-E0A9-E50E24DCCA9E");
    // UUID for the BTLE client characteristic which is necessary for notifications.
    public static UUID CLIENT_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");

    // UI elements
    private TextView messages;
    private EditText input;

    // BTLE state
    private BluetoothAdapter adapter;
    private BluetoothGatt gatt;
    private BluetoothGattCharacteristic tx;
    private BluetoothGattCharacteristic rx;



    // Main BTLE device callback where much of the logic occurs.
    private BluetoothGattCallback callback = new BluetoothGattCallback() {
        // Called whenever the device connection state changes, i.e. from disconnected to connected.
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            if (newState == BluetoothGatt.STATE_CONNECTED) {
                writeLine("Connected!");
                // Discover services.
                if (!gatt.discoverServices()) {
                    writeLine("Failed to start discovering services!");
                }
            }
            else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
                writeLine("Disconnected!");
            }
            else {
                writeLine("Connection state changed.  New state: " + newState);
            }
        }

        // Called when services have been discovered on the remote device.
        // It seems to be necessary to wait for this discovery to occur before
        // manipulating any services or characteristics.
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                writeLine("Service discovery completed!");
            }
            else {
                writeLine("Service discovery failed with status: " + status);
                return;
            }
            // Save reference to each characteristic.
            tx = gatt.getService(UART_UUID).getCharacteristic(TX_UUID);
            rx = gatt.getService(UART_UUID).getCharacteristic(RX_UUID);
            // Setup notifications on RX characteristic changes (i.e. data received).
            // First call setCharacteristicNotification to enable notification.


            enableRXNotification();
            // Notify of connection completion.
//            notifyOnConnected(context);


//            if (!gatt.setCharacteristicNotification(rx, true)) {
//                writeLine("Couldn't set notifications for RX characteristic!");
//            }
//            // Next update the RX characteristic's client descriptor to enable notifications.
//            if (rx.getDescriptor(CLIENT_UUID) != null) {
//                BluetoothGattDescriptor desc = rx.getDescriptor(CLIENT_UUID);
//                desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
//                if (!gatt.writeDescriptor(desc)) {
//                    writeLine("Couldn't write RX client descriptor value!");
//                }
//            }
//            else {
//                writeLine("Couldn't get RX client descriptor!");
//            }
        }

        public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
            if (adapter != null || gatt != null) {
                if (gatt.setCharacteristicNotification(characteristic, enabled)) {
                    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_UUID);

                    if (descriptor != null) {
                        byte[] data = enabled ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
                        if (descriptor.setValue(data)) {
                            gatt.writeDescriptor(descriptor);
                        } else {
                            writeLine("connectFailure 1");
                            //connectFailure();
                        }
                    } else {
                        writeLine("connectFailure 2"); //THE ERROR I GET
                        //connectFailure();
                    }
                } else {
                    writeLine("connectFailure 3");
                    //connectFailure();
                }
            }
            return true;
        }

        public boolean enableRXNotification() {
            if (gatt == null){
                writeLine("gatt == null");
                return false;
            }

            BluetoothGattService SerialService = gatt.getService(UART_UUID);
            if (SerialService == null){
                writeLine("SerialService == null");
                return false;
            }

            BluetoothGattCharacteristic RxChar = SerialService.getCharacteristic(RX_UUID);
            if (RxChar == null) {
                writeLine("connectFailure 4");
                //connectFailure();
                return false;
            }

            if (!setCharacteristicNotification(RxChar, true)) {
                writeLine("connectFailure 5");
                //connectFailure();
                return false;
            }

            return true;
        }

        // Called when a remote characteristic changes (like the RX characteristic).
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            writeLine("Received: " + characteristic.getStringValue(0));
        }
    };

    // BTLE device scanning callback.
    private LeScanCallback scanCallback = new LeScanCallback() {
        // Called when a device is found.
        @Override
        public void onLeScan(BluetoothDevice bluetoothDevice, int i, byte[] bytes) {

//            writeLine("Found device: " + bluetoothDevice.getAddress());
//            // Check if the device has the UART service.
//            if (parseUUIDs(bytes).contains(UART_UUID)) {
//                // Found a device, stop the scan.
//                adapter.stopLeScan(scanCallback);
//                writeLine("Found UART service!");
//                // Connect to the device.
//                // Control flow will now go to the callback functions when BTLE events occur.
//                gatt = bluetoothDevice.connectGatt(getApplicationContext(), false, callback);
//            }



            writeLine("Found device: " + bluetoothDevice.getAddress());
            //Check if found device is micro:bit
            if (bluetoothDevice.getAddress().contains("DB") && bluetoothDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
                writeLine("DB, paired");
                // Found a device, stop the scan.
                adapter.stopLeScan(scanCallback);
                writeLine("Found micro:bit!");
                // Connect to the device.
                // Control flow will now go to the callback functions when BTLE events occur.
                gatt = bluetoothDevice.connectGatt(getApplicationContext(), false, callback);
            }
        }
    };

    // OnCreate, called once to initialize the activity.
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Grab references to UI elements.
        messages = (TextView) findViewById(R.id.messages);
        input = (EditText) findViewById(R.id.input);

        adapter = BluetoothAdapter.getDefaultAdapter();
    }

    // OnResume, called right before UI is displayed.  Start the BTLE connection.
    @Override
    protected void onResume() {
        super.onResume();
        // Scan for all BTLE devices.
        // The first one with the UART service will be chosen--see the code in the scanCallback.
        writeLine("Scanning for devices...");
        adapter.startLeScan(scanCallback);
    }

    // OnStop, called right before the activity loses foreground focus.  Close the BTLE connection.
    @Override
    protected void onStop() {
        super.onStop();
        if (gatt != null) {
            // For better reliability be careful to disconnect and close the connection.
            gatt.disconnect();
            gatt.close();
            gatt = null;
            tx = null;
            rx = null;
        }
    }

    // Handler for mouse click on the send button.
    public void sendClick(View view) {
        String message = input.getText().toString();
        if (tx == null || message == null || message.isEmpty()) {
            writeLine("tx == null || message == null");
            // Do nothing if there is no device or message to send.
            return;
        }
        // Update TX characteristic value.  Note the setValue overload that takes a byte array must be used.
        tx.setValue(message.getBytes(Charset.forName("UTF-8")));
        if (gatt.writeCharacteristic(tx)) {
            writeLine("Sent: " + message);
        }
        else {
            writeLine("Couldn't write TX characteristic!");
        }
    }
...