Android 选取手机联系人

在日常的手机开发中,经常会有获取手机联系人的需求。我之前写过一篇关于通过 ContentProvider<博客链接> 操作联系人数据库的博客,里面主要是通过匹配规则和开放的数据操作接口进行数据库的操作。

不过除了要对整个联系人或者短信数据库进行备份外,一般是不会进行删改的操作,而通过选择来拿到某个联系人的手机号码或者邮箱却是一个比较频繁的需求。这里就以该需求出发,实现简洁高效的联系人信息抓取。

打开联系人选择列表

在使用支付宝进行转账或者充值的时候,可以直接打开联系人列表进行选择目标联系人,点击后就可以自动填充联系人手机号码。我们的目标就是实现同样的功能。

事实上这个联系人选择界面并不是由我们自己开发的,而是系统默认会提供给我们的。通过特定的意图(Intent)就可以开启这个界面。通常这个界面被称为 Android Contact Picker 。

1
2
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(intent, CODE_PICK_CONTACTS);

其中 CODE_PICK_CONTACTS 定义的一个Int类型的常量,用于表示请求码。

执行了这段逻辑就会打开一个联系人选择界面,通过点击就可以选择你的目标联系人。如果该联系人有多个手机号码,这个界面也会弹出对话框叫你选择,免去了我们自己实现逻辑的麻烦。


根据返回值进行操作

注意上面我们是使用 startActivityForResult 这个方法打开一个Activity的,因为我们需要拿到返回的字段,如姓名,手机号,邮箱等。

那么就重写 onActivityResult 将需要的字段显示出来:

1
2
3
4
5
6
7
8
9
10
11
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case (CODE_PICK_CONTACTS):
String phone=ContactInfoUtils.getPickPhoneNumber(this,data.getData());
break;
}
}
}

这里我将具体的获得联系人信息的逻辑进行了简单的封装,便于其他地方进行调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static ContactInfo getPickContact(Context context, Uri uri) {
ContactInfo info = new ContactInfo();
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
String num = "";
if (cursor != null && cursor.moveToNext()) {
info.id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
info.name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
num = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//替换掉不合法的字符
num = num.replace("-", "");
num = num.replace(" ", "");
info.phone = num;
cursor.close();
}

Cursor emailCur = context.getContentResolver().query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = "+info.id,
null, null);
if (emailCur != null) {
while (emailCur.moveToNext()) {
info.email = emailCur.getString(
emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
}
emailCur.close();
}
Log.d("getPickContact", "ID:" + info.id + " name:" + info.name + " num:" + info.phone + " email:" + info.email);
return info;
}

内部类:

1
2
3
4
5
6
public static class ContactInfo {
public String id;
public String name;
public String phone;
public String email;
}

运行后打印的日志如下:

D/getPickContact: ID:1 name:gyq num:12345678 email:gyq@qq.com

以上结果是在虚拟机中运行获得的。而在我的htc m7 中实测是不能获得邮件地址的,得到仍然是电话号码。手头上没有其他实体机器,目前还无法验证是不是仅在虚拟机中有效。