【问题标题】:Remove Duplicate Contacts in custom listview删除自定义列表视图中的重复联系人
【发布时间】:2017-01-27 15:56:44
【问题描述】:

我正在使用https://trinitytuts.com/get-contact-list-and-show-in-custom-listview-android/# 教程在列表视图中获取联系人列表。它工作正常,但提供了重复的联系人。有人可以指导解决此问题并仅在列表视图中获得一次联系吗?

Mainactivity的代码如下:

import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class MainActivity extends Activity {

    // ArrayList
    ArrayList<SelectUser> selectUsers;
    List<SelectUser> temp;
    // Contact List
    ListView listView;
    // Cursor to load contacts list
    Cursor phones, email;

    // Pop up
    ContentResolver resolver;
    SearchView search;
    SelectUserAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        selectUsers = new ArrayList<SelectUser>();
        resolver = this.getContentResolver();
        listView = (ListView) findViewById(R.id.contacts_list);

        phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
        LoadContact loadContact = new LoadContact();
        loadContact.execute();

        search = (SearchView) findViewById(R.id.searchView);

        //*** setOnQueryTextListener ***
        search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override
            public boolean onQueryTextSubmit(String query) {
                // TODO Auto-generated method stub

                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                // TODO Auto-generated method stub
                adapter.filter(newText);
                return false;
            }
        });
    }

    // Load data on background
    class LoadContact extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected Void doInBackground(Void... voids) {
            // Get Contact list from Phone

            if (phones != null) {
                Log.e("count", "" + phones.getCount());
                if (phones.getCount() == 0) {
                    Toast.makeText(MainActivity.this, "No contacts in your contact list.", Toast.LENGTH_LONG).show();
                }

                while (phones.moveToNext()) {
                    Bitmap bit_thumb = null;
                    String id = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
                    String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    String EmailAddr = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA2));
                    String image_thumb = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI));
                    try {
                        if (image_thumb != null) {
                            bit_thumb = MediaStore.Images.Media.getBitmap(resolver, Uri.parse(image_thumb));
                        } else {
                            Log.e("No Image Thumb", "--------------");
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    SelectUser selectUser = new SelectUser();
                    selectUser.setThumb(bit_thumb);
                    selectUser.setName(name);
                    selectUser.setPhone(phoneNumber);
                    selectUser.setEmail(id);
                    selectUser.setCheckedBox(false);
                    selectUsers.add(selectUser);
                }
            } else {
                Log.e("Cursor close 1", "----------------");
            }
            //phones.close();
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            adapter = new SelectUserAdapter(selectUsers, MainActivity.this);
            listView.setAdapter(adapter);

            // Select item on listclick
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

                    Log.e("search", "here---------------- listener");

                    SelectUser data = selectUsers.get(i);
                }
            });

            listView.setFastScrollEnabled(true);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        phones.close();
    }
}

【问题讨论】:

    标签: java android listview android-contacts


    【解决方案1】:

    为什么不使用Set?尝试将您的联系人存储在Object 中,将Object 存储在Set 中。请记住覆盖 Objectequals 方法,基于该方法您需要消除重复项。

    更多阅读在这里 http://www.java2novice.com/java-collections-and-util/hashset/duplicate/

    【讨论】:

    • 如果我只是将 Arraylist 更改为 Hashset 以保持一切不变,则列表大小从 2973 变为 30。因此跳过了大部分要添加到集合中的联系人。这个怎么用。
    • 您必须添加要显示在对象中的联系人,即联系人对象(例如)。然后在联系人对象中,您需要覆盖 equals 方法并根据您需要返回 true 或 false 的任何标准。其余全部由 HashSet 内部管理。
    【解决方案2】:

    您看到重复的联系人是因为您查询的是电话列表,而不是联系人,如果一个联系人有多个电话,您将多次获得同一个联系人 - 每个电话号码一个。

    您需要决定如何处理多部手机的联系人,以及没有任何手机的联系人(目前您不显示没有任何手机的联系人)。

    假设您希望每个联系人使用一条线路,仅显示有电话的联系人,并在同一行显示该联系人的所有电话,您需要修改你的代码有点:

    1. SelectUser 对象应接受电话列表,而不仅仅是一个。
    2. selectUsers 字段应该是 HashMap&lt;Long, SelectUser&gt; 而不是 ArrayList&lt;SelectUser&gt;
    3. String id = ... 实际上应该是 Long id = ...

    然后在您的光标迭代器中执行以下操作:

    if (selectUsers.containsKey(id)) {
        SelectUser selectUser = selectUsers.get(id);
        selectUser.addPhone(phoneNumber); // new method you need to implement
    } else {
        SelectUser selectUser = new SelectUser();
        selectUser.setThumb(bit_thumb);
        selectUser.setName(name);
        selectUser.setPhone(phoneNumber);
        selectUser.setEmail(id); // Email can't be retrieved from the phones table, see below
        selectUser.setCheckedBox(false);
        selectUsers.add(selectUser);
    }
    

    附言 查询CommonDataKinds.Phone表时无法读取CommonDataKinds.Email字段,如果要在同一查询中同时读取电话和电子邮件,则需要查询ContactsContract.Data表,并选择Data.MIMETYPE + ' = ' + Phone.CONTENT_TYPE + ' OR ' + Data.MIMETYPE + ' = ' + Email.CONTENT_TYPE。 这将使您将光标悬停在 电话或电子邮件的行上(您可以使用 Data.MIMETYPE 来检查它是哪一个。

    在此处查看更多信息:https://developer.android.com/reference/android/provider/ContactsContract.Data.html https://stackoverflow.com/a/31864811/819355

    【讨论】:

      猜你喜欢
      • 2017-07-18
      • 2023-03-21
      • 1970-01-01
      • 2013-11-18
      • 1970-01-01
      • 1970-01-01
      • 2021-02-08
      • 2017-02-03
      • 2023-03-23
      相关资源
      最近更新 更多