Android BLE 蓝牙查找

蓝牙,想必大家都不陌生,它是一种无线通讯技术标准,用于短距离间交换数据。

蓝牙主要分为经典蓝牙和低功耗蓝牙,蓝牙 3.0 以下版本称为经典蓝牙,功耗高,传输数据量大,有效距离 10 米左右,蓝牙 4.0 及以上为低功耗蓝牙,简称 BLE 蓝牙,功耗低,传输数据量相对较小,有效距离 50 米左右。因为现在的蓝牙基本上都是 5.0+ 了,所以这里主要讲解 BLE 蓝牙的开发。Android 4.3 为蓝牙低功耗引入内置平台支持,并提供了相应的 API 。

蓝牙权限

xml 复制代码
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

其中 ACCESS_COARSE_LOCATION 和 ACCESS_FINE_LOCATION 属于危险权限,需要动态申请,这里不再赘述。位置是必须的权限,否则是扫描不出结果的。

启用蓝牙

首先需要获取 BluetoothAdapter,它是设备的蓝牙适配器,系统只有一个蓝牙适配器,我们需要使用此对象进行交互。

kotlin 复制代码
private val bluetoothAdapter: BluetoothAdapter? by lazy(LazyThreadSafetyMode.NONE) {
    val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    bluetoothManager.adapter
}

启用蓝牙时,需先判断一下蓝牙是否已经启用,如果没有的话则启用它。需要注意的是,这里使用的 registerForActivityResult 要写在 onCreate 方法里,不然会报错。

kotlin 复制代码
val bluetoothLauncher =
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        if (it.resultCode == Activity.RESULT_OK) {
            // TODO: Bluetooth enabled successfully
        }
    }

bluetoothAdapter?.takeUnless { it.isEnabled }?.let {
    val intent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
    bluetoothLauncher.launch(intent)
}

查找设备

因为蓝牙扫描比较耗电,所以应遵循以下准则:

  • 找到所需设备后,立即停止扫描。
  • 绝对不进行循环扫描,并设置扫描时间限制。之前可用的设备可能已超出范围,继续扫描会耗尽电池电量。
kotlin 复制代码
lifecycleScope.launch(Dispatchers.IO) {
    // 开启扫描
    bluetoothAdapter?.bluetoothLeScanner?.startScan(scanCallback)
    // 扫描时间限制
    delay(10000)
    // 停止扫描
    bluetoothAdapter?.bluetoothLeScanner?.stopScan(scanCallback)
}

这里会接收一个 ScanCallback 回调

kotlin 复制代码
private val scanCallback = object : ScanCallback() {

    // 当扫描到蓝牙设备时,这个方法会被调用。其中 callbackType 参数表示扫描类型,result 参数表示扫描到的设备信息。
    override fun onScanResult(callbackType: Int, result: ScanResult?) {
        if (result != null) {
            val device = result.device
            Log.i(TAG, "device.name:${device?.name}, address:${device.address}")
        }
    }

    // 当批量扫描到多个蓝牙设备时,这个方法会被调用。其中 results 参数表示扫描到的设备列表。
    override fun onBatchScanResults(results: MutableList<ScanResult>?) {
        Log.i(TAG, "results size: ${results?.size}")
    }

    // 当蓝牙扫描失败时,这个方法会被调用。其中 errorCode 参数表示扫描失败类型。
    override fun onScanFailed(errorCode: Int) {
        Log.i(TAG, "onScanFailed: $errorCode")
    }
    
}

在一般情况下,BLE 蓝牙只能扫描到支持 BLE 协议的设备,而不能直接扫描到传统蓝牙设备。某些设备具有双模功能,既支持传统蓝牙也支持 BLE,这样的设备可以通过 BLE 来进行扫描,并且可以同时扫描到支持 BLE 和传统蓝牙的设备。

相关推荐
jiang_bluetooth11 小时前
Simple fast pair design
蓝牙·gfps·fast pair·蓝牙快连·蓝牙架构设计
Lenzetech3 天前
科技资讯|谷歌Play应用商店有望支持 XR 头显,AR / VR设备有望得到发展
科技·物联网·ar·xr·蓝牙·find my
Lenzetech5 天前
蓝牙资讯|苹果AirPods Pro 2推出听力测试、助听器和听力保护等功能
科技·物联网·蓝牙·find my
Marko_Chai8 天前
Android BLE 杂谈
android·蓝牙
Lenzetech14 天前
Find My平板键盘|苹果Find My技术与键盘结合,智能防丢,全球定位
科技·物联网·蓝牙·find my
Lenzetech15 天前
蓝牙资讯|iOS 18.1 正式版下周推送,AirPods Pro 2耳机将带来助听器功能
科技·物联网·蓝牙·find my
jiang_bluetooth21 天前
结合空口分析BLE AUDIO之PAC
嵌入式硬件·信息与通信·蓝牙·智能硬件·蓝牙5.2·ble audio
jiang_bluetooth1 个月前
分享蓝牙耳机A2DP音频卡顿原因及解决思路
嵌入式硬件·音视频·信息与通信·蓝牙·智能硬件·a2dp
Lenzetech1 个月前
蓝牙技术|国产手机厂商推出蓝牙的公里级无网通信技术,可实现1500米无网通话
科技·物联网·蓝牙·find my
Android技术栈1 个月前
鸿蒙开发(NEXT/API 12)【蓝牙服务开发】网络篇
网络·华为·蓝牙·harmonyos·鸿蒙·鸿蒙系统·openharmony