文章目录
Bluetooth low energy
Devices running Android 4.3 (API level 18) and higher have built-in platform support for Bluetooth Low Energy (BLE) in the central role. Your app can use APIs to discover devices, query for services, and transmit information.
In contrast to Classic Bluetooth, BLE is designed to provide significantly lower power consumption. This allows Android apps to communicate with BLE devices that have stricter power requirements, such as proximity sensors, heart rate monitors, and fitness devices.
Caution: When a user pairs their device with another device using BLE, the data that’s communicated between the two devices is accessible to all apps on the user’s device. For this reason, if your app captures sensitive data, you should implement app-layer security to protect the privacy of that data.
Key terms and concepts
Here is a summary of key BLE terms and concepts:
-
Generic Attribute Profile (GATT) — The GATT profile is a general specification for sending and receiving short pieces of data known as attributes over a BLE link. All current Low Energy application profiles are based on GATT. Review the Android BluetoothLeGatt sample on GitHub to learn more.
-
The Bluetooth SIG defines many profiles for Low Energy devices. A profile is a specification for how a device works in a particular application. Note that a device can implement more than one profile. For example, a device could contain a heart rate monitor and a battery level detector.
-
Attribute Protocol (ATT) — GATT is built on top of the Attribute Protocol (ATT). This is also referred to as GATT/ATT. ATT is optimized to run on BLE devices. To this end, it uses as few bytes as possible. Each attribute is uniquely identified by a Universally Unique Identifier (UUID), which is a standardized 128-bit format for a string ID used to uniquely identify information. The attributes transported by ATT are formatted as characteristics and services.
-
Characteristic — A characteristic contains a single value and zero or more descriptors that describe the characteristic’s value. A characteristic can be thought of as a type, analogous to a class.
-
Descriptor — Descriptors are defined attributes that describe a characteristic value. For example, a descriptor might specify a human-readable description, an acceptable range for a characteristic’s value, or a unit of measure that is specific to a characteristic’s value.
-
Service — A service is a collection of characteristics. For example, you could have a service called “Heart Rate Monitor” that includes characteristics such as “heart rate measurement.” You can find a list of existing GATT-based profiles and services on bluetooth.org.
Roles and responsibilities
The following are the roles and responsibilities that apply when an Android device interacts with a BLE device:
- Central versus peripheral. This applies to the BLE connection itself. The device in the central role scans, looking for an advertisement, and the device in the peripheral role makes the advertisement.
- GATT server versus GATT client. This determines how two devices talk to each other once they’ve established a connection.
To understand the distinction between central and peripheral roles, imagine that you have an Android phone and an activity tracker that is a BLE device. The phone supports the central role and the activity tracker supports the peripheral role. To establish a BLE connection, you need one of each; two devices that support only peripheral couldn’t talk to each other, nor could two things that support only central.
Once the phone and the activity tracker have established a connection, they start transferring GATT metadata between each other. Depending on the kind of data they transfer, one or the other might act as the server. For example, if the activity tracker wants to report sensor data to the phone, it might make sense for the activity tracker to act as the server. If the activity tracker wants to receive updates from the phone, then it might make sense for the phone to act as the server.
In the example used in this topic, the Android app (running on an Android device) is the GATT client. The app gets data from the GATT server, which is a BLE heart rate monitor that supports the Heart Rate Profile. You could as easily design your Android app to play the GATT server role. See BluetoothGattServer
for more information.
BLE permissions
To use Bluetooth features in your application, you must declare the BLUETOOTH
permission. You need this permission to perform any Bluetooth communication, such as requesting a connection, accepting a connection, and transferring data.
If you want your app to initiate device discovery or manipulate Bluetooth settings, you must also declare the BLUETOOTH_ADMIN
permission.
Note: If you use the
BLUETOOTH_ADMIN
permission, then you must also have theBLUETOOTH
permission.
Because discoverable devices might reveal information about the user’s location, the device discovery process requires location access. If your app is being used on a device that runs Android 8.0 (API level 26) or higher, consider using the Companion Device Manager API, instead. This API performs device discovery on your app’s behalf, so that your app doesn’t need to request location permissions.
If you don’t use the Companion Device Manager API, declare the ACCESS_FINE_LOCATION
permission.
Note: Not declaring the required permissions causes [
BluetoothLeScanner.startScan()
](https://developer.android.google.cn/reference/android/bluetooth/le/BluetoothLeScanner#startScan(java.util.List, android.bluetooth.le.ScanSettings, android.app.PendingIntent)) to fail silently.
Declare the permissions in your application manifest file. For example:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!-- Required only if your app isn't using the Device Companion Manager. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
If you want to declare that your app is available to BLE-capable devices only, include the following in your app’s manifest:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
If you want to make your app available to devices that don’t support BLE, include this element in your app’s manifest, but set required="false"
. Then at runtime you can determine BLE availability by using PackageManager.hasSystemFeature()
.
// Use this check to determine whether BLE is supported on the device. Then
// you can selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
For information on setting up a BLE connection from your app see Use Bluetooth low energy.
准备
Android Studio
Android Studio 4.1.3
Build #AI-201.8743.12.41.7199119, built on March 11, 2021
Runtime version: 1.8.0_242-release-1644-b01 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
关于手机
HUAWEI Mate 10
模拟设备
在运行时检查设备是否支持 BLE
新建项目,选择 Empty Activity,在配置项目时,Minimum SDK
选择 API 16: Android 4.1 (Jelly Bean)
。
编辑 src\main\AndroidManifest.xml
应用清单文件:
- 声明 android.permission.BLUETOOTH 等权限(第 5~7 行);
- 声明不需设备支持 BLE 特性(第 9 行)。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mk">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />
...
</manifest>
编辑 MainActivity
,在运行时检查设备是否支持 BLE(第 16 ~ 21 行):
package com.mk;
import androidx.appcompat.app.AppCompatActivity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "BLE not supported.", Toast.LENGTH_LONG).show();
// finish();
} else {
Toast.makeText(this, "BLE supported.", Toast.LENGTH_LONG).show();
}
}
}
分别在 HUAWEI Mate 10 和模拟设备上运行:
HUAWEI Mate 10 支持 BLE:
模拟设备不支持 BLE: