Android BLE development-Android mobile phone and BLE terminal first recognized, androidble
Bluetooth BLE official Demo: http://download.csdn.net/detail/lqw770737185/8116019
Refer to blog address: http://www.eoeandroid.com/thread-563868-1-1.html? _ Dsign = 843d16d6
Device: One MX5 mobile phone and one pesticide residue detector (BLE terminal device)
Objective: To implement Mobile Phone control instruments, such as sending printing instructions and printing operations.
There is a lot of information on how to enable Bluetooth, configure related permissions, search for BLE devices, and other steps online. I will not explain it here. This article focuses on communication. Note that the result of searching for the BLE device is returned asynchronously. leScanCallback is returned in the callback, And the search process is a very power-consuming process, so we should do the corresponding processing, for example, let it search for 10 s and stop the search.
Before we understand the communication process between Android devices and BLE terminal devices, we need to first understand several categories:
BluetoothGatt:BluetoothGatt is the most widely used and most important class. To make it as easy as possible, we can regard it as a channel for communication between Android phones and BLE terminal devices, only with this channel can we have the premise of communication.
BluetoothGattService:Here we compare the bluetooth device service to the class. While we use thdevice to compare it to a school. A school can have many classes. That is to say, each BLE terminal device has multiple services and classes (various services) they are differentiated by UUID (unique identifier.
BluetoothGattCharacteristic:The characteristics of a bluetooth device are the key to data exchange between the mobile phone and the BLE terminal device. All we do is to get it. Here we compare it to a student. There are many students in a class. That is to say, we have multiple features under each service. Students (each feature) Use UUID (unique identifier) difference.
Conclusion: when we want to use our mobile phone to communicate with the BLE device, it is actually equivalent to finding a student to communicate with. First, we need to build a pipeline, that is to say, we need to obtain a BluetoothGatt first. Secondly, we need to know which class the student belongs to and what the student ID is. This is what we call serviceUUID, and charUUID. Here, we also need to pay attention that the student is not directly communicating with him after finding the student. He is like an intermediary who helps the two send information between mobile phones and BLE terminal devices, the data sent by our mobile phone must first pass through him and be transmitted to the BLE device, while the information returned from the BLE device is also transmitted to him first, then the phone reads data from him.
The communication result between the Android mobile phone and the BLE terminal device is returned in the form of callback. The following are several common return callbacks (which can be seen in the BluetoothLeservice class of the official Demo ):
Private effecthgattcallback mGattCallback = new effecthgattcallback () {// callback for connection status change @ Override public void onConnectionStateChange (effecthgatt gatt, int status, int newState) {if (newState = effecthprofile. STATE_CONNECTED) {// after the connection is successful, start the service discovery Log. e ("AAAAAAAA", "Startup service discovery:" + mbluw.thgatt. discoverServices () ;}}; // The callback public void onServicesDiscovered (descrithgatt gatt, int status) {if (status = descrithgatt. GATT_SUCCESS) {Log. e (TAG, "successfully found service");} else {Log. e (TAG, "service discovery failed, error code:" + status) ;}}; // write operation callback public void onCharacteristicWrite (descrithgatt gatt, descrithgattcharacteristic characteristic, int status) {if (status = processing thgatt. GATT_SUCCESS) {Log. e (TAG, "written successfully" + characteristic. getValue () ;}}; // public void onCharacteristicRead (descrithgatt gatt, descrithgattcharacteristic characteristic, int status) {if (status = descrithgatt. GATT_SUCCESS) {Log. e (TAG, "read successful" + characteristic. getValue () ;}}// the callback returned by the data (this receives the data returned by the BLE device) public void onCharacteristicChanged (descrithgatt gatt, descrithgattcharacteristic characteristic ){};};}
1. Connect to the Bluetooth BLE Terminal Device
After we turn on Bluetooth and scan to find the device we want to connect to, next we need to connect to it. The connection method is very simple and we can implement it with a line of code (as shown below ). It can be found that when we start to connect to the BLE terminal device, the connection method will automatically return a thgatt object for us. As we mentioned above, thgatt is our most important class, it is equivalent to a pipe, which is the prerequisite for communication: (there are three parameters, the first parameter is the context object, and the second parameter is whether to automatically connect. Here it is set to false, the third parameter is the callback method above)
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
The following callback is used to tell us whether the connection is successful or not:
// Callback for connection status change @ Override public void onConnectionStateChange (descrithgatt gatt, int status, int newState) {// indicates that the connection is successful, here we can send a broadcast back to tell the activity that it has successfully connected if (newState = descrithprofile. STATE_CONNECTED) {// after the connection is successful, start the service discovery Log. e ("AAAAAAAA", "Startup service discovery:" + mbluw.thgatt. discoverServices ());}}
2. Start Service Discovery
After the connection is successful, we need to find the services we need. here we need to start service discovery and use a code:
mBluetoothGatt.discoverServices() ;
When the service is started, the result is returned through the callback function:
// Public void onServicesDiscovered (descrithgatt gatt, int status) callback of the Discovery Service {// after discovering the service, you can call the corresponding method to obtain all services of the BLE device, and print the UUID of each service and the UUID of each feature under each service if (status = descrithgatt. GATT_SUCCESS) {List <javasthgattservice> supportedGattServices = mbluw.thgatt. getServices (); for (int I = 0; I <supportedGattServices. size (); I ++) {Log. e ("AAAAA", "1: effecthgattservice UUID =:" + supportedGattServices. get (I ). getUuid (); List <symbol thgattcharacteristic> listGattCharacteristic = supportedGattServices. get (I ). getCharacteristics (); for (int j = 0; j <listGattCharacteristic. size (); j ++) {Log. e ("a", "2: descrithgattcharacteristic UUID =:" + listGattCharacteristic. get (j ). getUuid () ;}} else {Log. e ("AAAAA", "onservicesdiscovered Received:" + status );}}
We can also call the following method to learn the attributes of each feature: readable, writable, notification, or all.
// Cyclically traverse the service and each feature under each service to judge the read/write and notification attributes for (descrithgattservice gattService: supportedGattServices) {List <descrithgattcharacteristic> gattCharacteristics = supportedGattServices. getCharacteristics (); for (BluetoothGattCharacteristic gattCharacteristic: gattCharacteristics) {int charaProp = gattCharacteristic. getProperties (); if (charaProp | descrithgattcharacteristic. PROPERTY_READ)> 0) {// Log. e ("nihao", "the UUID of gattCharacteristic is:" + gattCharacteristic. getUuid (); // Log. e ("nihao", "attributes of gattCharacteristic are: readable");} if (charaProp | BluetoothGattCharacteristic. PROPERTY_WRITE)> 0) {// Log. e ("nihao", "the UUID of gattCharacteristic is:" + gattCharacteristic. getUuid (); // Log. e ("nihao", "attributes of gattCharacteristic are: writable");} if (charaProp | BluetoothGattCharacteristic. property_policy)> 0) {// Log. e ("nihao", "the UUID of gattCharacteristic is:" + gattCharacteristic. getUuid () + gattCharacteristic); // Log. e ("nihao", "attributes of gattCharacteristic are: Attributes of notification ");}}}
3. Obtain Characteristic
As we said before, our ultimate goal is to get Characteristic for communication. Normally, we can get serviceUUID and characteristicUUID from the hardware engineer, that is, the class number and student number we compared to get our characteristic, but if we cannot know the required UUID, we can also use the method in the previous step to obtain (print all features UUID and retrieve desired features ). In this experiment, I obtained this method, but I found that even though the BLE terminal on my side has all the features of each service, it has the readable and writable notification attributes, however, only characteristicUUID = "effecffe1-0000-1000-8000-00805f9b34fb" can communicate with this UUID, and its corresponding serviceUUID = "nobody" can be used first. Assuming that we know serviceUUID and characteristicUUID, we can obtain the corresponding feature value through the following code:
BluetoothGattService service = mBluetoothGatt.getService(UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb"));BluetoothGattCharacteristic characteristic= service.getCharacteristic(UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb"));
4. Start Communication
After we get a corresponding feature, we can start the read/write operation to communicate with each other.
A. the read operation is relatively simple. You only need to pass in the corresponding feature value to obtain the data under the feature value. The code below:
mBluetoothGatt.readCharacteristic(characteristic);
The read result is returned through the onCharacteristicRead callback: (The read value can be obtained through characteristic. getValue)
// Read operation callback public void onCharacteristicRead (descrithgatt gatt, descrithgattcharacteristic characteristic, int status) {if (status = descrithgatt. GATT_SUCCESS) {Log. e (TAG, "read successful" + characteristic. getValue ());}}
B. Write operations. Write operations are our focus. We can control BLE terminal devices by writing commands (sending commands) to characteristic:
// Place the command into the characteristic feature. setValue (new byte [] {0x7e, 0x14, 0x00, 0x00,0x00, (byte) 0xaa}); // set the reply form characteristic. setWriteType (fig. WRITE_TYPE_NO_RESPONSE); // start to write data mbluw.thgatt. writeCharacteristic (chharacteristic );
Note: We send hexadecimal data to communicate with the instrument. When sending the data, we need to first load it into the byte [] array, for example, if I send the 7e 14 00 00 00 aa command, I need to convert it to ew byte [] {0x7e, 0x14, 0x00, 0x00,0x00, (byte) 0xaa} is sent in this way, because the BLE transmission process can only transmit up to 20 bytes at a time, so if the Command sent is greater than 20 bytes, it should be subcontracted to send, for example, if you want to send 28 bytes, You can first write (the first 20 bytes), enable the thread sleep (dozens of milliseconds), and then write (the last 8 bytes).
V. data returned by BLE terminal Devices
When we write commands to BLE terminal devices, if the writing succeeds and the commands are correct, we will get the corresponding response commands, in the following callback, we can get the response command returned by the BLE device (through characteristic. getValue () to retrieve the returned data ):
// The callback returned by the data (in this example, the server receives and processes the data) public void onCharacteristicChanged (descrithgatt gatt, descrithgattcharacteristic characteristic) {Log. e ("AAAAAAAA", characteristic. getValue ());};
The premise for receiving the returned data is that we have set the feature to have the Notification function, so the complete write operation code should be like this (note that the code for setting the feature Notification should be placed at the beginning ):
Mbluw.thgatt. setCharacteristicNotification (characteristic, true) // place the command in characteristic. setValue (new byte [] {0x7e, 0x14, 0x00, 0x00,0x00, (byte) 0xaa}); // set the reply form characteristic. setWriteType (fig. WRITE_TYPE_NO_RESPONSE); // start to write data mbluw.thgatt. writeCharacteristic (chharacteristic );
The above is my preliminary understanding of communication between Android phones and BLE devices. please correct me if I have any incorrect information.