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

Android低功耗蓝牙(BLE)扫描异常求助:仅获取随机地址且设备名称为null

Fixing Your Android BLE Scanning Issues

Hey there, let's tackle those BLE scanning problems you're facing. I'll break down each issue and give you actionable fixes based on your code and common BLE pitfalls.

Issues Recap

  • You're only seeing random Bluetooth addresses, and device.getName() returns null.
  • Your app only detects devices when another phone is running BLE advertising (via the BLE Scanner app).

Breakdown & Fixes

1. Random Addresses & Null Device Names

BLE devices commonly use random addresses (for privacy reasons) alongside public addresses—this isn't necessarily a bug. The null device name usually happens because:

  • The device isn't broadcasting its name in the advertising packet, or
  • The Android Bluetooth stack hasn't resolved the name yet (it may take multiple scan results).

Fix Steps:

  • Check Address Type: Use device.getType() to confirm if it's a random address (BluetoothDevice.DEVICE_TYPE_LE_RANDOM) or public. Random addresses are normal for many modern BLE devices.
  • Parse Scan Record Manually: If device.getName() is null, extract the name directly from the ScanResult's scan record. Add this logic to your onScanResult:
    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        super.onScanResult(callbackType, result);
        BluetoothDevice device = result.getDevice();
        String deviceName = device.getName();
        
        // Fallback to parsing scan record if name is missing
        if (deviceName == null) {
            ScanRecord scanRecord = result.getScanRecord();
            if (scanRecord != null) {
                deviceName = scanRecord.getDeviceName();
            }
        }
        
        String address = device.getAddress();
        int rssi = result.getRssi();
        Toast.makeText(BluetoothActivity.this, 
            String.format("%s | %s | RSSI: %d", address, deviceName != null ? deviceName : "Unknown", rssi), 
            Toast.LENGTH_SHORT).show();
    }
    
  • Verify Permissions: For Android 6.0+, you need ACCESS_FINE_LOCATION (requested at runtime). For Android 12+, add BLUETOOTH_SCAN and BLUETOOTH_CONNECT permissions to your manifest and request them at runtime. Missing permissions can restrict scanning or return incomplete data.

2. Scanning Only Works When Another Phone Advertises

This is likely tied to your scan settings or device-specific scanning behavior. Here's what to adjust:

  • Scan Mode: You're using SCAN_MODE_LOW_POWER, which is optimized for background use (low battery but limited sensitivity). For foreground scanning, switch to SCAN_MODE_LOW_LATENCY to get more frequent results:
    ScanSettings scanSettings = new ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // Update this line
            .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
            .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
            .setReportDelay(0)
            .build();
    
  • Location Services: Android requires Location Services to be enabled for BLE scanning (even if you don't use location data). Make sure it's turned on in the device settings.
  • Test with More Devices: Try scanning other BLE hardware (smartwatches, headphones, beacons) to rule out issues with your test device's advertising behavior. The BLE Scanner app might send a stronger/frequent advertisement that triggers your phone's scan module to detect other devices.

Additional Code Improvements

  • Reuse ScanCallback: Creating a new ScanCallback every time you call scanBLEDevices can lead to reference leaks or mismatched stop/start calls. Move it to a class-level variable instead.
  • Enhance Error Handling: In onScanFailed, map error codes to readable messages to diagnose issues faster:
    @Override
    public void onScanFailed(int errorCode) {
        super.onScanFailed(errorCode);
        String errorMsg = switch (errorCode) {
            case ScanCallback.SCAN_FAILED_ALREADY_STARTED -> "Scan already running";
            case ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED -> "BLE scan not supported on this device";
            case ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES -> "Insufficient hardware resources";
            case ScanCallback.SCAN_FAILED_INTERNAL_ERROR -> "Internal scan error";
            default -> "Unknown scan error: " + errorCode;
        };
        Toast.makeText(BluetoothActivity.this, "Scan failed: " + errorMsg, Toast.LENGTH_SHORT).show();
    }
    

Example Updated Code

Here's how your refined scan setup might look:

// Class-level variables
private ScanCallback scanCallback;
private Handler handler = new Handler(Looper.getMainLooper());

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Initialize scan callback once
    scanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            BluetoothDevice device = result.getDevice();
            String deviceName = device.getName();
            
            if (deviceName == null) {
                ScanRecord scanRecord = result.getScanRecord();
                if (scanRecord != null) {
                    deviceName = scanRecord.getDeviceName();
                }
            }
            
            String address = device.getAddress();
            int rssi = result.getRssi();
            Toast.makeText(BluetoothActivity.this, 
                String.format("%s | %s | RSSI: %d", address, deviceName != null ? deviceName : "Unknown", rssi), 
                Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);
            Toast.makeText(BluetoothActivity.this, "Batch scan results received", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            String errorMsg = switch (errorCode) {
                case ScanCallback.SCAN_FAILED_ALREADY_STARTED -> "Scan already running";
                case ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED -> "BLE scan not supported on this device";
                case ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES -> "Insufficient hardware resources";
                case ScanCallback.SCAN_FAILED_INTERNAL_ERROR -> "Internal scan error";
                default -> "Unknown scan error: " + errorCode;
            };
            Toast.makeText(BluetoothActivity.this, "Scan failed: " + errorMsg, Toast.LENGTH_SHORT).show();
        }
    };
}

public void scanBLEDevices(boolean enable) {
    if (bleScanner == null) {
        Toast.makeText(BluetoothActivity.this, "Couldn't get Scanner object", Toast.LENGTH_SHORT).show();
        return;
    }

    if (enable) {
        ScanSettings scanSettings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
                .setReportDelay(0)
                .build();

        bleScanner.startScan(null, scanSettings, scanCallback);
        Toast.makeText(BluetoothActivity.this, "Scan Started!", Toast.LENGTH_SHORT).show();

        handler.postDelayed(() -> {
            bleScanner.stopScan(scanCallback);
            Toast.makeText(BluetoothActivity.this, "Scan stopped automatically", Toast.LENGTH_SHORT).show();
        }, 30000);
    } else {
        try {
            bleScanner.stopScan(scanCallback);
            Toast.makeText(BluetoothActivity.this, "Scan stopped!", Toast.LENGTH_SHORT).show();
        } catch (IllegalStateException e) {
            Toast.makeText(BluetoothActivity.this, "Error stopping scan: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
}

Give these changes a try, and test on multiple devices to rule out device-specific quirks. Let me know if you still hit snags!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 21:19:07