Android蓝牙无法进入BroadcastReceiver的问题排查与解决
蓝牙设备搜索BroadcastReceiver不触发及崩溃问题解决
问题现象
按照Android官方蓝牙开发教程实现设备搜索功能时,日志仅能打印"1",无法进入BroadcastReceiver(无"2"日志输出),调整接收器注册方式后问题依旧。
初始实现代码
public class ScanList extends AppCompatActivity { BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); BroadcastReceiver mReceiver; int REQUEST_ENABLE_BT = 1; ArrayAdapter<String> mArrayAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scan_list); if (mBluetoothAdapter != null) { if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, REQUEST_ENABLE_BT ); } startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } } IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(receiver, filter); mBluetoothAdapter.startDiscovery(); Log.i("devi", "1"); // can only print this line } // Create a BroadcastReceiver for ACTION_FOUND. private BroadcastReceiver receiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { Log.i("devi", "2"); String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Discovery has found a device. Get the BluetoothDevice // object and its info from the Intent. BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (ActivityCompat.checkSelfPermission(ScanList.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( ScanList.this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, REQUEST_ENABLE_BT ); } String deviceName = device.getName(); String deviceHardwareAddress = device.getAddress(); // MAC address Log.i("devi", deviceName); Log.i("devi", deviceHardwareAddress); Intent reintent = new Intent(ScanList.this, MainActivity.class); Bundle extras = new Bundle(); extras.putString("name",deviceName); extras.putString("address",deviceHardwareAddress); reintent.putExtras(extras); startActivity(reintent); finish(); } } }; @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(receiver); } }
补充调试情况
在mBluetoothAdapter.startDiscovery();和String deviceName = device.getName();前添加以下权限检查代码后,能够获取到设备,但功能不稳定:扫描未必能进入BroadcastReceiver,且进入时会崩溃,提示“Bluetooth keeps stopping”(Bluetooth为应用名称)。
补充的权限检查代码:
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( MainActivity.this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, 1001 ); }
最终解决方案
问题根源:部分蓝牙设备未设置名称,调用device.getName()会返回null,直接打印或传递null值会引发空指针异常,导致应用崩溃。
修复方式:添加空值判断,处理deviceName为null的情况,示例代码如下:
String deviceName = device.getName(); // 空值判断,避免空指针异常 if (deviceName == null) { deviceName = "未知设备"; } String deviceHardwareAddress = device.getAddress(); // MAC address Log.i("devi", deviceName); Log.i("devi", deviceHardwareAddress);
额外优化建议:
初始BroadcastReceiver不触发的潜在原因是扫描启动时机过早,建议将mBluetoothAdapter.startDiscovery()移至蓝牙开启回调onActivityResult或权限申请回调onRequestPermissionsResult中,确保蓝牙就绪、权限获取完成后再启动扫描。
内容的提问来源于stack exchange,提问作者yolopoi
相关产品推荐
相关产品推荐

