【问题标题】:Read contacts from phone is very slow从手机读取联系人非常慢
【发布时间】:2019-06-16 22:49:31
【问题描述】:

我正在尝试从我的手机中获取所有联系人,包括从具有多个号码的联系人中获取所有号码。

所以我已经构建了查询,虽然没有过度运行所有联系人,并构建了联系人用户,并且有带有 id 选择的内部查询来获取每个用户的所有号码。但由于我的内部查询包括选择,所以需要很长时间。还有什么想法吗?

private Cursor initPhoneCursor() {
    try {

        // get the contacts URI
        final Uri phoneUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
        // get the name column's name depending on the Android Version
        final String nameColumn = Contact.COLUMN_NAME_PHONE;


        // declare columns object - init later depending on version
        String selection = getQuerySelectionForCursor();

        String[] columns = getColumnSelectionForCursor(nameColumn);

        if (mApp != null) {
            // return cursor from contentresolver
            return mApp.getContentResolver().query(phoneUri, columns, selection, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
        }
    } catch (Exception e) {
        // couldn't read phone cursor

        CaughtExceptionHandler.reportException(e);
    }
    return null;
}

private void importContactsFromCursor(Cursor cursor, boolean isSimCard) {


    mCurrentContactCursor = initPhoneCursor();

    // check cursor is alive
    if (cursor != null && !cursor.isClosed()) {

        while (cursor.moveToNext() && shouldContinueImport()) {

//                // as log as we have contacts, move through them
            importContact(cursor, isSimCard);

            mCurrentContact++;

        }
        // when done - close the cursor
        cursor.close();
    }
}

private void importContact(Cursor cursor, boolean simCard) {

    // create Contact object
    Contact row = new Contact(cursor, simCard);

//        mContactsTimer.onContactCreated();


    if (simCard) {
        // if simCard, contact must have number

        // validate number and create contact
        row = validateAndCheckNumber(row, cursor);

    }
    else {
        // if not sim card (phone cursor), a contact might have no numbers,
        // single or multiple phone numberss

        // let's check if this contact has any numbers
        if (hasPhoneNumbers(cursor)) {

            // get all of the contact's phone numbers
            row = importAllNumbersForContact(row);

        }

    }

    // check if this is valid
    final boolean isValidForSaving = row != null && row.hasName() && row.hasNumbers();

    if (isValidForSaving && !sStopRequested) {

        mContactsToSave.add(row);
    }

}

private Contact importAllNumbersForContact(Contact contact) {

    // uri of contact phones
    Uri contentUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;

    // contact_id = ?
    String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
    String[] selectionArgs = {String.valueOf(contact.getOriginalId())};

    // do the query
    Cursor phoneCursor = mApp.getContentResolver().query(contentUri, null, selection, selectionArgs, null);

    if (phoneCursor != null) {

        // save numbers if we got anything
        contact = loopThroughContactNumbers(contact, phoneCursor);


        // close cursor when done
        phoneCursor.close();

    }
    return contact;
}

【问题讨论】:

    标签: android performance cursor android-contacts import-contacts


    【解决方案1】:

    采用以下解决方案:

    Map<String,Contact> contactsMap = new TreeMap<>();
        contacts = new ArrayList<>();
    
        Cursor phones = getBaseContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" ASC");
        assert phones != null;
        while (phones.moveToNext())
        {
            Contact contact = new Contact();
            contact.setDisplayName(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
            contact.setPhoneNumber(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
            contact.setDisplayPicture(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI)));
            contactsMap.put(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)),contact);
        }
    
        contacts.addAll(contactsMap.values());
        phones.close();
    

    为联系人的所有号码修改它。你很适合。

    【讨论】:

    • 如何修改它以获取所有数字? Phone.number 只返回主号码?
    • 哥们,你需要做的工作很少,因为我以前没有这样做过,但这是获取联系人的最快方法。
    • 我搜索了很多...我找到的唯一方法是使用另一个带有选择的查询,就像我在 importAllNumbersForContact() 上使用的那样。但是需要很长时间,我没有找到其他方法直接从光标中获取它
    猜你喜欢
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    • 2015-01-23
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    相关资源
    最近更新 更多