【问题标题】:How to retrieve phone numbers/photo id/firstname/lastname within a single request?如何在单个请求中检索电话号码/照片 ID/名字/姓氏?
【发布时间】:2015-08-04 17:14:04
【问题描述】:

我目前正在使用这个问题的答案:How to get all contacts first name, last name, email, phone number, etc without duplicates 来检索用户联系人列表,其中包含每个联系人的所有电话号码、名字、姓氏和照片 ID。

我对这个答案的疑问是它为每个想要的数据创建一个请求。它在我的应用程序上造成性能问题。我想从一个请求中检索所有这些信息,但是我很难理解 Android 的查询是如何管理的以及我要查找的存储数据在哪里。

我尝试过的示例(我做了很多测试但没有成功,以下是我尝试过的最后一个):

    new CursorLoader(
        this,
        ContactsContract.Data.CONTENT_URI,
        null,
        ContactsContract.Data.HAS_PHONE_NUMBER + "!=0 AND (" + ContactsContract.Data.MIMETYPE + "=?)",
        new String[]{ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE},
        ContactsContract.Data.CONTACT_ID)
    ; 

以及我想检索的信息:

        int firstNameCol = cursor.getColumnIndex(CommonDataKinds.StructuredName.GIVEN_NAME);
        int lastNameCol = cursor.getColumnIndex(CommonDataKinds.StructuredName.FAMILY_NAME);
        int photoIdCol = cursor.getColumnIndex(CommonDataKinds.StructuredName.PHOTO_ID);
        int phoneCol = cursor.getColumnIndex(Phone.NUMBER);

该请求存在两个问题:

  • 每个联系人我只有一个电话号码,但是我的一些联系人有多个号码,我想找回它们

  • 我没有检索名字和姓氏(我得到一个奇怪的数字)

请注意,我不想检索 DISPLAY_NAME,我想要 given_name 和 family_name。另请注意,我希望每个联系人有一个结果,而不是每个电话号码有一个结果(即一个结果包含一对多的电话号码)

有什么想法可以在一个请求中完成吗?

编辑:尝试使用来自 @pskink 的另一段代码,但我收到“列 '_id' 不存在”错误

    String[] projection = {
        ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
        ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
        ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.StructuredName.PHOTO_ID
    };
    String selection = ContactsContract.Data.MIMETYPE + " in (?, ?, ?, ?)";
    String[] selectionArgs = {
        ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
        ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
        ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
        ContactsContract.CommonDataKinds.StructuredName.PHOTO_ID
    };
    //String sortOrder = ContactsContract.Contacts.SORT_KEY_ALTERNATIVE;

    //Uri uri = ContactsContract.CommonDataKinds.Contactables.CONTENT_URI;
    Uri uri = ContactsContract.Data.CONTENT_URI;
    // ok, let's work...
    return new CursorLoader(
        this, uri, projection, selection, selectionArgs, null
    );

【问题讨论】:

  • 查看 stackoverflow.com/a/26820544/2252830 并修改它以满足您的特定需求
  • 这就是我不知道如何适应我的需要的东西。查看我的更新,我正在尝试,但出现“列 '_id' 不存在”错误。此外,您的解决方案正在做一些检查以检索对象中的电子邮件列表(如果(mimeType.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)),我不能这样做,我真的需要在一行中检索所有电话号码,因为我在列表视图中使用了光标适配器,并且每个项目都必须链接到一个联系人,而不是一个电话号码。
  • 对不起,我不知道你在说什么,你有没有尝试在 Activity.onCreate 中添加我的代码?
  • (对不起 - 你太快了,我正在更新我的答案,为什么你无法理解)不,我没有尝试添加你的代码,因为它不适合我的需要。网上有很多例子,每个例子都在工作,但我找不到适合我需要的东西(在一个请求中,作为一个快速提醒,我现在有一些工作但有请求很多,并且花费了太多时间)
  • 是您制作了最终版本(顺便说一句,您也可以在此处发布答案);如果你愿意,你可以投票给我的原创作品

标签: android android-contacts


【解决方案1】:

感谢@pskink,我现在有一个快速的单一请求来检索我想要的东西。不幸的是,我不能使用 CursorAdapter,我必须请求整个数据库并将结果存储在对象模型中,但结果非常快,所以没关系。

这是完整的代码:

public ArrayList<ContactModel> retrieveContactList(){

    ArrayList<ContactModel> list = new ArrayList<>();
    LongSparseArray<ContactModel> array = new LongSparseArray<>();

    Set<String> set = new HashSet<String>();
    set.add(ContactsContract.Data.MIMETYPE);
    set.add(ContactsContract.Data.CONTACT_ID);
    set.add(ContactsContract.Data.PHOTO_ID);
    set.add(ContactsContract.CommonDataKinds.Phone.NUMBER);
    set.add(ContactsContract.CommonDataKinds.Phone.TYPE);
    set.add(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
    set.add(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
    set.add(ContactsContract.Contacts.PHOTO_ID);

    Uri uri = ContactsContract.Data.CONTENT_URI;
    String[] projection = set.toArray(new String[0]);
    String selection = ContactsContract.Data.MIMETYPE + " in (?, ?)";
    String[] selectionArgs = {
        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
        ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
    };
    String sortOrder = ContactsContract.Contacts.SORT_KEY_ALTERNATIVE;

    Cursor cursor = this.context.getContentResolver().query(
        uri,
        projection,
        selection,
        selectionArgs,
        sortOrder
    );

    final int mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE);
    final int idIdx = cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID);
    final int phoneIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
    final int phoneTypeIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
    final int givenNameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME);
    final int familyNameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME);
    final int photoIdIdx = cursor.getColumnIndex(ContactsContract.Data.PHOTO_ID);

    while (cursor.moveToNext()) {

        long id = cursor.getLong(idIdx);
        ContactModel addressBookContact = array.get(id);

        if (addressBookContact == null) {
            addressBookContact = new ContactModel(id);
            array.put(id, addressBookContact);
            list.add(addressBookContact);
        }

        Long photoId = cursor.getLong(photoIdIdx);
        if (photoId != null){
            addressBookContact.addPhotoId(photoId);
        }

        switch (cursor.getString(mimeTypeIdx)) {
            case ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE:
                // row's data: see ContactsContract.CommonDataKinds.Phone
                addressBookContact.addPhone(cursor.getInt(phoneTypeIdx), cursor.getString(phoneIdx));
                break;
            case ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE:
                // row's data: see ContactsContract.CommonDataKinds.StructuredName
                addressBookContact.addName(cursor.getString(givenNameIdx), cursor.getString(familyNameIdx));
                break;
        }
    }

    cursor.close();

    return list;
}

【讨论】:

  • 顺便说一句:你需要selectionArgs 中的ContactsContract.Contacts.CONTENT_ITEM_TYPE(和selection 中的三个“?”)吗?你不会在任何地方使用它...
  • 是的,你说得对,它没用,我第一次尝试使用 CONTENT_ITEM_TYPE 作为照片 ID,后来我忘了删除它。答案已编辑。再次感谢!
  • 我找到了使用 SimpleCursorAdapter 的解决方案 ;-),请将速度与此进行比较:codeshare.io/eOxal
猜你喜欢
  • 2011-08-10
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多