蓝牙设备发现和自定义列表适配器

Bluetooth devices discovery and custom list adapter

我正在尝试检索可见蓝牙设备的列表,并使用自定义适配器将收集到的信息传递给 ListView。 我的功能中唯一有问题的部分是将发现的项目(设备)添加到 ListView,在测试不同的方法时,ListView 根本没有填充,项目被覆盖或项目在 ListView.

我当前的函数根本不填充 ListView:

public void startDevicesDiscovery(){

    rowItemsDevices.clear();
    devicesAdapter =new DevicesListAdapter(tContext, rowItemsDevices);

    //cancel discovery if discovering
    if (mBluetoothAdapter.isDiscovering()){
        mBluetoothAdapter.cancelDiscovery();
    }
    general.log("BT","start list size: "+rowItemsDevices.size());
    bluetoothReceiver = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            General general = new General(tContext);
            String action = intent.getAction();

            // if device found
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {

                btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                if(btDevice == null){
                    general.log("BT","device NULL");
                }else{

                    Device device = new Device(btDevice.getName(),btDevice.getAddress());

                    general.log("BT","device: "+device.getDeviceName()+"\ndevice MAC: "+device.getMacAddress());

                    RowItemDevices items = new RowItemDevices(device.getDeviceName(),device.getMacAddress());
                    rowItemsDevices.add(items);
                    devicesAdapter.notifyDataSetChanged();
                }

            }else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                general.log("BT","device search finished");
                general.log("BT","end list size: "+rowItemsDevices.size());
            }

        }
    };

    visibleDevices.setAdapter(devicesAdapter);

    IntentFilter filter = new IntentFilter();
    filter.addAction(BluetoothDevice.ACTION_FOUND);
    filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    registerReceiver(bluetoothReceiver, filter);

    mBluetoothAdapter.startDiscovery();

}

日志显示已正确发现设备:

为了排除问题的原因是我的自定义 ListView 适配器本身,我创建了一个测试函数来证明向我的 ListView 添加元素可以正常工作:

public void testListView(){
    general.log("BT","testListView");
    rowItemsDevices.clear();
    devicesAdapter =new DevicesListAdapter(tContext, rowItemsDevices);
    RowItemDevices items = new RowItemDevices("test 1","test sub 1");
    rowItemsDevices.add(items);
    RowItemDevices items2 = new RowItemDevices("test 2","test sub 2");
    rowItemsDevices.add(items2
    );
    visibleDevices.setAdapter(devicesAdapter);
}

知道这里出了什么问题吗?函数 startDevicesDiscovery 看起来像预期的那样工作,但也许我实现它的方式不正确?

编辑:

在我的适配器上添加 devicesAdapter.notifyDataSetChanged() 后,列表在第一个 运行 上显示正确的值,但如果我再次 运行 该函数,项目就会重复,因此我一开始遇到的同样问题。通过查看日志,我可以看出问题是由 BroadcastReceiver 引起的,出于某种原因,在第二次搜索时,将之前发现的设备添加到新搜索中。如何解决?

  1. 要让 ListView 显示添加的项目,您必须告诉 ListVIew 列表中的某些内容已更新:在 rowItemsDevices.add(items); 之后添加 yourAdapter.notifyDataSetChanged()。没有它ListView 更新会知道他已经有一些物品要画了。
  2. 项目现在是重复的,因为您注册了新的 BroadcastReceiver,并且没有注销旧的。如果您第 3 次尝试 运行 您的方法,您将得到 3 个重复项。所以你必须在扫描完成后注销接收器:

    else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
        general.log("BT","device search finished");
        general.log("BT","end list size: "+rowItemsDevices.size());
        unregisterReceiver(this); //add this line
    }