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

Android蓝牙设备搜索异常:BroadcastReceiver无法正常工作

Hey there, let's figure out why your Bluetooth device discovery isn't working. Looking at your code and logs, the main issue here is missing runtime location permissions (critical for Android 6.0+) plus a couple of small code tweaks. Let's break down the fixes step by step:

1. Remove the Unprivileged Permission

First, delete <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" /> from your AndroidManifest.xml. This permission is only available to system apps, and including it won't help your regular app—it might even cause unexpected behavior.

2. Request Location Permissions at Runtime

Starting with Android 6.0 (API 23), apps need to request ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION at runtime to scan for Bluetooth devices. Your manifest has the static permissions, but you're not asking the user to grant them.

Add this code to handle runtime permissions:

private static final int REQUEST_LOCATION_PERMISSION = 100;

// Call this before starting discovery
private boolean checkLocationPermissions() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                REQUEST_LOCATION_PERMISSION);
        return false;
    }
    return true;
}

// Handle permission request result
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_LOCATION_PERMISSION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission granted, start discovery
            DiscoverDevice();
        } else {
            Toast.makeText(this, "Location permission is required for Bluetooth scanning", Toast.LENGTH_SHORT).show();
        }
    }
}

Then update your DiscoverDevice() method to check permissions first:

public void DiscoverDevice(){
    if (!checkLocationPermissions()) {
        return; // Wait for permission grant
    }
    Log.d("MainActivity", "RUNNING-1");
    if (bluetoothAdapter.isDiscovering()){
        Log.d("MainActivity", "RUNNING-2");
        bluetoothAdapter.cancelDiscovery();
    }
    // Register receiver BEFORE starting discovery
    IntentFilter discoverDevicesIntent = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    registerReceiver(mBroadcastReceiver, discoverDevicesIntent);
    bluetoothAdapter.startDiscovery();
    Log.d("MainActivity", "RUNNING-3 (Discovery started)");
}

3. Fix BroadcastReceiver Registration & Memory Leaks

Right now you're registering the receiver every time you start discovery, which can lead to multiple registrations. Instead, register it in onResume() and unregister in onPause() to avoid leaks and ensure it's active when needed:

@Override
protected void onResume() {
    super.onResume();
    IntentFilter discoverDevicesIntent = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    registerReceiver(mBroadcastReceiver, discoverDevicesIntent);
}

@Override
protected void onPause() {
    super.onPause();
    try {
        unregisterReceiver(mBroadcastReceiver);
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    }
}

4. Fix the Null Pointer Exception for mBluetooth

In your onCreate() method, you're calling mBluetooth.setOnClickListener() without initializing it with findViewById. Add this line after setContentView():

mBluetooth = (Switch) findViewById(R.id.mBluetooth); // Replace with your actual Switch ID

5. Additional Checks

  • Make sure the Bluetooth device you're trying to discover is set to discoverable mode (most devices don't broadcast by default).
  • Verify that your phone's Bluetooth is enabled before starting the scan.
  • Double-check that your DeviceListAdapter is correctly implemented (though the main issue here is the permission and receiver timing).

After making these changes, run your app again—you should see the RUNNING-6 log and devices appearing in your list once permissions are granted and discovery starts.

内容的提问来源于stack exchange,提问作者Kacper Żołądziejewski

火山引擎 最新活动