Android Bluetooth 4.0BLE Communication Read-Write Data Update

Project Requirements: app communicates with Bluetooth, and receives messages sent by hardware keys via Bluetooth. app does the corresponding operation, which is similar to Bluetooth headset listening and hanging up.
Less contact before Bluetooth development, classic Bluetooth development has been done android bt , BLE does little, so I don't know much about it all the time. Recently, BLE Bluetooth has been used in the project again. So, under the simple collation of some code of the project, mainly Bluetooth connection, read and write data, Bluetooth message monitoring.Bluetooth search code I don't write here, you can own Baidu.
In order to monitor that app and Bluetooth are connected all the time and that the connection is working properly, the code uses writing data all the way to Bluetooth as a heartbeat to determine if the connection is working properly. The logic is:
Connection ConnectionGatt ->Connection Successful onConnectionStateChange ->Search Service Discovered ->Search Service Successful Callback onServicesDiscovered ->Read Data readCharacteristic ->Read Data Callback onCharacteristicRead ->Write Data writeCharacteristic (Start a thread 10 seconds to write once, keep writing, write failure indicates Bluetooth disconnection or exception)
Official API:
BLE

//Get writeCharacteristic from Bluetooth mac address
BluetoothDevice bluetoothDevice =BluetoothAdapter.getDefaultAdapter().getRemoteDevice(macAddress);

Bluetooth connectivity

  mBluetoothGatt = mDevice.connectGatt(mContext, false, new BluetoothGattCallback() {

            /**
             * Bluetooth Connection Status Callback
             * @param gatt
             * @param status
             * @param newState
             */
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                if (status == BluetoothGatt.GATT_SUCCESS) {//Get GATT Service Success
                    if (newState == BluetoothProfile.STATE_CONNECTED) {
                        Log.e(TAG, "Bluetooth Connection Power...status=STATE_CONNECTED"+gatt.getDevice().getName())
                        // Connection successful, start search service, must call this method, otherwise the service will not be available
                        mBluetoothGatt.discoverServices(); 
                    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                        Log.e(TAG, "Bluetooth disconnection...status=STATE_DISCONNECTED");
                    }
                } else {  //Disconnect and reconnect
                    Log.e(TAG, "Bluetooth disconnection...status=" + status );      
                }
            }

            /**
             * A new service is discovered when the remote service, feature, and descriptor list of the remote device has been updated.
             * @param gatt
             * @param status
             */
            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                serviceDiscover(gatt, status);
            }

            /**
             * Write data to Bluetooth result callback
             * @param gatt
             * @param characteristic
             * @param status
             */
            @Override
            public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
                                              int status) {
                Log.e(TAG, "onCharacteristicWrite write status: " + status);
            }

            /**
             *
             * Read Bluetooth Data Result Callback
             * @param gatt
             * @param characteristic
             * @param status
             */
            @Override
            public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
                                             int status) {
                Log.e(TAG, "onCharacteristicRead write status: " + status);
                characteristRead(gatt, characteristic, status);
            }

            /**
             * Bluetooth Device Status Change Callback
             * @param gatt
             * @param characteristic
             */
            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                Log.e(TAG, "onCharacteristicChanged is null: " + (characteristic == null));
                //Message from Bluetooth
                dealReceiverMessage(gatt, characteristic);
            }
        });

Get GATT service, read data, set data change update

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    private void serviceDiscover(BluetoothGatt gatt, int status) {
        Log.e(TAG, "serviceDiscover status:" + status);
        FileUtil.writeError("BLE", "onServicesDiscovered status:" + status);
        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.e(TAG, "Device Connection Service is successful and ready for communication");
            BluetoothGattService service = gatt.getService(mUUIDService);
            if (service == null) {
                if (TranBlueService.currentState != TranBlueService.STATE_DISCONNECTED) {
                    mHandler.sendEmptyMessage(MSG_BLE_DISCONNECTED);
                }
                return;
            }
            /**
             * Get Bluetooth Service
             */
            mCharaRead = service.getCharacteristic(UUID.fromString(CHAR_UUID1));//read
            mCharaWrite = service.getCharacteristic(UUID.fromString(CHAR_UUID2));//write
            mCharaNotification = service.getCharacteristic(UUID.fromString(CHAR_UUID3));//notice

            if (mCharaRead != null) {
                boolean b = mBluetoothGatt.readCharacteristic(mCharaRead);//read
                mHandler.removeCallbacks(mRunnable);
                mHandler.postDelayed(mRunnable, CHECK_TIME);

                Log.e(TAG, "Device Connection Service is successful and ready for communication" + b);
            }
            if (mCharaNotification != null) {
                boolean b = mBluetoothGatt.setCharacteristicNotification(mCharaNotification, true);//Enable device notification reminders
                Log.e(TAG, "equipment notifytion Result" + b);
            }
        } else {
            Log.e(TAG, "Device connection service failed to communicate, please reconnect" + status);
            showToast("Bluetooth connection failed, please reconnect");
            if (TranBlueService.currentState != TranBlueService.STATE_DISCONNECTED) {
                mHandler.sendEmptyMessage(MSG_BLE_DISCONNECTED);
            }
        }
    }

Write data

 @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    private void characteristRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                if (value == 1) { // Private mode
            if (mCharaWrite != null) {
                // Set up data content
                mCharaWrite.setValue("1");
                // Write data to Bluetooth module
                boolean b = mBluetoothGatt.writeCharacteristic(mCharaWrite);
                Log.e(TAG, "write result = " + b);
                if(b){
                    Log.e(TAG, "Successfully written test data");
                    if (TranBlueService.currentState != TranBlueService.STATE_CONNECTED) {
                        mHandler.sendEmptyMessage(MSG_BLE_CONNECTED);
                    }
                    mHandler.removeCallbacks(mRunnable);
                    mHandler.postDelayed(mRunnable, CHECK_TIME);
                    mHandler.removeMessages(BlueManager.MSG_LINK_TIMEOUT);
                }else{
                    Log.e(TAG, "Failed to write test data");
                    if (mBluetoothGatt != null) {
                        mBluetoothGatt.disconnect();
                    }
                    mHandler.removeCallbacks(mRunnable);

                    if (TranBlueService.currentState != TranBlueService.STATE_DISCONNECTED) {
                        mHandler.sendEmptyMessage(MSG_BLE_DISCONNECTED);
                    }
                }

            }
        }
        }

Threads write data

    /***
     * Write heartbeat data to Bluetooth
     */
    Runnable mRunnable = new Runnable() {
        @Override
        public void run() {

            if (TranBlueService.currentState == TranBlueService.STATE_CONNECTED) {
                if (mCharaWrite != null) {
                    mCharaWrite.setValue("1");
                    boolean b = mBluetoothGatt.writeCharacteristic(mCharaWrite);         // Write data to Bluetooth module
                    if (b) { // Successful data writing and normal Bluetooth connection
                        mHandler.postDelayed(mRunnable, CHECK_TIME);
                        Log.e(TAG, "Successfully written test data");

                    } else { // Data write failed, Bluetooth connection abnormal, reconnect

                        if (mBluetoothGatt != null) {
                            mBluetoothGatt.disconnect();
                        }
                        mHandler.removeCallbacks(mRunnable);

                        if (TranBlueService.currentState != TranBlueService.STATE_DISCONNECTED) {
                            mHandler.sendEmptyMessage(MSG_BLE_DISCONNECTED);
                        }

                        Log.e(TAG, "Failed to write test data");
                    }
                } else {
                    Log.e(TAG, "Bluetooth connection abnormal, disconnect Bluetooth...Rescan Connections");
                    FileUtil.writeError("BLE", "Bluetooth connection abnormal, disconnect Bluetooth...Rescan Connections");
                    if (mBluetoothGatt != null) {
                        mBluetoothGatt.disconnect();
                    }
                    mHandler.removeCallbacks(mRunnable);
                    if (TranBlueService.currentState != TranBlueService.STATE_DISCONNECTED) {
                        mHandler.sendEmptyMessage(MSG_BLE_DISCONNECTED);
                    }
                }
            }
        }
    };

Processing data from Bluetooth

   private void dealReceiverMessage(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        if (characteristic == null)
            return;
        byte[] new_data = characteristic.getValue();
        if (new_data != null && new_data.length > 0) {
            dealReceOrder(new_data[0] & 0xff);//Processing Bluetooth data
        }
    }

Tags: less Android Mac

Posted on Fri, 01 May 2020 14:11:53 -0700 by Paulkirkewalker