Android 6.0及以上版本无法扫描BLE设备的技术求助
Hey there, let's tackle this BLE scanning issue on Android 6.0! The root cause here is almost always tied to runtime permissions—a key change introduced in Android 6.0 (API 23) that didn't affect your Android 5.1.1 device. Let's break down the fix step by step.
1. Understand the Core Problem
Android 6.0 shifted from install-time permission grants to runtime requests for "dangerous" permissions. BLE scanning relies on location permissions (ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION) because BLE beacons can be used to infer a user's physical location. Your Samsung J3 (5.1.1) works because it uses the old permission model where permissions are granted upfront during installation.
2. Verify Gradle & Manifest Setup
First, confirm your configuration includes the necessary declarations and SDK targets:
Module-level build.gradle Snippet
Ensure your target SDK version is aligned with modern practices (runtime permissions are enforced if targetSdkVersion >= 23):
android { compileSdkVersion 33 defaultConfig { applicationId "com.your.ble.app" minSdkVersion 21 targetSdkVersion 33 versionCode 1 versionName "1.0" } }
Required AndroidManifest.xml Permissions
Even with runtime permissions, you must declare these in your manifest:
<!-- BLE core permissions --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- Location permissions for BLE scanning --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Declare app requires BLE hardware --> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
3. Fix Your Scanning Activity
You need to add runtime permission checks before initiating any BLE scan. Here's how to modify your activity:
Step 1: Define Constants & Variables
Add these to your activity class:
private static final int REQUEST_LOCATION_PERMISSION = 100; private BluetoothLeScanner bleScanner; private BluetoothAdapter bluetoothAdapter;
Step 2: Check Permissions Before Scanning
Add logic to request permissions if they're not already granted before starting the scan:
private void startBleScan() { // First, ensure Bluetooth is enabled if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, 1); return; } // Check if location permission is granted if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request permission from the user ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATION_PERMISSION); return; } // Permission granted—start scanning bleScanner = bluetoothAdapter.getBluetoothLeScanner(); bleScanner.startScan(scanCallback); }
Step 3: Handle Permission Request Results
Override the callback to resume scanning once permission is granted:
@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 approved—start scanning startBleScan(); } else { // Permission denied—notify the user Toast.makeText(this, "Location permission is required to scan BLE devices", Toast.LENGTH_SHORT).show(); } } }
Step 4: (Optional) Check Location Services
Some Android 6.0 devices require Location Services to be enabled for BLE scanning. Add this check if you encounter further issues:
private boolean isLocationEnabled() { LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); }
Call this in startBleScan() and prompt the user to enable location services if it's disabled.
4. Quick Best Practices
- Always stop BLE scans when they're no longer needed (e.g., in
onPause()oronDestroy()) to save battery. - If your
targetSdkVersionis below 23, Android 6.0 will auto-grant permissions at install time, but adding runtime handling ensures future compatibility.
内容的提问来源于stack exchange,提问作者bircastri

