合并重复联系人

  1. 1.搜索重复联系人
    1. 初始化search 界面
  2. 2.显示重复联系人
  3. 3.合并重复联系人

详细code逻辑,请参考lineageos 开源项目.

1.搜索重复联系人

//SearchDupActivity.java
@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
        case R.id.search_dup_dialog: {
            mProgressDialog = initSearchingDialog();
            DuplicatesUtils.setDialog(mProgressDialog);
            Thread thread = new SearchDuplicatedThread();
            DuplicatesUtils.mSearchState = true;
            thread.start();
            return mProgressDialog;
        }
    }
    return super.onCreateDialog(id);
}

初始化search 界面

//SearchDupActivity.java
private ProgressDialog initSearchingDialog() {
    ProgressDialog dialog = new MyProgressDialog(this);
    dialog.setMessage(this.getString(R.string.searching_duplicated_contacts));
    dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    dialog.setCanceledOnTouchOutside(false);
    Cursor cursor = null;
    int allCount = 0;
    String selection = RawContacts.DELETED + "= 0";
    try {
        //计算progress total size(通过rawcontacts表查询,去除DELETED)
        cursor = getContentResolver()
                .query(RawContacts.CONTENT_URI, RAWCONTACTS_ID_PROJECTION,
                selection, null, null);
    } finally {
        if (cursor != null) {
            allCount = cursor.getCount();
            cursor.close();
        }
    }
    dialog.setMax(allCount);
    return dialog;
}

1.获取 account list
2.计算 duplicate contacts 用于显示MergeContactActivity的数据
3.查询完后,handler通知启动MergeContactActivity界面。


//SearchDupActivity.java
private class SearchDuplicatedThread extends Thread {
    @Override
    public void run() {
        List<AccountWithDataSet> list = AccountTypeManager
                .getInstance(SearchDupActivity.this).getAccounts(true);
        ArrayList<Account> accountsList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            accountsList.add(list.get(i).getAccountOrNull());
        }

        /* calculate the contacts which can be merged. */
        boolean isComplete = DuplicatesUtils
                .calculateMergeRawContacts(SearchDupActivity.this, accountsList,
                        getContentResolver());
        Message msg = Message.obtain();
        if (isComplete) {
            ArrayList<DuplicatesUtils.MergeContacts> mergeRawContacts =
                    DuplicatesUtils.getMergeRawContacts();
            if (mergeRawContacts != null && mergeRawContacts.size() > 0) {
                msg.what = FIND_DUPLICATED;
            } else {
                msg.what = NO_DUPLICATED;
            }
            handler.sendMessage(msg);
        }
    }
}

1.根据account 先进行区分
2.根据account 查询 rawcontacts, 获取HashMap <name(ignore大小写), list(rawcontacts ids)>
3.判定是否有dup contacts(list size 是否大于2)
判定是否可merge:
a。根据id in RawContactsEntity进行查询
b。根据mimeType 组建mergePhoneList、mergeEmailList、photoid等
c。构建ArrayList<ContactsInfo>
d。构建ArrayList<MergeContacts> 对于sim contacts 进行额外判定。(MergeContacts:ContactsInfo ~ 1:n)
4.progress 进度的更新


//DuplicatesUtils.java
public static boolean calculateMergeRawContacts(Context context, List<Account> accounts,
    ContentResolver resolver) {
    SimContactsOperation simContactsOperation = new SimContactsOperation(context);
    mMergeRawContacts = new ArrayList<>();
    int count = 0;
    // contacts in different accounts are separated.
    for (int i = 0; i < accounts.size() && mSearchState; i++) {
        Account account = accounts.get(i);
        HashMap<String, List<Long>> map = DuplicatesUtils.getRawNameWithIds(resolver,
                new String[]{account.name, account.type});
        if (map != null && map.size() > 0) {
            ArrayList<ContactsInfo> lst1;
            Iterator<String> iterator = map.keySet().iterator();
            while (mSearchState && iterator.hasNext()) {
                List<String> mergePhoneList = new ArrayList();
                List<String> mergeEmailList = new ArrayList();
                long contactId = -1;
                lst1 = new ArrayList<>();
                String keyName = iterator.next();
                List<Long> lst = map.get(keyName);
                if (lst.size() >= 2) {
                    EntityIterator entityIterator = DuplicatesUtils.getEntityByIds(resolver,
                            lst);
                    if (entityIterator == null) {
                        continue;
                    }
                    try {
                        while (entityIterator.hasNext()) {
                            ArrayList<String> phoneList = new ArrayList<>();
                            ArrayList<String> emailList = new ArrayList<>();
                            long photoId = 0;
                            Entity next1 = entityIterator.next();
                            ContentValues values = next1.getEntityValues();
                            Long rawId = values.getAsLong(RawContacts._ID);
                            String id = values.getAsString(RawContacts.CONTACT_ID);
                            if (!TextUtils.isEmpty(id)) {
                                contactId = Long.parseLong(id);
                            }
                            Iterator<Entity.NamedContentValues> namedContentValuesIterator =
                                    next1.getSubValues().iterator();
                            while (namedContentValuesIterator.hasNext()) {
                                ContentValues values1 = namedContentValuesIterator
                                        .next().values;
                                String mimeType = values1.getAsString(Data.MIMETYPE);
                                if (CommonDataKinds.StructuredName
                                        .CONTENT_ITEM_TYPE.equals(mimeType)) {
                                    continue;
                                }
                                if (CommonDataKinds.Photo.CONTENT_ITEM_TYPE
                                        .equals(mimeType)) {
                                    photoId = values1.getAsLong(CommonDataKinds.Photo._ID)
                                            .longValue();
                                    continue;
                                }
                                if (CommonDataKinds.Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
                                    String data1 = values1
                                            .getAsString(CommonDataKinds.Phone.DATA1);
                                    phoneList.add(data1);
                                    if (!TextUtils.isEmpty(data1)
                                            && !mergePhoneList.contains(data1)) {
                                        boolean contains = false;
                                        for (int j = 0; j < mergePhoneList.size(); j++) {
                                            if (PhoneNumberUtils.compare(data1,
                                                    mergePhoneList.get(j))) {
                                                contains = true;
                                                break;
                                            }
                                        }
                                        if (!contains) {
                                            mergePhoneList.add(data1);
                                        }
                                        continue;
                                    }
                                }
                                if (CommonDataKinds.Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
                                    String email = values1
                                            .getAsString(CommonDataKinds.Email.DATA1);
                                    emailList.add(email);
                                    if (!mergeEmailList.contains(email)) {
                                        mergeEmailList.add(email);
                                    }
                                    continue;
                                }
                            }
                            Cursor cursor = resolver.query(Contacts.CONTENT_URI,
                                    CONTACTS_PROJECTION, Contacts._ID.concat(" = ?"),
                                    new String[]{String.valueOf(contactId)}, null);

                            if (cursor != null && cursor.moveToNext()) {
                                String lookUp = cursor.getString(cursor
                                        .getColumnIndex(Contacts.LOOKUP_KEY));
                                String displayName = cursor.getString(cursor.getColumnIndex(
                                        Contacts.DISPLAY_NAME_PRIMARY));
                                lst1.add(new ContactsInfo(contactId, lookUp, photoId,
                                        displayName, phoneList, emailList, rawId));
                                cursor.close();
                            }
                        }
                    } finally {
                        if (entityIterator != null) {
                            entityIterator.close();
                        }
                    }
                    // for sim contacts, analyse if it can be merged.
                    if (contactId != -1
                            && account.type.equals(SimContactsConstants.ACCOUNT_TYPE_SIM)) {
                        int subscription = simContactsOperation.getSimSubscription(contactId);
                        int oneSimAnrCount = MoreContactUtils.getOneSimAnrCount(
                                context, subscription);
                        int oneSimEmailCount = MoreContactUtils
                                .getOneSimEmailCount(context, subscription);
                        if (mergePhoneList.size() > oneSimAnrCount + 1
                                || mergeEmailList.size() > oneSimEmailCount) {
                            continue;
                        }
                    }
                    if (mMergeRawContacts != null) {
                        mMergeRawContacts.add(
                            new MergeContacts(account.name, account.type, lst1));
                    }
                }
                count += lst.size();
                mProgressDialog.setProgress(count);
            }
        }
    }
    if (mSearchState) {
        // search ended, change the flag.
        mSearchState = false;
        return true;
    }
    return false;
}

2.显示重复联系人


根据ArrayList<MergeContacts> 显示UI e.g. 根据mSelectCount 控制merge enanble或disable等


//MergeContactActivity.java
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    MergeContactAdapter adapter = (MergeContactAdapter) l.getAdapter();
    DuplicatesUtils.MergeContacts item = (DuplicatesUtils.MergeContacts) adapter
            .getItem(position);
    CheckBox cb = (CheckBox) v.findViewById(R.id.row_box);
    // mark the mergeContacts item, which will be merged later, if true.
    // calculate the selected count.
    if (cb.isChecked() && item.isChecked()) {
        cb.setChecked(false);
        item.setChecked(false);
        mSelectCount--;
    } else {
        cb.setChecked(true);
        item.setChecked(true);
        mSelectCount++;
    }
    // if the selected count is '0', disable the menuItem.
    if (mSelectCount == 0 && mergeItem != null && mergeItem.isEnabled()) {
        mergeItem.setEnabled(false);
    } else if (mSelectCount > 0 && mergeItem != null && !mergeItem.isEnabled()) {
        mergeItem.setEnabled(true);
    }
}

3.合并重复联系人

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_merge: {
            mProgressDialog = new MyProgressDialog(MergeContactActivity.this);
            mProgressDialog.setMessage(this.getString(R.string.merging_contacts));
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            Iterator<DuplicatesUtils.MergeContacts> iterator = mMergeList.iterator();
            while (iterator.hasNext()) {
                DuplicatesUtils.MergeContacts next = iterator.next();
                if (!next.isChecked()) {
                    iterator.remove();
                }
            }
            mProgressDialog.setMax(mMergeList.size());
            mProgressDialog.setCancelable(false);
            mProgressDialog.setCanceledOnTouchOutside(false);
            mProgressDialog.show();
            Thread thread = new MergeDuplicatedThread();
            DuplicatesUtils.mMergeState = true;
            thread.start();
        }
    }
    return true;
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 450603622@qq.com

文章标题:合并重复联系人

文章字数:958

本文作者:steinswang

发布时间:2018-01-16, 10:00:00

最后更新:2020-02-03, 11:15:26

原始链接:http://yoursite.com/2018/01/16/merge-contacts/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录