【问题标题】:Read phone number along with address using Intent.ACTION_PICK使用 Intent.ACTION_PICK 读取电话号码和地址
【发布时间】:2016-09-14 16:32:19
【问题描述】:

我想从构建联系人选择器中读取联系人信息。我正在读取电话号码、街道、电子邮件和地址。它出错了。

以下是调用联系人选择器的代码:

Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
context.startActivityForResult(contactPickerIntent, REQUEST_ID_CONTACT_PICKER); 

以下是 OnActivityResult 方法的代码,我是 fetching contact 来自光标的信息:

Uri contactURI = intent.getData();
                    Cursor cursor = activity.getContentResolver().query(contactURI, null, null, null, null);
int count = cursor.getCount();
// here value of count is 1, so need to do cursor.moveToNext() to go to selected record.
if (cursor.moveToNext()) {
            String givenName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            String familyName =  cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
            String displayName =  cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
            String middleName =  cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));

            int contactType = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
            String phoneNo = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            String poBox = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POBOX));
            String street = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
            String city = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
            String state = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
            String postalCode = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE));
            String country = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY));
            String neighborhood = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.NEIGHBORHOOD));
            String formattedAddress = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS));
            String emailId = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));

        }

我无法识别,为什么我在街道、电子邮件 ID 等列中得到错误的数据(即联系电话)。

这里 cursor.moveToNext() 需要转到第一行,所以它是 显然是必需的,我的问题不是我变得不同 记录,我在街道,emailId 列中获取手机号码,即 错了。

【问题讨论】:

    标签: android android-contentprovider android-contacts android-contact-mimetype


    【解决方案1】:

    在浪费了超过 3 天之后,找到了做我想做的事情的方法:

    common structure 用于存储所有类型的数据,例如电话、地址、电子邮件等。 See the common columns names,

    这就是为什么我们无法获取所有类型的数据(联系人、电子邮件、地址 等)具有联系人选择器意图,所以首先我们需要获取联系人 由于联系人选择器意图,ID 或联系人lookUpKey,而不是我们 其他详情需要单独查询。

    但是当尝试获取其他详细信息时会出现问题,因为每个 数据保存在相同的表结构中,即可以 持有任何类型的联系数据。

    并且存储在给定行中的数据类型由该行的 MIMETYPE 值,它确定通用列的含义 DATA1 到 DATA15。例如,如果数据 Mime 类型是 Phone.CONTENT_ITEM_TYPE,然后DATA1列存储手机 number,但如果数据 Mime 类型为 Email.CONTENT_ITEM_TYPE,则 DATA1 存储电子邮件地址。

    所以首先我们需要在查询前设置带有 Mime 类型的 where 子句 任何类型的内容,请参阅 mime 类型列表here

    这就是我们应该如何触发一个意图来选择联系人:

    int REQUEST_ID_CONTACT_PICKER = 1001;
    Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
    startActivityForResult(contactPickerIntent, REQUEST_ID_CONTACT_PICKER); 
    

    相比onActivityResult,我们在data中获取URI:

    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        Contact contact = null;
        if (resultCode == Activity.RESULT_OK) {
          switch (requestCode) {
            case REQUEST_ID_CONTACT_PICKER :
              try {
                Uri contactURI = intent.getData();
                contact = fetchAndBuildContact(getApplicationContext(), contactURI);
                Log.d(LOG_TAG, "Pick contact sucessfully!!"+contact.toString());
              }
              catch (Exception e) {
                Log.e(LOG_TAG, "Failed to pick contact!!");
                e.printStackTrace();
              }
              break;
          }
        } else {
          Log.e(LOG_TAG, "Failed to pick contact!!");
        }
      }
    

    我们不需要查找 LookUpKey,它有助于获取任何 Mime 类型的数据:

      private Contact fetchAndBuildContact(Context ctx, Uri uriContact){
          // Getting cursorLookUpKey because contacts ID may not be correct all the time.
          Cursor cursorLookUpKey = ctx.getContentResolver().query(uriContact, new String[]{ContactsContract.Data.LOOKUP_KEY}, null, null, null);
          Contact contact = null;
          String lookupKey = null;
          if (cursorLookUpKey.moveToFirst()) {
              lookupKey = cursorLookUpKey.getString(cursorLookUpKey.getColumnIndex(ContactsContract.Data.LOOKUP_KEY));
              if(null != lookupKey ){
                  contact = new Contact();
                  contact = buildConactPhoneDetails(lookupKey, ctx, contact);
                  contact = buildEmailDetails(lookupKey, ctx, contact);
                  contact = buildAddressDetails(lookupKey, ctx, contact);
              }
          }
          cursorLookUpKey.close();
          return contact;
      }
    

    这就是我们使用ContactsContract.Data.MIMETYPE = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE获取电话详细信息的方法:

    private Contact buildConactPhoneDetails(String lookupKey, Context ctx, final Contact contact) {
          ContentResolver contentResolver = ctx.getContentResolver();
          String contactWhere = ContactsContract.Data.LOOKUP_KEY + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?"; 
          String[] contactWhereParams = new String[]{lookupKey, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE};
          Cursor cursorPhone = contentResolver.query(ContactsContract.Data.CONTENT_URI, null, contactWhere, contactWhereParams, null);
          if (cursorPhone.getCount() > 0) {
                if (cursorPhone.moveToNext()) {
                    if (Integer.parseInt(cursorPhone.getString(cursorPhone.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                        String givenName = cursorPhone.getString(cursorPhone.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                        String familyName = cursorPhone.getString(cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
                        String middleName = cursorPhone.getString(cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME));
                        int contactType = cursorPhone.getInt(cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
                        String phoneNo = cursorPhone.getString(cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        contact.contactNumber = phoneNo;
                        contact.givenName = givenName;
                        contact.familyName = familyName;
                        contact.middleName = middleName;
                        contact.contactType = contactType;
                    }
                }
          }
          cursorPhone.close();
          return contact;
      }
    

    这就是我们使用ContactsContract.Data.MIMETYPE = ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE获取电子邮件详细信息的方法:

      private Contact buildEmailDetails (String lookupKey, Context ctx, final Contact contact) {
          ContentResolver contentResolver = ctx.getContentResolver();
          String emailWhere = ContactsContract.Data.LOOKUP_KEY+ " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?"; 
          String[] emailWhereParams = new String[]{lookupKey, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE};
          Cursor emailCursor = contentResolver.query(ContactsContract.Data.CONTENT_URI, null, emailWhere, emailWhereParams, null); 
          if (emailCursor.moveToNext()) { 
              String emailId = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
              contact.emailId = emailId;
          } 
          emailCursor.close();
          return contact;
      }
    

    这就是我们使用ContactsContract.Data.MIMETYPE = ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE获取PhoneDetails的方法:

      private Contact buildAddressDetails(String lookupKey, Context ctx, final Contact contact) {
        ContentResolver contentResolver = ctx.getContentResolver();
        String addrWhere = ContactsContract.Data.LOOKUP_KEY + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?"; 
        String[] addrWhereParams = new String[]{lookupKey, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE}; 
        Cursor addrCursor = contentResolver.query(ContactsContract.Data.CONTENT_URI, null, addrWhere, addrWhereParams, null); 
        if (addrCursor.moveToNext()) {
            String poBox = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POBOX));
            String street = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
            String city = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
            String state = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
            String postalCode = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE));
            String country = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY));
            String neighborhood = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.NEIGHBORHOOD));
            String formattedAddress = addrCursor.getString(addrCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS));
    
            contact.poBox = poBox;
            contact.street = street;
            contact.city = city;
            contact.state = state;
            contact.zipcode = postalCode;
            contact.country = country;
            contact.street = street;
            contact.neighborhood = neighborhood;
            contact.poBox = poBox;
            contact.formattedAddress = formattedAddress;
        }
        addrCursor.close();
        return contact;
      }
    

    这是 Contact POJO 类,我们在上面的代码中创建:

    public class Contact {
        String country;
        String poBox;
        String givenName;
        String middleName;
        String familyName;
        String address;
        String city;
        String state;
        String street;
        String zipcode;
        String emailId;
        String contactNumber;
        String neighborhood;
        String formattedAddress;
        String label;
        int contactType;
    }
    

    【讨论】:

    • 这段代码不错,谢谢分享!值得更多的支持。
    • 最佳答案:) 谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    相关资源
    最近更新 更多