Android Java蓝牙周边设备扫描无结果问题求助(附代码)
Android 蓝牙设备扫描无结果排查与修复方案(Java)
常见问题根源
- 权限适配不全:Android 12+ 新增了
BLUETOOTH_SCAN、BLUETOOTH_CONNECT等细分权限,仅在Manifest声明不够,必须动态申请;Android 10及以下扫描蓝牙仍需位置权限(ACCESS_FINE_LOCATION),需确保用户已授予。 - 蓝牙状态未正确校验:必须主动检查蓝牙是否开启,不能依赖系统设置,需通过
ACTION_REQUEST_ENABLE请求用户授权开启,而非直接操作。 - 扫描API版本不匹配:旧教程常用的
startDiscovery()仅适用于经典蓝牙,若扫描BLE设备需使用BluetoothLeScanner.startScan();两类设备的扫描API不通用,需区分场景。 - 回调未正确注册:BLE扫描的
ScanCallback需正确传入扫描方法,经典蓝牙的BroadcastReceiver需注册ACTION_FOUND过滤器,且不能遗漏注册步骤。 - 后台扫描限制:Android 12+ 对后台扫描频率有严格限制,测试时需保持App在前台运行。
适配Android 12+的BLE扫描代码示例
Manifest权限声明
<!-- 旧版本兼容权限 --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <!-- Android 12+ 蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- Android 10及以下位置权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="29" /> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
Java核心代码
import android.Manifest; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothManager; import android.bluetooth.le.BluetoothLeScanner; import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanResult; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; import androidx.appcompat.app.AppCompatActivity; import java.util.ArrayList; public class BluetoothScanActivity extends AppCompatActivity { private BluetoothLeScanner bleScanner; private ListView deviceListView; private ArrayList<String> deviceData = new ArrayList<>(); private ArrayAdapter<String> listAdapter; // BLE扫描回调 private final ScanCallback bleScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); String deviceInfo = String.format("%s | %s", result.getDevice().getName() == null ? "未知设备" : result.getDevice().getName(), result.getDevice().getAddress()); if (!deviceData.contains(deviceInfo)) { deviceData.add(deviceInfo); listAdapter.notifyDataSetChanged(); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); deviceListView = findViewById(R.id.device_list); listAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, deviceData); deviceListView.setAdapter(listAdapter); // 初始化蓝牙管理器 BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE); BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter(); // 检查蓝牙支持与开启状态 if (bluetoothAdapter == null) { // 设备不支持蓝牙 finish(); return; } if (!bluetoothAdapter.isEnabled()) { startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), 100); return; } bleScanner = bluetoothAdapter.getBluetoothLeScanner(); checkPermissionsAndStartScan(); } private void checkPermissionsAndStartScan() { if (checkSelfPermission(Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.BLUETOOTH_SCAN}, 200); return; } bleScanner.startScan(bleScanCallback); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 200 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { bleScanner.startScan(bleScanCallback); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 100 && resultCode == RESULT_OK) { checkPermissionsAndStartScan(); } } @Override protected void onDestroy() { super.onDestroy(); if (bleScanner != null) { bleScanner.stopScan(bleScanCallback); } } }
经典蓝牙扫描补充
若需扫描经典蓝牙设备,替换扫描逻辑为:
// 初始化广播接收器 private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); String deviceInfo = device.getName() + " | " + device.getAddress(); if (!deviceData.contains(deviceInfo)) { deviceData.add(deviceInfo); listAdapter.notifyDataSetChanged(); } } } }; // 注册广播与开始扫描 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(bluetoothReceiver, filter); bluetoothAdapter.startDiscovery(); // 销毁时注销广播 @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(bluetoothReceiver); bluetoothAdapter.cancelDiscovery(); }
测试注意事项
- 使用真实设备测试,模拟器蓝牙功能不稳定;
- 保持App在前台,避免后台扫描被系统限制;
- 确保待扫描设备处于可被发现状态。
内容的提问来源于stack exchange,提问作者lastminuter025
相关产品推荐
相关产品推荐

