使用 Intent.ACTION_PICK 读取电话号码和地址

Posted

技术标签:

【中文标题】使用 Intent.ACTION_PICK 读取电话号码和地址【英文标题】:Read phone number along with address using 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 列中获取手机号码,即 错了。

【问题讨论】:

【参考方案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;

【讨论】:

这段代码不错,谢谢分享!值得更多的支持。 最佳答案:) 谢谢

以上是关于使用 Intent.ACTION_PICK 读取电话号码和地址的主要内容,如果未能解决你的问题,请参考以下文章

Intent.ACTION_GET_CONTENT 和 Intent.ACTION_PICK 之间的区别

Android MediaStore.ACTION_IMAGE_CAPTURE 和 Intent.ACTION_PICK

ACTION_PICK 与通讯录一起使用

使用隐式意图读取库文件夹

使用电话号码选择联系人而不是读取电话号码时出现问题

Android中的图像上传