鸿蒙学习实战之路-蓝牙设备查找完全指南
扫描别太久:扫描很费蓝牙资源,找到设备就赶紧停权限别忘要:没权限的话啥都干不了,就像没洗手做饭会被打一样API版本要注意:API 18+ 用,API 17- 用配对状态要检查:有时候设备虽然在列表里,但可能已经取消配对了。
鸿蒙学习实战之路-蓝牙设备查找完全指南
最近好多朋友问我:“西兰花啊,我想在鸿蒙应用里查找周边的蓝牙设备,咋整啊?” 害,这问题可问对人了!今天我就把官方文档里的设备查找功能,用咱前端厨子的方式给你掰扯明白~
🥦 先唠唠为啥需要这功能
你想想,做个智能家居 app 得连蓝牙音箱吧?做个体脂秤 app 得连设备吧?甚至做个简单的文件传输 app 也得先找到对方设备啊!所以"查找设备"就是蓝牙功能的基础,相当于咱们做饭前得先把食材找出来~
第一步:配齐"锅碗瓢盆"(申请权限+导入模块)
1.1 先搞定权限
就像做饭得先洗手一样,用蓝牙功能得先申请权限。在你的 module.json5 里加上这个:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.ACCESS_BLUETOOTH"
}
]
}
}
1.2 导入必要的模块
做饭得先把锅碗瓢盆摆好,写代码也得先把模块导进来:
import { connection } from '@kit.ConnectivityKit';
import { BusinessError } from '@kit.BasicServicesKit';
第二步:开始"买菜"(扫描周边设备)
扫描设备就像在菜市场找特定的菜,得先支个摊(订阅结果),再吆喝(开始扫描),找到菜了就收摊(停止扫描)。
2.1 先支个摊:订阅扫描结果
鸿蒙 API 18+ 支持更详细的设备信息(地址、信号强度、名称、类型),推荐用这个:
// 定义扫描结果上报回调函数
function on扫描结果上报(data: Array<connection.DiscoveryResult>) {
console.info('发现蓝牙设备: ' + JSON.stringify(data)); // 包含设备地址、信号强度等详情
}
try {
// 发起订阅 - 相当于支摊等菜来
connection.on('discoveryResult', on扫描结果上报);
} catch (err) {
console.error('订阅失败: ' + (err as BusinessError).code + ', ' + (err as BusinessError).message);
}
🥦 西兰花小贴士:
如果你的应用要兼容 API 17-,就用 connection.on('bluetoothDeviceFind', ...),不过只能获取到设备地址哦~
2.2 开始吆喝:发起设备扫描
try {
// 先看看是不是已经在扫描了 - 别重复吆喝
let isScanning = connection.isBluetoothDiscovering();
if (!isScanning) {
// 开始扫描 - 相当于吆喝"收菜啦"
connection.startBluetoothDiscovery();
}
} catch (err) {
console.error('扫描失败: ' + (err as BusinessError).code + ', ' + (err as BusinessError).message);
}
🥦 西兰花警告:
扫描默认会持续约12秒自动停止,别以为它会一直扫哦!
2.3 找到菜了:停止扫描
扫描很费电,就像开着煤气灶不做饭一样浪费,找到设备赶紧停止:
try {
// 看看是不是还在扫描
let isScanning = connection.isBluetoothDiscovering();
if (isScanning) {
// 停止扫描 - 相当于收摊
connection.stopBluetoothDiscovery();
}
// 不需要的话就取消订阅
connection.off('discoveryResult', on扫描结果上报);
} catch (err) {
console.error('停止扫描失败: ' + (err as BusinessError).code + ', ' + (err as BusinessError).message);
}
第三步:决定"要不要让人发现"(设置本机扫描模式)
有时候咱们不仅要找别人,也要让别人找到咱们。这就像你在菜市场找菜,也可以举个牌子让卖家找到你~
try {
// 获取当前扫描模式
let currentMode: connection.ScanMode = connection.getBluetoothScanMode();
console.info('当前扫描模式: ' + currentMode);
// 如果不是"可被发现+可被连接"模式,就改成这个
if (currentMode != connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE) {
connection.setBluetoothScanMode(
connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE,
0
);
}
} catch (err) {
console.error('设置扫描模式失败: ' + (err as BusinessError).code + ', ' + (err as BusinessError).message);
}
🥦 西兰花小贴士:
SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE:既可以被发现,也可以被连接(相当于举着牌子喊"我在这!")SCAN_MODE_CONNECTABLE:只能被连接,不能被发现(相当于站在那但没举牌子)
第四步:看看"常去的摊位"(查找已配对设备)
有时候咱们不需要重新找,常买的菜(常用的设备)已经在咱们的"黑名单"里了(开玩笑,是配对列表)。直接去常去的摊位买更方便~
try {
// 获取已配对的设备列表
let pairedDevices = connection.getPairedDevices();
console.info('已配对设备: ' + JSON.stringify(pairedDevices));
// 如果已经知道设备地址,可以直接查配对状态
if (pairedDevices.length > 0) {
let firstDevice = pairedDevices[0];
let pairState = connection.getPairState(firstDevice);
console.info('设备 ' + firstDevice + ' 的配对状态是: ' + pairState);
}
} catch (err) {
console.error('查询配对设备失败: ' + (err as BusinessError).code + ', ' + (err as BusinessError).message);
}
🥦 给你整个"预制菜"(完整工具类)
为了方便大家使用,我把上面的功能封装成了一个工具类,就像超市里的预制菜,拿回去直接炒就行~
import { connection } from '@kit.ConnectivityKit';
import { BusinessError } from '@kit.BasicServicesKit';
export class 设备发现管理器 {
// 扫描结果回调
on扫描结果上报 = (data: Array<connection.DiscoveryResult>) => {
console.info('发现蓝牙设备: ' + JSON.stringify(data));
};
// 开始扫描
public 开始扫描() {
try {
// 先订阅结果
connection.on('discoveryResult', this.on扫描结果上报);
} catch (err) {
console.error('订阅扫描结果失败: ' + (err as BusinessError).code + ', ' + (err as BusinessError).message);
}
try {
// 检查是否正在扫描
let isScanning = connection.isBluetoothDiscovering();
if (!isScanning) {
// 开始扫描
connection.startBluetoothDiscovery();
}
} catch (err) {
console.error('开始扫描失败: ' + (err as BusinessError).code + ', ' + (err as BusinessError).message);
}
}
// 停止扫描
public 停止扫描() {
try {
// 检查是否正在扫描
let isScanning = connection.isBluetoothDiscovering();
if (isScanning) {
// 停止扫描
connection.stopBluetoothDiscovery();
}
// 取消订阅
connection.off('discoveryResult', this.on扫描结果上报);
} catch (err) {
console.error('停止扫描失败: ' + (err as BusinessError).code + ', ' + (err as BusinessError).message);
}
}
// 设置本机为可被发现模式
public 设置为可被发现() {
try {
// 获取当前模式
let currentMode: connection.ScanMode = connection.getBluetoothScanMode();
console.info('当前扫描模式: ' + currentMode);
// 如果不是可被发现模式,就改
if (currentMode != connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE) {
connection.setBluetoothScanMode(
connection.ScanMode.SCAN_MODE_CONNECTABLE_GENERAL_DISCOVERABLE,
0
);
}
} catch (err) {
console.error('设置扫描模式失败: ' + (err as BusinessError).code + ', ' + (err as BusinessError).message);
}
}
// 获取已配对设备
public 获取已配对设备() {
try {
// 获取已配对设备列表
let pairedDevices = connection.getPairedDevices();
console.info('已配对设备: ' + JSON.stringify(pairedDevices));
// 检查第一个设备的配对状态
if (pairedDevices.length > 0) {
let firstDevice = pairedDevices[0];
let pairState = connection.getPairState(firstDevice);
console.info('设备 ' + firstDevice + ' 的配对状态是: ' + pairState);
}
} catch (err) {
console.error('查询配对设备失败: ' + (err as BusinessError).code + ', ' + (err as BusinessError).message);
}
}
}
// 导出实例,方便全局使用
let 设备发现管理器实例 = new 设备发现管理器();
export default 设备发现管理器实例 as 设备发现管理器;
咋用这个工具类呢?
就像炒预制菜一样简单:
import 设备发现管理器 from './DeviceDiscoveryManager';
// 开始扫描周边设备
设备发现管理器.开始扫描();
// 过会儿停止扫描
设备发现管理器.停止扫描();
// 获取已配对设备
设备发现管理器.获取已配对设备();
// 设置本机为可被发现
设备发现管理器.设置为可被发现();
是不是超简单?^^
🥦 最后再啰嗦两句
- 扫描别太久:扫描很费蓝牙资源,找到设备就赶紧停
- 权限别忘要:没权限的话啥都干不了,就像没洗手做饭会被打一样
- API版本要注意:API 18+ 用
discoveryResult,API 17- 用bluetoothDeviceFind - 配对状态要检查:有时候设备虽然在列表里,但可能已经取消配对了
📚 推荐资料
我是盐焗西兰花,
不教理论,只给你能跑的代码和避坑指南。
下期见!🥦
更多推荐




所有评论(0)