You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android BLE开发:为何无法扫描到开启蓝牙的周边手机设备

为什么你的Android BLE扫描不到其他开启蓝牙的手机?

嘿,这个问题我之前帮不少开发者排查过,核心点其实在于你对BLE工作模式的理解有个小误区,咱们一步步拆解:

1. 目标手机根本没在发BLE广播

大多数手机开启系统蓝牙开关后,只是启用了经典蓝牙(用来配对耳机、传文件那种)和BLE的基础功能,但不会主动以BLE外围设备(Peripheral)的身份广播自身存在。而你的App作为BLE中央设备(Central),只能扫到正在主动发送BLE广播包的设备——这就好比你在房间里喊“谁在这”,只有回应你的人你才能找到,那些没出声的你自然听不到。

验证这个很简单:找一台目标手机,装个BLE外围设备测试工具(比如Google官方的BLE Peripheral Simulator),打开广播后再用你的扫描App试,肯定能扫到。

2. 你的扫描代码可能加了过严的过滤条件

检查下你调用startScan的代码,是不是传入了特定的服务UUID过滤器?比如:

List<ScanFilter> filters = new ArrayList<>();
ScanFilter filter = new ScanFilter.Builder()
    .setServiceUuid(ParcelUuid.fromString("你的UUID"))
    .build();
filters.add(filter);
bluetoothLeScanner.startScan(filters, scanSettings, scanCallback);

如果是这样,只有广播了这个UUID的设备才会被扫到,而普通手机根本不会广播这个,自然就被过滤掉了。

解决办法:暂时去掉过滤器,直接调用startScan(scanCallback)或者传空的过滤器列表,这样就能扫到所有正在广播的BLE设备了。

3. 权限没配全(Android 12+尤其要注意)

从Android 12(API 31)开始,BLE扫描的权限要求变严了:

  • 必须申请BLUETOOTH_SCAN权限,如果不需要关联定位,还要加上neverForLocation标记
  • 后台扫描的话还需要ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION权限,而且要在代码里请求运行时权限

先检查你的Manifest里有没有加这些权限:

<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

另外,别忘了在代码里动态请求这些权限,不然系统会直接拒绝扫描请求。

4. 设备的系统/硬件限制

个别定制ROM(比如某些国产手机的系统)会有省电策略,默认禁用后台BLE操作;或者蓝牙模块存在小bug,导致广播/扫描功能异常。

你可以试试:

  • 关闭目标手机的省电模式,再测试扫描
  • 开启开发者选项,检查“蓝牙HCI snoop日志”是否能正常开启,排除硬件层面的问题

最后再澄清你的疑问:BLE支持发现周边设备吗?

BLE本身是支持设备发现的,但有个核心前提:被发现的设备必须处于BLE广播状态。普通手机默认不会发BLE广播,所以你的扫描App找不到它们是正常的。

如果你的需求是发现所有开启蓝牙的手机(不管经典蓝牙还是BLE),那BLE方案并不适合,你得用经典蓝牙的设备发现(比如BluetoothAdapter.startDiscovery()),但要注意:经典蓝牙发现速度慢、功耗高,而且现在很多设备默认隐藏了经典蓝牙的可发现性,用户得手动开启“可被发现”模式才行。

内容的提问来源于stack exchange,提问作者CHAMI

火山引擎 最新活动