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

调用notifyDataSetChanged()时RecyclerView崩溃问题排查

问题分析与解决方案

崩溃原因1:空指针异常(最直接触发崩溃的原因)

在广播接收器中,你直接获取BluetoothDevice对象但未做非空判断:

BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
final String deviceName = device.getName();

如果intent中没有BluetoothDevice.EXTRA_DEVICE数据,device会返回null,直接调用device.getName()会抛出NullPointerException,导致应用崩溃。

崩溃原因2:权限判断逻辑完全颠倒

在getPairedDevices()方法中,权限判断条件写反:

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
    // 获取配对设备的逻辑
} else {
    return new String[0];
}

这段代码的逻辑是无BLUETOOTH_CONNECT权限时才去获取配对设备,这会直接触发SecurityException——因为获取绑定设备必须持有该权限。

崩溃原因3:缺少Android 12+蓝牙权限

Android 12(API 31)及以上版本,蓝牙扫描需要BLUETOOTH_SCAN权限,蓝牙连接需要BLUETOOTH_CONNECT权限,你的代码仅申请了位置权限,未添加这些必要权限,会引发权限异常。

崩溃原因4:扫描启动时机错误

在onCreate()的else分支中,你申请权限后立刻调用bluetoothAdapter.startDiscovery(),此时用户尚未完成授权,扫描会直接失败,后续可能引发逻辑异常。


修复方案

1. 修复广播接收器空指针问题

在使用BluetoothDevice前先做非空判断,同时避免重复添加设备:

private final BroadcastReceiver receiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        Log.d("Broadcast", "Broadcast called");
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // 先判断device非空
            if (device == null) {
                return;
            }
            final String deviceName = device.getName();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (deviceName != null && !availableDevices.contains(deviceName)) {
                        availableDevices.add(deviceName);
                        adapter2.notifyDataSetChanged();
                    }
                }
            });
        }
    }
};

2. 修正配对设备获取的权限逻辑

将权限判断改为有权限时才获取配对设备:

private String[] getPairedDevices() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) {
        Set<BluetoothDevice> bt = bluetoothAdapter.getBondedDevices();
        String[] pairedDevices = new String[bt.size()];
        int i = 0;
        for(BluetoothDevice d : bt){
            pairedDevices[i] = d.getName();
            i++;
        }
        return pairedDevices;
    } else {
        return new String[0];
    }
}

3. 添加Android 12+蓝牙权限

在AndroidManifest.xml中补充权限:

<!-- Android 12+ 蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- 旧版本扫描所需位置权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" android:maxSdkVersion="30" />

4. 修复扫描启动时机,添加权限回调

重写onRequestPermissionsResult方法,在用户授权后再启动扫描:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_BLUETOOTH_PERMISSION) {
        boolean allGranted = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                allGranted = false;
                break;
            }
        }
        if (allGranted && bluetoothAdapter.isEnabled()) {
            bluetoothAdapter.startDiscovery();
            Toast.makeText(this, "Discovering", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "需要权限才能扫描蓝牙设备", Toast.LENGTH_SHORT).show();
        }
    }
}

同时修改onCreate()的else分支,移除提前启动扫描的代码:

else {
    requestPermissions(new String[]{
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.BLUETOOTH_SCAN,
            Manifest.permission.BLUETOOTH_CONNECT
    }, REQUEST_BLUETOOTH_PERMISSION);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:55:15