You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 11:36:13