如何在将联系信息加载到listview时避免重复的联系人姓名(数据)?

时间:2014-07-29 09:27:40

标签: android android-contacts

我正在填写联系人列表详细信息以成功列出视图。 我的代码:

  String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
  Cursor   curLog =  getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null,order); 

如何在列表视图中避免重复数据,因为联系人详细信息如果已加入联系人,即与手机和Google同时加入,则会重复。屏幕类似于enter image description here

我想以编程方式只选择1个名称而不是两个名称?任何想法我如何选择?

7 个答案:

答案 0 :(得分:9)

我已经用一种粗略的方法来避免这个问题,这对我有很大帮助并且工作得很好。

使用本地数据库(SQLite)通过将电话号码设置为唯一来避免重复数据。

我已经制作了一个SQLite DB来处理这个问题:

ContactMerger.java:

public class ContactMerger {

private static final String CONTACT_TABLE = "_contact_table";
private static final String CONTACT_ID = "_contactId";
private static final String CONTACT_NAME = "_contactName";
private static final String CONTACT_MOBILE_NUMBER = "_contactNumber";
private static final String CONTACT_DATE  = "_contactDate";


private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "DB_Contact";

private final Context context;
private SQLiteDatabase ourDatabase;
private DbHelper ourHelper;

private class DbHelper extends SQLiteOpenHelper {

    public DbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        String contactQuery = "CREATE TABLE " + CONTACT_TABLE + " ("
                + CONTACT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + CONTACT_NAME + " TEXT NOT NULL, " + CONTACT_DATE
                + " TEXT NOT NULL, " + CONTACT_MOBILE_NUMBER
                + " TEXT NOT NULL UNIQUE);";

        db.execSQL(contactQuery);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        db.execSQL("DROP TABLE IF EXISTS " + CONTACT_TABLE);
        onCreate(db);
    }

}

public ContactMerger(Context context) {
    this.context = context;
}

public ContactMerger open() throws SQLException {
    ourHelper = new DbHelper(context);
    ourDatabase = ourHelper.getWritableDatabase();
    return this;
}

public void close() {
    ourHelper.close();
}

// Insert Data to Contact Table
public long insertContacts(String name, String number, String date) throws SQLException {
    ContentValues cv = new ContentValues();
    cv.put(CONTACT_NAME, name);
    cv.put(CONTACT_DATE, date);
    cv.put(CONTACT_MOBILE_NUMBER, number);
    Log.d("Insert Data", cv.toString());
    return ourDatabase.insert(CONTACT_TABLE, null, cv);
}

//Get Contact details from Contact Table
public ArrayList<ContactHolder> getContactDetails() throws Exception{
    ArrayList<ContactHolder> contactDetails = new ArrayList<ContactHolder>();
    String[] columns = new String[] { CONTACT_ID, CONTACT_NAME, CONTACT_DATE, CONTACT_MOBILE_NUMBER };
    Cursor c = ourDatabase.query(CONTACT_TABLE, columns, null, null, null,null, null);

    int iContactName = c.getColumnIndex(CONTACT_NAME);  
    int iContactDate = c.getColumnIndex(CONTACT_DATE);  
    int iContactMobileNumber = c.getColumnIndex(CONTACT_MOBILE_NUMBER);

    for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {

        ContactHolder data = new ContactHolder();
        data.setName(c.getString(iContactName));
        data.setDate(c.getString(iContactDate));
        data.setNumber(c.getString(iContactMobileNumber));

        contactDetails.add(data);
    }

    return contactDetails;
 }
}

此处ContactHolder只是一个用于处理联系人实体的getter / setter类。

首先,我在后台主题的帮助下,在MainActivity中插入了一次所有联系人信息。它可以防止多次插入联系信息。

类似的东西:

private ArrayList<ContactHolder> contactHolder;
private void setCallLogs(Cursor managedCursor) {
    contactHolder = new ArrayList<ContactHolder>();

    int _number = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
    int _name = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
    int _id = managedCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);


    while (managedCursor.moveToNext()) {

        ContactHolder holder = new ContactHolder();
        holder.setNumber(managedCursor.getString(_number));
        holder.setName(managedCursor.getString(_name));
        holder.setDate(managedCursor.getString(_id));
        contactHolder.add(holder);
    }
    Thread t = new Thread(new Runnable() {

        @Override
        public void run() {
            for(int i=0; i<contactHolder.size(); i++){
                try{
                    ContactMerger merger = new ContactMerger(HomeActivity.this);
                    merger.open();
                    merger.insertContacts(contactHolder.get(i).getName(),
                            contactHolder.get(i).getNumber(),
                            contactHolder.get(i).getdate());
                    merger.close();

                } catch(Exception e){
                     e.printStackTrace();
                }
            }

        }
    });

    t.start();  

}

最后,我获取了Asynctask(doInbackground())中的所有联系信息,并在我想要显示的类中的onPostExecute()方法中放入了adapter / listview。

下面:

@Override
    protected ArrayList<ContactHolder> doInBackground(String... parameters) {
        ArrayList<ContactHolder> filterContacts = new ArrayList<ContactHolder>();
        ContactMerger merger = new ContactMerger(Aaja_Contact.this);
        merger.open();
        try {
            filterContacts = merger.getContactDetails();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        merger.close();

        return filterContacts;
    }

答案 1 :(得分:2)

我认为,如果联系电话号码以两种不同的方式/格式存储,则可能会发生这种情况:例如,在您的情况下, Akshay 的号码可能会保存为 982-0123456 9820123456

您是否尝试通过在列表视图中包含数字来显示数字和名称?

答案 2 :(得分:1)

您需要从Cursor检索数据到HashSet(不允许重复的主题),然后将HashSet对象传递给ListView的适配器

这是一个转储解决方案,但它会对您有所帮助:

ListView listView;
Set<String> listItems;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    listView = (ListView) findViewById(R.id.listView);
    listItems = new HashSet<String>();

    String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
    Cursor curLog =  getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null,order); 

    if(curLog != null) {
        while(curLog.moveToNext()) {
            String str = curLog.getString(curLog.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY));
            listItems.add(str);
        }
    }

    String listString = listItems.toString();
    listString = listString.substring(1,listString.length()-1);
    String[] newList = listString.split(", ");

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, newList);
    listView.setAdapter(adapter);        
}
祝你好运..

答案 3 :(得分:0)

由于您要查询Phone.CONTENT_URI,我假设您正在寻找有电话号码的联系人..那么您可以使用ContactsContract.Contacts.CONTENT_URI

String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor curLog = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
                ContactsContract.Contacts.HAS_PHONE_NUMBER + "=?", new String[] { "1" }, order);

答案 4 :(得分:0)

这是因为listview显示了正常的联系人以及whatsapp(或类似的)链接的联系人。最好是将所有联系人存储在数据库中,然后使用&#34;选择不同的...&#34;来检索联系人。 SQL命令。

答案 5 :(得分:0)

String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
    Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, order);
    String temp_name="";
    while (phones.moveToNext())
    {
        String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
        if (name.equals(temp_name))
            continue;
        temp_name=name;
       //add name to your list or adapter here`enter code here` 
    }
    phones.close();

答案 6 :(得分:0)

当循环浏览联系人时,可以在循环语句中执行以下操作,同时添加下一个对象,以避免创建重复的联系人:

UserList object=new UserList(name,number);
        if(arrayList.size()==0)
        {
            arrayList.add(object);
        }
        if(arrayList.size()>0) {
            position = arrayList.size();
            if (!(arrayList.get(arrayList.position - 1).getName().equals(number) || 
                arrayList.get(position - 1).getNumber().equals(number)))
               {
                arrayList.add(object); }  
          }

在这里,在我的“ UserList”类对象中,名称和号码将从联系人列表中重复,因此此代码仅在添加新对象之前检查前一个对象是否具有相同的姓名或号码。