1 蓝牙开发原理
蓝牙技术作为短距离无线通信的核心标准,在手机端的应用覆盖了智能家居控制、可穿戴设备交互、无线数据传输等多个场景。NUCLEO-WBA65RI作为终端,采用手机控制可以实现更多的功能。
蓝牙技术通过标准化协议实现设备间低功耗、低成本的短距离数据交换,Android 平台支持经典蓝牙(BT)与低功耗蓝牙(BLE)两大类型,二者差异如下:
类型 |
核心特点 |
适用场景 |
代表版本 |
经典蓝牙(BT) |
传输速率较高(最高 48Mbps),功耗中等 |
语音通话、音乐传输、大数据文件同步 |
2.1+EDR、3.0+HS、5.0+ |
低功耗蓝牙(BLE) |
功耗极低,待机时间长,实时性强 |
智能家居、可穿戴设备(手环、手表)、传感器数据采集 |
4.0 及以上 |
按协议支持又可分为单模(仅支持 BT 或 BLE)和双模(同时支持 BT 与 BLE)模块,开发前需根据应用场景确定适配类型。
NUCLEO-WBA65RI的蓝牙开发以BLE为主要方式,显示端侧的低功耗特征等。
以ST25的NFC读取应用为蓝本融入蓝牙的开发。

2 环境配置和权限声明与动态申请
蓝牙开发需在AndroidManifest.xml
中声明基础权限,并根据系统版本补充细分权限,具体如下:
(1)基础权限(所有 Android 版本)
<!-- 连接已配对蓝牙设备 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 发现和配对蓝牙设备 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
(2)系统版本适配权限
-
Android 6.0(API 23)及以上:蓝牙扫描需定位权限(扫描可用于粗略定位)
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-
Android 10(API 29)及以上:后台扫描需补充后台定位权限
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
-
Android 12(API 31)及以上:新增蓝牙连接专用权限
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
如下设定

动态权限请求实现
定位、蓝牙连接等权限属于运行时权限,需在应用启动或功能触发前主动请求用户授权。可通过原生 API 或第三方库(如 XXPermissions)实现:
2. 蓝牙适配器初始化与设备检查
BluetoothAdapter
是所有蓝牙操作的入口,需先获取实例并检查设备兼容性:
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();// 检查设备是否支持蓝牙
if (bluetoothAdapter == null) {
// 设备不支持蓝牙,提示用户
Toast.makeText(this, "设备不支持蓝牙功能", Toast.LENGTH_SHORT).show();
return;
}// 检查蓝牙是否已启用
if (!bluetoothAdapter.isEnabled()) {
// 请求用户启用蓝牙(推荐方式,需用户确认)
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}// 监听蓝牙启用结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == RESULT_OK) {
// 蓝牙已启用,执行后续操作
} else {
// 用户拒绝启用蓝牙,提示功能不可用
}
}
}
(1)获取已配对设备
通过getBondedDevices()
方法获取系统中已配对的蓝牙设备列表:
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
String deviceName = device.getName(); // 设备名称
String deviceMac = device.getAddress(); // 设备MAC地址(唯一标识)
Log.d("Bluetooth", "已配对设备:" + deviceName + ",MAC:" + deviceMac);
}
}
(2)扫描附近设备
扫描过程通过startDiscovery()
触发(异步操作,持续约 12 秒),需注册广播接收器监听设备发现事件:
// 1. 注册广播接收器
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND); // 发现设备
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); // 扫描结束
registerReceiver(bluetoothReceiver, filter);
// 2. 启动扫描
if (bluetoothAdapter.startDiscovery()) {
Log.d("Bluetooth", "扫描已启动");
}
// 3. 广播接收器实现
private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// 获取发现的设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceMac = device.getAddress();
Log.d("Bluetooth", "发现设备:" + deviceName + ",MAC:" + deviceMac);
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Log.d("Bluetooth", "扫描结束");
}
}
};
// 4. 停止扫描与注销接收器
bluetoothAdapter.cancelDiscovery(); // 扫描消耗资源,找到目标后立即停止
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(bluetoothReceiver); // 避免内存泄漏
}
(3)设备配对
配对需监听ACTION_PAIRING_REQUEST
广播,处理 PIN 码输入或确认逻辑(不同设备配对流程可能不同):
// 广播接收器中添加配对事件监听
if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int pin = intent.getIntExtra(BluetoothDevice.EXTRA_PIN, 0000); // 获取默认PIN码(如0000)
// 输入PIN码并确认配对
device.setPin(String.valueOf(pin).getBytes());
device.createBond();
}