从Android联系提供程序中检索联系信息

时间:2016-04-14 22:43:28

标签: android android-contentprovider android-contacts contactscontract

我正在尝试从联系人提供程序检索数据,但数据显示似乎无法正确查询。我使用的代码如下:

mCursor = mContext.getContentResolver().query(
        ContactsContract.Data.CONTENT_URI, null, null, null, null);



if(mCursor == null){
    mListener.onRetrieveError();
    return;
}

for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext()) {
    String contact_f = mCursor.getString(mCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
    String contact_m = mCursor.getString(mCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));
    String contact_l = mCursor.getString(mCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
    String phone_type = mCursor.getString(mCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
    String email_type = mCursor.getString(mCursor
            .getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));

    Log.d(TAG,  "|" + contact_l + ", " + contact_f + " " + contact_m + " | " + phone_type + " | " + email_type);
}

日志显示例如:

Log: |LastName, FirstName  | FirstName  | FirstName  
Log: |null, 3 null | 3 | 3

我在期待:

Log: |LastName, FirstName MiddleName | PhoneType| EmailType

我希望能够获得名字,姓氏,中间名,电子邮件类型(家庭/工作......) - 以及列出的所有电子邮件类型以及手机类型。

目标是例如联系他的姓氏,名字中间名,并说我们得到的是家庭和工作电话或电子邮件

我得到的结果似乎是混合。

任何想法。

此致

3 个答案:

答案 0 :(得分:2)

这不是它的工作原理。 Data表包含每个联系人值字段一行(电话号码,电子邮件地址,结构化名称......)。每行都有一个mimetype值,告诉您如何解释该行的列。

例如,如果mimetype列的值为Phone.CONTENT_ITEM_TYPE,则必须使用Phone列映射来访问数据。

因此,如果联系人有一个电话号码和一个电子邮件地址,则Data表中此联系人至少有3行。一个用于StructuredName(每个RawContact只需要一次),一个用于Phone号码,另一个用于Email地址。

每一行还有一个RAW_CONTACT_ID,其中包含该值所属的RawContact的行ID。

当您查询Data表时,实际上是从一个将真实Data表与RawContacts表连接起来的视图中读取的,因此每行还包含CONTACT_ID该行所属的联系人。这意味着如果两行具有相同的CONTACT_ID,则它们属于同一个联系人。

我希望能够解释它。我真的不知道你到底想要实现什么,所以我不能提供任何有用的代码片段。

更新

关键是在决定如何解释值之前检查每一行的mimetype。您还需要阅读CONTACT_IDRAW_CONTACT_ID才能正确汇总数据。如果您按CONTACT_ID订购结果,则可以假定CONTACT_ID值更改时已读取属于某个联系人的所有行。

下面的(未经测试的)代码段应指向正确的方向。关键是,您无法在一行中获取联系人的所有数据。您总是需要读取多行并以某种方式聚合它们。

mCursor = mContext.getContentResolver().query(
        ContactsContract.Data.CONTENT_URI, null, null, null, ContactsContract.Data.CONTACT_ID);

if(mCursor == null){
    mListener.onRetrieveError();
    return;
}

colIdxContactId = mCursor.getColumnIndex(ContactsContract.Data.CONTACT_ID);
colIdxMimetype = mCursor.getColumnIndex(ContactsContract.Data.MIMETYPE);

long lastContactId = -1L;

for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext())

  // this is the contact Id the current row belongs to
  long contactId = mCursor.getLong(colIdxContactId);

  if (lastContactId != contactId) {
    // the previous contact is complete, the following data belong to a new contact
    // handle this case ...

    lastContactId = contactId;
  }

  // the mimetype column tells us how to interpret the current row:
  switch(mCursor.getString(colIdxMimetype)) {
    case ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE: {
      // this row is a structured name
      String contact_f = mCursor.getString(mCursor
        .getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
      String contact_m = mCursor.getString(mCursor
        .getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));
      String contact_l = mCursor.getString(mCursor
        .getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
      // store names somewhere ...

      break;
    }
    case ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE: {
      // this row represents a phone number
      int phone_type = mCursor.getInt(mCursor
        .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
      // store phone_type somewhere ...

      break;
    }
    case ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE: {
      // this row represents an email address
      int email_type = mCursor.getInt(mCursor
        .getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
      // store email_type somewhere ...

      break;
    }
  }
}

答案 1 :(得分:0)

您可以使用此

 public void getAllContacts(){


        Cursor cursor = null;
        ContactPerson contact;
        try {
            cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
            int nameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
            int phoneNumberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
            int emailAddressIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
            cursor.moveToFirst();
            do {
                contact = new ContactPerson(cursor.getString(nameIdx),cursor.getString(phoneNumberIdx),cursor.getString(emailAddressIdx));
                cpList.add(contact);
                                    //  Toast.makeText(getActivity(),cursor.getString(nameIdx)+" "+ cursor.getString(phoneNumberIdx),Toast.LENGTH_SHORT).show();

            } while (cursor.moveToNext());
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(getActivity(),e.getMessage(), Toast.LENGTH_LONG).show();
            Log.d("Error",e.getMessage());

        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

   }

答案 2 :(得分:0)

我认为您使用的URI是错误的。 尝试使用ContactsContract.Contacts.CONTENT_URI代替ContactsContract.Data.CONTENT_URI(这是我使用的)。