安卓讀取聯(lián)系人信息如果聯(lián)系人過(guò)多導(dǎo)致耗時(shí)問(wèn)題

最近有個(gè)項(xiàng)目,需要讀取Android系統(tǒng)的聯(lián)系人。安卓讀取操作其實(shí)是聯(lián)系人數(shù)據(jù)庫(kù)的增刪改查;IOS方面直接可以獲取聯(lián)系人集合,其實(shí)就是對(duì)象關(guān)系映射。

于是在網(wǎng)絡(luò)上狂搜博客,網(wǎng)絡(luò)上最常用讀取聯(lián)系人代碼如下(1000聯(lián)系人耗時(shí)20s),原理是先查詢(xún)出聯(lián)系人的contactId,name,再去查詢(xún)手機(jī)號(hào),可以看到Cursor游標(biāo)里面還嵌套著Cursor,這樣不耗時(shí)都難:

//獲取系統(tǒng)聯(lián)系人
    public void getPhoneContacts() {
        List<Contacts> data = new ArrayList<>();
        ContentResolver resolver = context.getContentResolver();
        // 獲取手機(jī)聯(lián)系人
        Cursor phoneCursor = resolver.query(ContactsContract.Contacts.CONTENT_URI,
                new String[]{android.provider.ContactsContract.Contacts._ID, android.provider.ContactsContract.Contacts.DISPLAY_NAME}, null, null, null);
        if (phoneCursor != null) {
            while (phoneCursor.moveToNext()) {
                Contacts contacts = new Contacts();
                //獲取聯(lián)系人的ID
                String contactId = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.Contacts._ID));
                //獲取聯(lián)系人的姓名
                String name = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                contacts.setRecordId(Integer.valueOf(contactId));
                contacts.setName(name);
                ArrayList<String> phone = new ArrayList<>();
                //查詢(xún)電話(huà)類(lèi)型的數(shù)據(jù)操作
                Cursor phones = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER},
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId,
                        null, null);
                if (phones != null) {
                    while (phones.moveToNext()) {
                        String phoneNumber = phones.getString(phones.getColumnIndex(
                                ContactsContract.CommonDataKinds.Phone.NUMBER));
                        String replace = phoneNumber.replace(" ", "").replace("-", "").replace("+", "");
                        if (CheckUtils.checkPhoneNumber(replace)) {
                            phone.add(replace);
                        }
                    }
                    phones.close();
                }
                String[] strings = new String[phone.size()];
                for (int i = 0; i < phone.size(); i++) {
                    strings[i] = phone.get(i);
                }
                contacts.setMobile(strings);
                data.add(contacts);
            }
            phoneCursor.close();
            syncAvatars(data);
        }
    }

所以獲取聯(lián)系人數(shù)據(jù)最好在一個(gè)Cursor里獲取,避免嵌套,查看了聯(lián)系人數(shù)據(jù)庫(kù)表結(jié)構(gòu),以下的讀取聯(lián)系人和號(hào)碼的操作(1000個(gè)聯(lián)系人只需要0.2S左右)

//獲取系統(tǒng)聯(lián)系人,獲取1000個(gè)聯(lián)系人0.2秒,最快速
    public void getPhoneContacts() {
        //聯(lián)系人集合
        List<Contacts> data = new ArrayList<>();
        ContentResolver resolver = context.getContentResolver();
        //搜索字段
        String[] projection = new String[]{
                ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
                ContactsContract.CommonDataKinds.Phone.NUMBER,
                ContactsContract.Contacts.DISPLAY_NAME};
        // 獲取手機(jī)聯(lián)系人
        Cursor contactsCursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                projection, null, null, null);
        if (contactsCursor != null) {
            //key: contactId,value: 該contactId在聯(lián)系人集合data的index
            Map<Integer, Integer> contactIdMap = new HashMap<>();
            while (contactsCursor.moveToNext()) {
                //獲取聯(lián)系人的ID
                int contactId = contactsCursor.getInt(0);
                //獲取聯(lián)系人的姓名
                String name = contactsCursor.getString(2);
                //獲取聯(lián)系人的號(hào)碼
                String phoneNumber = contactsCursor.getString(1);
                //號(hào)碼處理
                String replace = phoneNumber.replace(" ", "").replace("-", "").replace("+", "");
                //判斷號(hào)碼是否符合手機(jī)號(hào)
                if (CheckUtils.checkPhoneNumber(replace)) {
                    //如果聯(lián)系人Map已經(jīng)包含該contactId
                    if (contactIdMap.containsKey(contactId)) {
                        //得到該contactId在data的index
                        Integer index = contactIdMap.get(contactId);
                        //重新設(shè)置號(hào)碼數(shù)組
                        Contacts contacts = data.get(index);
                        String[] mobile = contacts.getMobile();
                        String[] mobileCopy = new String[mobile.length + 1];
                        for (int i = 0; i < mobile.length; i++) {
                            mobileCopy[i] = mobile[i];
                        }
                        mobileCopy[mobileCopy.length - 1] = replace;
                        contacts.setMobile(mobileCopy);
                    } else {
                        //如果聯(lián)系人Map不包含該contactId
                        Contacts contacts = new Contacts();
                        contacts.setRecordId(contactId);
                        contacts.setName(name);
                        String[] strings = new String[1];
                        strings[0] = replace;
                        contacts.setMobile(strings);
                        data.add(contacts);
                        contactIdMap.put(contactId, data.size() - 1);
                    }
                }
            }
            contactsCursor.close();
            syncAvatars(data);
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,872評(píng)論 25 709
  • 前幾天整理了Java面試題集合,今天再來(lái)整理下Android相關(guān)的面試題集合.如果你希望能得到最新的消息,可以關(guān)注...
    Boyko閱讀 3,926評(píng)論 8 135
  • 聽(tīng)民謠的人 都是有故事的嗎 在我看來(lái),民謠是沙啞或干凈的聲音,是簡(jiǎn)單的樂(lè)器伴奏,是內(nèi)心世界的表達(dá)。 現(xiàn)在的我,走...
    北城二三事閱讀 640評(píng)論 7 6
  • 年幼之時(shí)我們的想法還未受到限制,我們夢(mèng)想改變世界,長(zhǎng)大后面對(duì)現(xiàn)實(shí),我們發(fā)現(xiàn)是不可能的。 但是我們?nèi)杂胁桓剩覀冞M(jìn)行...
    蝸牛君喲閱讀 191評(píng)論 0 1
  • 仿李白《夢(mèng)游天姥吟留別》句式。 太白語(yǔ)巴蜀,山川峻拔飛鳥(niǎo)顧。 滄海到幽都,惶惶木枯漸蕭疏。 嗟呀石削鋼刀鳴,刀刀似...
    銓齋閱讀 776評(píng)論 10 25

友情鏈接更多精彩內(nèi)容