Android 10无法扫描到Nordic 52840周期性广播设备求助
问题分析
你的代码使用的是经典蓝牙(BR/EDR)的扫描机制(BluetoothAdapter.startDiscovery()),但Nordic nRF52840运行的是BLE周期性广播,属于低功耗蓝牙(BLE)范畴,经典蓝牙扫描无法捕获BLE广播包,这是找不到目标设备的核心原因。
解决步骤
1. 改用BLE专属扫描API
替换原有的扫描逻辑,使用BluetoothLeScanner执行BLE扫描:
首先在onCreate中正确初始化BLE相关实例:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lvNewDevice=(ListView)findViewById(R.id.lvNewDevice); mBTdevice=new ArrayList<>(); mHandler = new Handler(); // 通过BluetoothManager获取BLE适配器 BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); if (mBluetoothAdapter != null) { mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); } // 按钮初始化逻辑保留... }
然后实现BLE扫描回调并改写扫描方法:
// BLE扫描回调,处理扫描结果 private final ScanCallback mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); BluetoothDevice device = result.getDevice(); // 避免重复添加设备 if (!mBTdevice.contains(device)) { mBTdevice.add(device); String deviceName = device.getName() != null ? device.getName() : "未知BLE设备"; Log.d(TAG, "发现设备: " + deviceName + " | " + device.getAddress()); // 更新列表显示 mDeviceListAdapter = new DeviceListAdapter(MainActivity.this, R.layout.device_adapter_view, mBTdevice); lvNewDevice.setAdapter(mDeviceListAdapter); } } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); Log.e(TAG, "扫描失败,错误码: " + errorCode); Toast.makeText(MainActivity.this, "BLE扫描失败", Toast.LENGTH_SHORT).show(); } }; // 重写扫描方法 public void scanBTDevice(){ Log.d(TAG, "切换BLE扫描状态"); if (mScanning) { // 停止扫描 mBluetoothLeScanner.stopScan(mScanCallback); mScanning = false; Log.d(TAG, "已停止扫描"); } else { checkBTPermission(); // 配置扫描参数,低延迟模式适合前台快速扫描 ScanSettings scanSettings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .build(); // 开始扫描,null表示不过滤设备,可添加ScanFilter指定目标设备 mBluetoothLeScanner.startScan(null, scanSettings, mScanCallback); mScanning = true; Log.d(TAG, "已启动BLE扫描"); // 可选:设置10秒自动停止扫描,避免持续占用资源 mHandler.postDelayed(() -> { if (mScanning) { mBluetoothLeScanner.stopScan(mScanCallback); mScanning = false; Log.d(TAG, "扫描超时自动停止"); } }, 10000); } }
2. 完善权限配置
在AndroidManifest.xml中添加BLE扫描必需的权限:
<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="true" />
Android 10中,ACCESS_FINE_LOCATION是BLE扫描的强制权限,必须申请并获得用户授权。
3. 确认Nordic设备配置
- 先用nRF Connect官方APP扫描Nordic设备,确认设备的周期性广播正常开启且可被检测到
- 检查设备广播包是否包含可识别的字段(比如设备名称、服务UUID),避免广播包仅包含无法被Android扫描识别的私有数据
4. 清理冗余代码
移除原有的经典蓝牙扫描相关逻辑:
- 删除
mBroadcastreceiver3及其注册代码 - 去掉
startDiscovery()、cancelDiscovery()相关调用,避免与BLE扫描冲突
额外提示
- 确保APP处于前台状态,Android对后台BLE扫描有严格限制
- 如果需要解析周期性广播的具体数据,可在
onScanResult中通过result.getScanRecord().getBytes()获取广播原始字节流进行解析
内容的提问来源于stack exchange,提问作者JayLin1119
相关产品推荐
相关产品推荐

