Android Listview显示重新扫描的蓝牙设备的重复条目

Android Listview显示重新扫描的蓝牙设备的重复条目,android,listview,bluetooth,Android,Listview,Bluetooth,我有一个应用程序,它在按钮(切换按钮)上按扫描并在自定义列表视图中显示发现的蓝牙设备,再次按同一按钮时,扫描停止 btOnOff.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if(btOnOff.isChecke

我有一个应用程序,它在按钮(切换按钮)上按扫描并在自定义列表视图中显示发现的蓝牙设备,再次按同一按钮时,扫描停止

        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });
现在,当我再次按下按钮(第二次)开始扫描时,问题出现了,相同的设备显示了两次。在我停止并开始扫描(第三次)后,相同的设备显示三次。发现的设备从未与我的android手机配对

        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });
有一个类似的问题,但答案对我没有帮助。请告诉我哪里出了问题

        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });
下面是代码

        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });
我还有两个类可以定制listview,有什么可以避免重复的条目吗。下面是第一类文件的代码

        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });
 public class CustomAdapter extends ArrayAdapter<Custom>{

private ArrayList<Custom> entries;
private Activity activity;

public CustomAdapter(Activity a, int textViewResourceId, ArrayList<Custom> entries) {
    super(a, textViewResourceId, entries);
    // TODO Auto-generated constructor stub
    this.entries = entries;
    this.activity = a;
}

public static class ViewHolder{
    public TextView tv1;
    public TextView tv2;
}

@Override
public View getView(int position, View convertView, ViewGroup parent){
    View v = convertView;
    ViewHolder holder;
    if(v == null){
        LayoutInflater vi = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.show_devices, null);
        holder = new ViewHolder();
        holder.tv1 = (TextView) v.findViewById(R.id.tv1);
        holder.tv2 = (TextView) v.findViewById(R.id.tv2);

        v.setTag(holder);
    }else{
        holder = (ViewHolder)v.getTag();
    }

    final Custom custom = entries.get(position);
    if(custom != null){
        holder.tv1.setText(custom.getFirst());
        holder.tv2.setText(custom.getSecond());
    }
    return v;
}
 public class Custom {
private String text1;
private String text2;

public Custom(String string1, String string2){
    this.text1 = string1;
    this.text2 = string2;
}

public String getFirst(){
    return text1;
}

public void setFirst(String text1){
    this.text1 = text1;
}

public String getSecond(){
    return text2;
}

public void setSecond(String text2){
    this.text2 = text2;
}
 }

开始重新扫描时,请清除列表中的“获取”项。。基本上,每次扫描时,您都会将蓝牙搜索设备添加到以前的列表中。

使用上面使用的逻辑自定义listview会创建冗余,并创建重复条目。因此,我们可以使用带有简单列表项1的ArrayAdapter,而不是使用另外两个类编写自定义listview

        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });
在按钮onclick事件中,ArrayAdapter对象将清除重复的条目,简单列表项将提供两行listview,类似于自定义listview

        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });

简单的实现是show

如果您无法使用默认的listview适配器,比如您想在dialogfragment或类似的东西中显示设备,下面是我不太优雅的解决方案,以避免在重新扫描相同设备时出现重复的设备:

        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        // When discovery finds a device

        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // Get the BluetoothDevice object from the Intent
            device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            if(count ==0){
              prev_device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
              mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
              mArrayAdapter.notifyDataSetChanged();
            }
            Log.d("BLUETOOTH","count = "+count);
            if(!device.getAddress().contains(prev_device.getAddress())){
                Log.d("BLUETOOTH","NOT A MATCH - ADD TO LIST");
            // Add the name and address to an array adapter to show in a ListView
                mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                mArrayAdapter.notifyDataSetChanged();
            }

            prev_device = device;

            if(count ==0){
                showDevices(); //Simply displays a dialogFragment with listview of devices
            }
            count++;
        }
    }
};

基本上,您可以检查设备之前是否被扫描过。但是,这只在只有一个设备(对于我的应用程序)的情况下才有效,但是如果需要适应许多设备,则需要存储所有以前的地址,并像查找一样解析它们,只显示新的地址。

我也有同样的问题。只需将接收器放在onclick之外的oncreate下。
        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });
因为它在onclick下,所以接收器被初始化两次,从而复制设备

        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });

在onclick中删除接收器并将其置于oncreate下。您需要清除适配器中使用的列表。像这样->

        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });
private fun setAdapterToListView() {

        devicesNameAddressList.clear()
        for (i in 0 until devicesName.size) {
            val list = HashMap<String, String>()
            list.put("line1", devicesName[i])
            list.put("line2", devicesAddress[i])
            devicesNameAddressList.add(list)
        }

        val simpleAdapter = SimpleAdapter(this, devicesNameAddressList, R.layout.devices_listview_texttype,
                arrayOf("line1", "line2"), intArrayOf(R.id.line_a, R.id.line_b))
        BluetoothDevicesListID.adapter = simpleAdapter
    }
private fun setAdapterToListView(){
DeviceNameAddressList.clear()
用于(在DeviceName.size之前输入0){
val list=HashMap()
list.put(“第1行”,设备名称[i])
list.put(“第2行”,设备地址[i])
DeviceNameAddressList.add(列表)
}
val simpledapter=simpledapter(此,设备名称地址列表,R.layout.devices\u列表视图\u文本类型,
排列(“第1行”、“第2行”),在排列中(R.id.line_a、R.id.line_b))
BluetoothDeviceListId.adapter=simpleAdapter
}

对于具有mac地址的蓝牙设备,您可以匹配mac地址并从列表中删除重复的设备。

在开始查找设备之前,我使用cAdapter.clear()清除列表。扫描开始时,列表被清除,但稍后同一设备上的列表带有旧的时间戳。那么,您是想说在重新扫描之前列表没有被清除吗??它包含以前结果的元素??旧条目列表被清除,但重新扫描时,设备会显示重复条目和相同的时间戳。我又添加了两个类文件,希望这能帮助您解决问题;在此行中,尝试将BluetoothDevice.EXTRA\u设备更改为BluetoothDevice.ACTION\u。可能正在使用EXTRA_设备意图是返回带有旧时间戳的列表设备以及带有新时间戳的相同设备作为新条目..应用程序意外停止。感谢帮助,我的问题已通过我发布的答案得到解决。
        btOnOff.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(btOnOff.isChecked()){

                btAdapter.startDiscovery();
                setProgressBarIndeterminateVisibility(true);

                    bcReceiver = new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            // TODO Auto-generated method stub
                            String action = intent.getAction();
                            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                                deviceName = device.getName();
                                currentDateTime = DateFormat.getDateTimeInstance().format(new Date());

                                Custom data = new Custom(deviceName, currentDateTime);
                                fetch.add(data);

                                lv.setAdapter(cAdapter);

                            }else if(btAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                                btAdapter.startDiscovery();
                            }
                        }
                    };

                    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(bcReceiver, filter);
            } else {
                btAdapter.cancelDiscovery();
            }
        }

    });