记录笔记,需要使用时方便查阅。
简单三步获取手机联系人
通过源码可知手机联系人数据库的位置:/data/data/com.android.providers.contacts/databases/contacts2.db
没有root的手机是访问不了这个目录的
不过我们并不需要关系这个,因为Android已经将这个数据库通过内容提供者暴露出来了,我们直接使用即可。
导出后只需要关注三个表即可:
data表:
data1列用来存储所有联系人的信息,,然后通过raw_contact_id列区分用户,mimetype_id列区分手机还是姓名等信息
mimetypes表:
通过id区分数据类型
raw_contacts表:
记录用户编号个数
以上是联系人数据库的结构,下面直接上代码,3步即可实现功能:
1)先定义一个实体类存放联系人数据,需要哪些数据就加哪些字段
/**
* 联系人的实体类
*/
public class Contact {
private String id;
private String name;
private String email;
private String phone;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "Contact [id=" + id + ", name=" + name + ", email=" + email
+ ", phone=" + phone + "]";
}
2)通过内容解析者获取联系人信息
public static ArrayList<Contact> queryContact(Context context){
ArrayList<Contact> contactLists =new ArrayList<Contact>();
//(1)先查询Contacts中contact_id列
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri = Uri.parse("content://com.android.contacts/data");
Cursor cursor = context.getContentResolver().query(uri, new String[]{"contact_id"}, null, null, null);
while(cursor.moveToNext()){
String contact_id = cursor.getString(0);
if (contact_id!=null) {
Contact contact = new Contact();
contact.setId(contact_id);
//(2)通过contact_id 查询data表中data1列和mimetype_id列
// (注意:data表中没有mimetype_id这一列,data视图已经合并完数据字段,所以直接查询mimetype列)
Cursor dataCursor = context.getContentResolver().query(dataUri, new String[]{"data1","mimetype"}, "raw_contact_id=?", new String[]{contact_id}, null);
while(dataCursor.moveToNext()){
String data1 = dataCursor.getString(0);
String mimetype = dataCursor.getString(1);
//(3)通过mimetype列的类型判断data1数据具体是名称还是手机号,需要哪些数据可对照表中数据添加判断
if ("vnd.android.cursor.item/email_v2".equals(mimetype)) {
contact.setEmail(data1);
}else if ("vnd.android.cursor.item/name".equals(mimetype)) {
contact.setName(data1);
}else if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {
contact.setPhone(data1);
}
}
//将 Contact对象添加到集合中
contactLists.add(contact);
}
}
return contactLists;
}
3)在activity中获取数据
public class MainActivity extends Activity {
public static final int REQUEST_READ_CONTACTS = 0x10112; //读取联系人
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(checkReadPermission(Manifest.permission.READ_CONTACTS, REQUEST_READ_CONTACTS)){
getContacts();
}
}
/**
* 6.0+检测权限
* @param string_permission
* @param request_code
* @return
*/
public boolean checkReadPermission(String string_permission,int request_code) {
boolean flag = false;
if (ContextCompat.checkSelfPermission(this, string_permission) == PackageManager.PERMISSION_GRANTED) {//已有权限
flag = true;
} else {//申请权限
ActivityCompat.requestPermissions(this, new String[]{string_permission}, request_code);
}
return flag;
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_READ_CONTACTS:
if (permissions.length != 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {//失败
Toast.makeText(this,"请允许获取联系人权限后再试",Toast.LENGTH_SHORT).show();
} else {
getContacts();
}
break;
}
}
/**
* 获取联系人信息
*/
private void getContacts() {
List<Contact> queryContacts = QueryContactUtils.queryContact(this);
for (Contact contact : queryContacts) {
System.out.println("Contact:"+contact);
}
}
}
最后记得在清单文件中配置联系人权限:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
以作备忘,方便以后使用时翻阅。