1. IntroductionThis article is mainly based on Android's official low-power Bluetooth connection service. Explain how to connect to Bluetooth devices via UUID. If you don't know much about GATT services, this article should be able to help you a little. Official document address: https://developer.android.google.cn/guide/topics/connectivity/bluetooth-le?hl=zh_cn#connect 2. ConceptIf you are an old user, you should know that Bluetooth devices used to be high power consumption components. It was impossible to turn them on for a long time. After Bluetooth 4.0, Bluetooth communication, power consumption, and anti-interference have been significantly improved. At the same time, the cost of Bluetooth has also been reduced. Then there was the explosion of various wearable devices we have today, such as bracelets, Bluetooth headsets, Bluetooth electronic scales, Bluetooth speakers, etc. At the same time, other industrial or external devices have also begun to support Bluetooth communication in large quantities because of the reduced energy consumption and cost. For low-power Bluetooth communication, Android 4.3 (API 18) introduced the BLE library. We can directly use the Bluetooth BLE library in the Android SDK without importing additional dependent libraries.
2.1 Terminology
The above terminology is introduced from the Android official website 2.2 Communication ProcessSuppose we have a Bluetooth external device (Device) and a Bluetooth-enabled mobile device (Phone). The communication steps between the two are:
This is the whole process. I will also introduce this communication process below. 3. DevelopmentBased on my usage, I will introduce the complete Bluetooth development and configuration process from scratch. Here is a reference for you The main language is Java 3.1 PermissionsTo use Bluetooth functionality in your app, you must declare the BLUETOOTH permission. This permission is required to perform any Bluetooth communication, such as requesting a connection, accepting a connection, and transferring data. At the same time, location permission is also required because Bluetooth LE beacons are usually associated with locations. If the ACCESS_FINE_LOCATION permission is not enabled, we will not be able to discover Bluetooth devices. That is, executing the Bluetooth scanning API will not get any results (PS: The error log in Logcat will tell you that you need to enable location permissions, otherwise you cannot scan and discover Bluetooth devices). <!-- Bluetooth search pairing --> android.permission.ACCESS_FINE_LOCATION is a permission for higher versions of API 28. If you want to support lower versions, you need to apply for <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />. If we want to perform Bluetooth scanning, we need to apply for the permission: <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> If you want to perform a Bluetooth connection, turn Bluetooth on and off. You need to apply for: <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> permission The above two permissions are only valid on API 31. For lower versions, you need to apply: <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> permission is enough. After the permissions are configured, it is time to develop the code. Regardless of whether it is a high version or a low version, it is safest to apply for all permissions. 3.2 Check whether the device supports BluetoothUsually, mobile phones have Bluetooth. However, if we use other Android devices, such as TVs, tablets, all-in-one computers, etc., we cannot guarantee whether they have Bluetooth. If you are unsure, you can check the availability of BLE by using the following code. @Override Whether Bluetooth is turned on or not does not affect the test results. It checks whether the device has Bluetooth function, not whether Bluetooth is turned on. The following will introduce how to determine whether Bluetooth is turned on 3.3 Turn on BluetoothOnce our device supports Bluetooth and the permissions are configured, the next step is to obtain the BluetoothAdapter object. final BluetoothManager bluetoothManager = ( BluetoothManager ) getSystemService ( Context . BLUETOOTH_SERVICE ); Our subsequent control of the Bluetooth status is achieved through this method. First, check whether Bluetooth is enabled. You can use the isEnabled() method to check: if ( bluetoothAdapter == null || ! bluetoothAdapter . isEnabled ()) { We can actually use bluetoothAdapter.enable() to enable Bluetooth directly. If Bluetooth is not enabled, we can enable it directly. The result of this method is not returned in real time. If we want to know whether Bluetooth is turned on, we need to listen to the broadcast of Bluetooth status. The following will introduce broadcast monitoring.
The official recommendation is that we use Intent to let the system settings turn on Bluetooth. if ( bluetoothAdapter == null || ! bluetoothAdapter .isEnabled ( ) ) { But now the startActivityForResult method is obsolete. We can use Launcher to call: ActivityResultLauncher < Intent > launcher = registerForActivityResult ( new ActivityResultContracts .StartActivityForResult ( ) , result -> { The launcher above needs to be initialized in the onCreate method of Activity. Then configure it where the Bluetooth settings interface needs to be launched: Intent enableBtIntent = new Intent ( BluetoothAdapter . ACTION_REQUEST_ENABLE ); //Create a Bluetooth startup intent If Android Studio displays a code error warning when we use bluetoothAdapter.enable();, we can add the @SuppressLint("MissingPermission") annotation to the method used in the code. 3.4 Broadcast MonitoringIn fact, whether this broadcast monitoring is necessary depends on your actual situation. It is not necessarily necessary. First, create a dynamic broadcast object: public class BluetoothFoundReceiver extends BroadcastReceiver { Then register for broadcasting: bluetoothFoundReceiver = new BluetoothFoundReceiver (); After registration is complete, you need to unregister in the onDestroy method: @Override
3.5 Bluetooth device searchThe recommended search method in the official documentation is: bluetoothAdapter . startLeScan ( leScanCallback ); //Find But now this method is outdated. The replacement method is: BluetoothLeScanner scanner = bluetoothAdapter . getBluetoothLeScanner (); The onScanResult method is a callback triggered in the child thread. We cannot directly operate the UI object in this method. Secondly, scanning a Bluetooth device will trigger a message callback. We can get a BluetoothDevice object. That is to say, this method will trigger multiple callbacks. Therefore, it is recommended that after scanning our Bluetooth device, we actively call scanner.stopScan(callback); to stop scanning.
The above is a general search mode, we can also configure our own filtering conditions. For example: ScanFilter sn = new ScanFilter . Builder (). setDeviceName ( "The name of the Bluetooth device" ). setServiceUuid ( ParcelUuid . fromString ( "Service UUID of our device" )). build (); In the ScanFilter object, we can configure the information of the Bluetooth device we want to find. It can be setDeviceName, setServiceUuid, setDeviceAddress, setServiceSolicitationUuid, etc. The ScanSettings object can define our scanning mode. By configuring this item, we can improve the scanning efficiency. By default, the following is performed: SCAN_MODE_LOW_POWER Performs Bluetooth LE scanning in low power mode. This is the default scanning mode as it consumes the least power. 3.5.1 startDiscoveryIf the above method does not meet our needs, you can use: if ( bluetoothAdapter . isDiscovering ()) { // Is it scanning? We can directly use bluetoothAdapter to scan. After this method is triggered, the system will perform Bluetooth scanning, just like we click Bluetooth scanning in the settings interface of the mobile phone. The above method has no callback because all Bluetooth device discoveries will be delivered via broadcast events. You need to listen to the content introduced above to obtain the scanned devices in real time. There are several disadvantages to using the above approach: 1. Slow efficiency and time-consuming. 2. Repeated scanning will fail. It cannot be said that it fails, but the system will block the request for repeated scanning. The key problem is that this blocking operation is customized by the mobile phone manufacturer.
3.6 Link GattWhen we scan a Bluetooth device, we will get a BluetoothDevice object. Then we use the BluetoothDevice object to create a GATT service for subsequent Bluetooth communication. BluetoothDevice device ; // After we get the device object through scanning, we create the Gatt service There is nothing much to introduce about the first parameter context. The second parameter autoConnect: is a boolean value object. False means directly connecting to the Bluetooth device. True means automatically connecting when the Bluetooth device is available. The third parameter BluetoothGattCallback is the various callbacks of the Gatt service. We use the gattCallback callback content to obtain the connection status with the Bluetooth device, data communication content, etc. The following is a detailed introduction to several methods of the BluetoothGattCallback object. String SERVICE_UUID = "00000-000000-000000-000000" ; //This is the ServiceUUID of the Bluetooth device I want to connect to We can judge the current communication status with the Bluetooth device through the link success and link disconnection. After we successfully compare the UUID of the Service, we can get the Characteristic object of the Service. This object is also the characteristic. By registering the characteristic, we can implement the monitoring and sending of messages. 3.7 Register message listener-setCharacteristicNotification@SuppressLint ( "MissingPermission" ) In the example above: READ_DEDSCRIPTION_UUID = "00002902-0000-1000-8000-00805f9b34fb" is fixed, no matter what kind of bluetooth device you connect to. When registering a message monitor, the UUID value is 00002902-0000-1000-8000-00805f9b34fb. This is reserved by the Android system and is used for dynamic monitoring. If you don't want to use this dynamic monitoring, you need to write your own thread to actively poll and obtain the messages sent by the Bluetooth device. At this point, we can actually monitor the Bluetooth device in real time and get the message content. 3.8 Writing data to a Bluetooth deviceIf we want to push content to a Bluetooth device, when discovering services, onServicesDiscovered traverses the characteristics and ensures that it is the characteristic object used to write messages. Select to hold the characteristic, and then pass: String data = "0x12" ; 3.9 Closing the ConnectionWhen the Bluetooth communication ends or the interface is closed, we need to close the GATT service to reduce resource usage. if ( bluetoothGatt != null ) { You can also turn off the BluetoothGattCallback callback monitoring: gattCallback . disConnectBlue (); //Disable GATT service callback monitoring 4. SummaryThis is the end of Bluetooth connection and reading. After we find the Bluetooth device through bluetoothAdapter, we pair the Bluetooth device with the phone through GATT service. We directly compare UUIDs, and no longer need PIN codes for pairing. (PS: Some devices with higher security requirements still require active PIN pairing. PIN pairing can only be performed through the Bluetooth function item in the system device interface.) After successfully connecting to the GATT service, you can query the various characteristics of the server. Different characteristics correspond to a function. There are characteristics for sending messages and characteristics for receiving messages. At the same time, a Bluetooth device object may have multiple service functions. If you don't want to write thread variables to poll messages sent by the device, you can register a message listener and let the BLE framework help you poll and then notify you. |
<<: React Native vs. Kotlin: A Quick Comparison
>>: Google now releases the second beta version of the Android 14 system developer preview
From the arcade N73, to the T9 flagship N95, to t...
Written in front: Recently, I have seen many iOS ...
The second phase of the advanced watercolor illus...
With Apple releasing the latest version of Watch ...
On July 7, the 1818 Golden Eye program reported t...
The China Earthquake Networks Center officially d...
Last Sunday, we discussed with our friends on “Br...
On October 25, Xiaomi Note 2 was released as sche...
2022 has passed, and the brand new year of 2023 h...
Nowadays, our lives are inseparable from electric...
Recently, Jaguar Land Rover Automotive Trading (S...
Large-scale enterprise-level data center DC power...
Preface Network programming is essential in Andro...
Qishui soup, Gradually the carriage curtains and ...
Review expert: Peng Guoqiu, deputy chief physicia...