且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-02-17 19:47:33

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

I have used a rough way to avoid this problem which helped me so much and working nicely.

使用本地数据库(SQLite)通过使电话号码唯一来避免重复数据.

Use local database (SQLite) to avoid duplicate data by make phone number to unique.

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

I have made one SQLite DB to handle this problem:

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 类.

Here ContactHolder is just a getter/setter class to handle contact entities.

首先,我在后台线程的帮助下将所有联系信息插入到我的 MainActivity 中.它可以防止多次插入联系信息.

First I inserted all Contact information once in my MainActivity by the help of a background thread. It prevents to insert the contact info multiple times.

类似于:

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() 方法中.

At last I gtt all contact information inside an Asynctask(doInbackground()) and put in adapter/listview in its onPostExecute() method in the class I want to show.

这里:

@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;
    }