使用 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