扫描蓝牙设备传递至Adapter遇空指针问题及解决方法
解决Bluetooth Device传递到Adapter的空指针问题
我尝试把ScanActivity中发现的Bluetooth Device传递到其他类实现后续功能,但用构造方法传递时出现Bluetooth Device空指针异常。目前ScanActivity通过BroadcastReceiver发现蓝牙设备,将设备名称、地址存入BluetoothDeviceModel后传给RecyclerView的Bluetooth_adapter设置到ViewHolder中,现在需要把完整的BluetoothDevice对象传递到Adapter里。
步骤1:修改BluetoothDeviceModel,添加BluetoothDevice字段
在原有模型中新增字段存储完整的BluetoothDevice对象,确保Adapter能直接获取到设备实例:
public class BluetoothDeviceModel { private String name; private String address; private int imageResource; private BluetoothDevice device; // 新增存储完整设备的字段 // 新增带BluetoothDevice的构造方法 public BluetoothDeviceModel(String name, String address, int imageResource, BluetoothDevice device) { this.name = name; this.address = address; this.imageResource = imageResource; this.device = device; } // 新增设备对象的getter方法 public BluetoothDevice getDevice() { return device; } // 保留原有getter方法 public String getName() { return name; } public String getAddress() { return address; } public int getImageresouce() { return imageResource; } }
步骤2:优化ScanActivity的设备发现逻辑
在BroadcastReceiver中传入完整的BluetoothDevice到模型,同时避免重复创建Adapter(原代码每次发现设备都new Adapter会引发性能问题):
// 在ScanActivity的BroadcastReceiver的onReceive方法中 if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // ... 权限检查和设备信息获取逻辑保持不变 ... // 传入完整的BluetoothDevice到模型 data.add(new BluetoothDeviceModel(deviceName, deviceAddress, logoResourse, device)); // 复用Adapter,仅在首次创建时初始化 if (Adapter == null) { Adapter = new Bluetooth_adapter(data, ScanActivity.this, deviceClickListener); recyclerViewSD.setAdapter(Adapter); } else { Adapter.notifyDataSetChanged(); } }
步骤3:修改Bluetooth_adapter,添加点击回调并获取设备
先定义点击回调接口,再修改Adapter构造方法和绑定逻辑:
// 定义点击回调接口 public interface BluetoothDeviceClickListener { void onDeviceClicked(BluetoothDevice device); } // 修改Adapter类 public class Bluetooth_adapter extends RecyclerView.Adapter<BluetoothViewHolder> { private ArrayList<BluetoothDeviceModel> data; private Context context; private BluetoothDeviceClickListener clickListener; // 带回调的构造方法 public Bluetooth_adapter(ArrayList<BluetoothDeviceModel> data, Context context, BluetoothDeviceClickListener clickListener) { this.data = data; this.context = context; this.clickListener = clickListener; } @NonNull @Override public BluetoothViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View view = inflater.inflate(R.layout.pair_devices, parent, false); return new BluetoothViewHolder(view); } @Override public void onBindViewHolder(@NonNull BluetoothViewHolder holder, int position) { BluetoothDeviceModel deviceModel = data.get(position); BluetoothDevice device = deviceModel.getDevice(); // 获取完整设备对象 // 原有UI绑定逻辑保持不变 String name = deviceModel.getName(); String address = deviceModel.getAddress(); int imgresource = deviceModel.getImageresouce(); holder.dropdownImgPD.setImageResource(imgresource); holder.deviceNamePD.setText(name != null ? name : address); // 设置点击事件,传递设备对象 holder.cardViewPD.setOnClickListener(v -> { if (clickListener != null && device != null) { clickListener.onDeviceClicked(device); } }); } @Override public int getItemCount() { return data.size(); } }
步骤4:在ScanActivity中初始化Adapter并处理回调
在onCreate方法中初始化Adapter,实现点击回调逻辑:
// 在ScanActivity的onCreate方法中,初始化data之后 BluetoothDeviceClickListener deviceClickListener = new BluetoothDeviceClickListener() { @Override public void onDeviceClicked(BluetoothDevice device) { // 这里处理设备点击后的逻辑,比如连接设备 establishConnection(device); } }; // 初始化Adapter Adapter = new Bluetooth_adapter(data, this, deviceClickListener); recyclerViewSD.setAdapter(Adapter);
同时修改ScanActivity的establishConnection方法,接收BluetoothDevice参数:
private void establishConnection(BluetoothDevice device) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.BLUETOOTH_CONNECT}, 1); return; } // 这里编写设备连接逻辑,比如创建BluetoothSocket Log.d(TAG, "准备连接设备: " + device.getName() + " (" + device.getAddress() + ")"); }
内容的提问来源于stack exchange,提问作者joash deoghare
相关产品推荐
相关产品推荐

