This is the first day of my participation in the November Gwen Challenge, the event details: 2021 last Gwen Challenge preface

Have old iron people private letter, want to explain next bluetooth development, so today came;

Android 4.3 (API Level 18) introduces Bluetooth Low Energy (BLE) core features and provides corresponding apis. Through these apis, applications can scan Bluetooth devices, query services, and characteristics of read and write devices.

BLE Low power Bluetooth, the main features are fast search, fast connection, ultra-low power hold connection and data transfer;

1. BLE development process

1. Apply for permission

Android phone involves bluetooth permission problem, bluetooth development needs to add permission declaration in androidmanifest.xml file:

<! BLUETOOTH permissions - - - > < USES - permission android: name = "android. Permission. BLUETOOTH" / > < USES - the permission The android: name = "android. Permission. BLUETOOTH_ADMIN" / > for android version 6.0 and above need to add a fuzzy positioning permissions < USES - the permission The android: name = "android. Permission. ACCESS_COARSE_LOCATION" / > phone allows the permissions in the rights management, can appear otherwise can't search to the device.Copy the code

2. Turn on bluetooth

Ask to turn on your phone’s Bluetooth before searching for a device:

Private BluetoothAdapter mBluetoothAdapter = bluetoothAdapter.getDefaultAdapter (); If (mBluetoothAdapter! = null && ! mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, 1); } Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); If (requestCode == 1) {if (resultCode == RESULT_OK) {toast.maketext (this, "Bluetooth enabled ", toast.length_short).show(); } else if (resultCode == RESULT_CANCELED) {toa.maketext (this, "No Bluetooth permission ", toa.length_short).show(); finish(); }}}Copy the code

3. Search equipment

MBluetoothAdapter. StartLeScan (LeScanCallback callback) scanning BLE bluetooth device, as follows:

mBluetoothAdapter.startLeScan(callback); private LeScanCallback callback = new LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, Int arg1, byte[] arg2) {//device is the BLE device detected if(device.getname () == "targetDevice name "){// get targetDevice targetDevice = device; }}};Copy the code

4. Connect the device

By scanning the BLE device, the targetDevice targetDevice is distinguished according to the device name. The next step is to realize the connection with the targetDevice. Before connecting the device, stop searching bluetooth.

mBluetoothAdapter.stopLeScan(callback);
Copy the code

It usually takes a certain time to stop the search. It is better to call the stop search function and delay it by 100ms to ensure that the system can completely stop searching bluetooth devices. Start the connection process after stopping the search;

BLE Bluetooth connection method is relatively simple just call connectGatt method;

Public BluetoothGatt connectGatt (Context Context, Boolean autoConnect, BluetoothGattCallback callback);Copy the code

Parameters that

  • BluetoothGatt: BLE Bluetooth connection management class, mainly responsible for communication with the device;
  • Boolean autoConnect: Set the value to false to increase connection speed.
  • Bluetoothattcallback Callback connection callback, important parameters, the core part of BLE communication;

5. Equipment communication

After establishing a connection with the device and communicating with the device, the whole communication process is completed in the asynchronous callback function of BluetoothGattCallback;

The main callback functions in BluetoothGattCallback are as follows:

private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {

@Override

public void onConnectionStateChange(BluetoothGatt gatt, int status,

int newState) {

}

@Override

public void onCharacteristicWrite(BluetoothGatt gatt,

BluetoothGattCharacteristic characteristic, int status) {

super.onCharacteristicWrite(gatt, characteristic, status);

}

@Override

public void onDescriptorWrite(BluetoothGatt gatt,

BluetoothGattDescriptor descriptor, int status) {

};

@Override

public void onServicesDiscovered(BluetoothGatt gatt, int status) {

}

@Override

public void onCharacteristicChanged(BluetoothGatt gatt,

BluetoothGattCharacteristic characteristic) {

}

};
Copy the code

The above callbacks are indispensable in BLE development.

6. Wait until the device is successfully connected

When calling targetdDevice. ConnectGatt (context, false, gattCallback) after the system will initiate and BLE bluetooth connection, if successfully connect to the device will callback onConnectionStateChange method, Its processing process is as follows:

@Override public void onConnectionStateChange(BluetoothGatt gatt, int status, Int newState) {if (newState == bluetoothgatt.state_connected) {log. e(TAG, "device connected to start scanning service "); / / start scanning service, android bluetooth development. One of the important steps mBluetoothGatt discoverServices (); } if (newState == bluetoothgatt.state_disconnected) {// bluetoothgatt.state_disconnected;Copy the code

If newState == bluetoothgatt. STATE_CONNECTED, the device has been successfully connected.

7. Enable the scan service

mBluetoothGatt.discoverServices();
Copy the code

The discovered () function onServicesDiscovered() is called after the device is successfully connected. The prototype of the function is as follows:

@Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { private List<BluetoothGattService> servicesList; / / get service list servicesList = mBluetoothGatt getServices (); }Copy the code
  • BLE bluetooth protocol of data communication mode using BluetoothGattService, BluetoothGattCharacteristic and BluetoothGattDescriptor three main classes implement communication;
  • BluetoothGattService for short, is the component unit of THE BLE device protocol stack. A Bluetooth device protocol stack is generally composed of one or more BluetoothGattService.
  • BluetoothGattCharacteristic referred to as “characteristics, a service includes one or more characteristics, features as the basic unit of data;
  • A BluetoothGattCharacteristic feature contains a data value and additional description of characteristics
  • BluetoothGattDescriptor: class used to describe features, which also contain a value;

8, obtain BluetoothGattCharacteristic is responsible for the communication

BLE bluetooth development is mainly responsible for communication BluetoothGattService to complete. When and called communication service. Obtain the communication service from the UUID provided by hardware engineers. Obtain it as follows:

  • BluetoothGattService service = mBluetoothGatt. GetService (UUID. FromString (” bluetooth module provides is responsible for the communication UUID string “));
  • Communications services include BluetoothGattCharacteristic responsible for reading and writing, and is called notifyCharacteristic and writeCharacteristic respectively. NotifyCharacteristic is responsible for starting the listening, that is, starting the channel for receiving data, and writeCharacteristic is responsible for writing data.

The specific operation mode is as follows:

BluetoothGattService service = mBluetoothGatt. GetService (UUID. FromString (" bluetooth module is responsible for the communication service provided by the UUID string ")); // For example: 49535343-fe7d-4ae5-8fa9-9fafd205e455 notifyCharacteristic = service.getCharacteristic(UUID.fromString("notify uuid")); writeCharacteristic = service.getCharacteristic(UUID.fromString("write uuid"));Copy the code

9. Enable listening

Enable monitoring, that is, establish the first data channel for communication with the device. In BLE development, only when the upper computer successfully starts monitoring, can it receive and send data with the lower computer. You can enable listening as follows:

mBluetoothGatt.setCharacteristicNotification(notifyCharacteristic, true) BluetoothGattDescriptor descriptor = characteristic .getDescriptor(UUID .fromString ("00002902-0000-1000-8000-00805f9b34fb")); descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); If listening is enabled successfully the BluetoothGattCallback onDescriptorWrite() method is called back as follows: @Override public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, Int status) {if (status == bluetoothgatt.gatt_success) {log. e(TAG, "bluetoothgatt.gatt_success "); }};Copy the code

10. Write data

After successful monitoring, the communication with the lower computer is realized by writing data to writeCharacteristic. Write as follows:

/ / value for PC sent down a machine instruction writeCharacteristic. SetValue (value); mBluetoothGatt.writeCharacteristic(writeCharacteristic)Copy the code

Value is generally in Hex format, and its content is specified by bluetooth communication protocol of the device.

11. Receiving data

If the write command succeeds, the onCharacteristicWrite() method in BluetoothGattCallback is called back, indicating that the data has been sent to the next machine.

@Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, Int status) {if (status == bluetoothgatt.gatt_success) {log. e(TAG, "sent successfully "); } super.onCharacteristicWrite(gatt, characteristic, status); }Copy the code

If the data sent conforms to the communication protocol, the lower computer replies the corresponding data to the upper computer. The sent data is retrieved using the onCharacteristicChanged() callback method as follows:

@Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {/ / the value for the devices to send data, according to the data protocol parsing byte [] value = characteristic. The getValue (); }Copy the code

By sending instructions to the lower machine to obtain the reply data of the lower machine, the communication process with the equipment can be completed;

12. Disconnect

Disconnect the device when communicating with it. Call the following methods to disconnect from the device:

mBluetoothGatt.disconnect();

mBluetoothGatt.close();
Copy the code

Ii. Notes for Bluetooth operation

  • Bluetooth write operations, read operations must be serialized. Write data and read data cannot be performed at the same time. If the method that writes data is called and then calls the method that writes data or reads data, the method that is called for the second time will immediately return false, indicating that the operation cannot be performed.
  • The number of Android peripherals is limited, and BluetoothGatt#close must be called to release resources when bluetooth devices are not needed.
  • The timeout period of bluetooth API connection to Bluetooth device is about 20s, depending on the system implementation. Sometimes the bluetooth connection on some devices can take a long time, more than ten seconds. BluetoothGattCallback#onConnectionStateChange return state == 133 if you manually set the connection timeout on some devices.
  • All Bluetooth operations are fixed to a single thread using a Handler, which saves a lot of trouble because threads are out of sync.

conclusion

There are many problems in bluetooth development, we should calm down and analyze the problems, we can certainly solve them, refueling together;