This is the 31st day of my participation in the August Text Challenge.More challenges in August
Android BLE Bluetooth — Console development
Android is generally used as the host to connect to the slave machine, such as Bluetooth headset, Internet of things devices, these are slave machine, slave machine can set some parameters such as broadcast content and frequency, the host can also set some configuration, but in Android some pits need to record.
What is a host
In Bluetooth, it is the host that actively connects to other devices
Master mode: Works in master mode and can be connected to a slave device. In this mode, you can search for surrounding devices and select secondary devices to be connected. Theoretically, a bluetooth primary device can communicate with multiple Bluetooth secondary devices simultaneously.
2. Develop consoles on Android
2.1 the flow chart
Under normal circumstances, our communication flow with slave machine is like this. Because of these flows, the complexity in Android is that almost all operations wait for callbacks. If there is a one-to-many situation, all callback interfaces also need to be installed in the collection.
Graph LR [scan] -- > B (display device list) - B > C (select A single device) C > D (connection) D -- -- > E (sending data)
2.2 permissions
Permissions are still indispensable, in some mobile phones, do not open the location permissions, will not scan the slave device.
<! BLUETOOTH permissions - - - > < USES - permission android: name = "android. Permission. BLUETOOTH" / > < USES - the permission android:name="android.permission.BLUETOOTH_ADMIN" /> <! -- <uses-permission android:name="android.perm ission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />Copy the code
2.3 scan
Scanning mode under Android 5.0
/ / start scanning mBluetoothAdapter. StartLeScan (mLeScanCallback); / / stop scanning mBluetoothAdapter stopLeScan (mLeScanCallback);Copy the code
Scanning mode on Android 5.0 and above
ScanSettings.Builder settingBuilder = new ScanSettings.Builder(); settingBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY); // Low latency. ScanSettings settings = settingBuilder.build(); BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner(); scanner.startScan(scanFilterList, settings, scanCallback);Copy the code
SetScanMode can set the power, set to low delay can quickly scan to the slave machine, and changed to the point saving mode, scan to the slave machine speed greatly reduced.
ScanFilterList stores the filter conditions of slave devices, such as specifying UUID and bluetooth name
List<ScanFilter> scanFilterList = new ArrayList<>();
ScanFilter.Builder builder = new ScanFilter.Builder();
builder.setDeviceName("XXX");
builder.setServiceUuid(new ParcelUuid(AppConfig.UUID_SERVICE));
ScanFilter scanFilter = builder.build();
scanFilterList.add(scanFilter);
Copy the code
There are two other caveats.
- If Bluetooth scans frequently and repeatedly, the device cannot be scanned, which will be recovered after a period of time.
- Bluetooth scan duration The default duration is 30 seconds and there is no place to set it. To change the scan time, maintain a timer and manually turn off the scan after a certain time.
2.4 the connection
Android provides a way to connect to a slave computer using a MAC address. Where can I get the MAC address? In fact, after scanning the device, we can get the MAC address.
In addition, the connection method also needs to determine the version, otherwise it is easy to link error, error code 133 error
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
gatt = bluetoothDevice.connectGatt(mContext, false, mBleGattCallBack, TRANSPORT_LE);
} else {
gatt = bluetoothDevice.connectGatt(mContext, false, mBleGattCallBack);
}
Copy the code
In addition, through the system’s connection status callback, we can add a retry after connection failure mechanism to this foundation.
2.5 Sending Data
I see most articles saying that BLE is not good for transferring large amounts of data, only 20 bytes per packet by default. I don’t think so.
In fact, the default value is 20 bytes, but the data obtained by applying the MTU is the final number of bytes that can be transmitted in a packet.
How is MTU obtained
gatt.requestMtu(XX) @Override public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { super.onMtuChanged(gatt, mtu, status); //TODO if (bluetoothgat.gatt_success == status) {blesdklog. e(TAG, "set MTU successfully:" + MTU); BLESdkConfig.getInstance().setBleMaxSplitCount(mtu - 3); Else {blesdklog. e(TAG, "failed to set MTU:" + MTU); BLESdkConfig.getInstance().setBleMaxSplitCount(mtu - 3); } gatt.discoverServices(); // Start service discovery}Copy the code
Then if it is a large amount of data, it is subcontracted and sent according to MTU.
There is also a fine line when sending, do not simply send in a loop, but wait for each packet of successful feedback before sending the next packet of data.