从手机读取联系人非常慢

Posted

技术标签:

【中文标题】从手机读取联系人非常慢【英文标题】: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;

【问题讨论】:

【参考方案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() 上使用的那样。但是需要很长时间,我没有找到其他方法直接从光标中获取它

以上是关于从手机读取联系人非常慢的主要内容,如果未能解决你的问题,请参考以下文章

如何从android中的联系人读取电子邮件字段?

Android中读取手机联系人

Android使用READ_CONTACTS读取手机联系人

android 读写联系人需要啥权限

Android快速获取联系人

vivo手机怎么设置通讯录读取权限