Android读取短信和联系人
程序员文章站
2022-05-31 11:45:43
...
读取短信和联系人经常会用到,要了解的是这是内容提供者(contentProvider)的知识点,大家都知道数据库是在data-->data 对应的包目录下,其他应用是不可以访问到的,如果有些数据要提供给其他的应用,比如通信录,其他应用想获取它的数据怎么办呢,这时内容提供者就出现了,预先写好了一些操作数据库的方法,因为方法是开发这个应用的开发者提供的,所以保证了数据库的安全操作,又能共享数据。
短信
开始切入正题,先说短信,要从数据库中获取数据,就要了解其结构
短信数据库在data-->data中的下面路径
它的表结构如下,有3个是我们要注意的,这3个是我们待会要用到的,其中date是毫秒值
Java代码为
//获取内容提供者
ContentResolver contentResolver = getContentResolver();
//获取短信表的路径
Uri uri = Uri.parse("content://sms");
//设置要查询的列名
String[] line = {"address", "date", "body"};
//各个参数的意思,路径、列名、条件、条件参数、排序
Cursor cursor = contentResolver.query(uri, line, null, null, null);
//下面就跟操作普通数据库一样了
if (cursor != null) {
while (cursor.moveToNext()) {
String address = cursor.getString(cursor.getColumnIndex("address"));
String date = cursor.getString(cursor.getColumnIndex("date"));
String body = cursor.getString(cursor.getColumnIndex("body"));
Log.e("短信", "address:" + address + "\ndate:" + date + "\nbody:" + body);
}
cursor.close();
}
联系人
获取联系人就比较复杂了,其表结构也比较复杂,我们获取联系人的姓名、电话号码、邮箱,要通过3张表去提取
数据库所在位置data-->data中的下面路径
data表,这个表中的“data1”列几乎包含了我们想要的数据,但是如何通过分类提取,第四列的代号说明了data1数据的类型,这些代号在mimetypes表中有对应的说明,要找到这些数据,又要通过raw_contact_id去查找,这些ID又来于raw_contacts表中
mimetypes表,对代号类型的说明
raw_contacts表,我们通信录中要显示的信息必须要在这里找到对应的ID,当我们删除了联系人,data表中的数据并没有删除,只是删除了证张表contact_id变为null,而不是真的删除
了解其表结构后,就开始写代码了
//获取内容提供者
ContentResolver contentResolver = getContentResolver();
//获取raw_contacts表的路径
Uri raw_contact_uri = Uri.parse("content://com.android.contacts/raw_contacts");
//各个参数的意思,路径、列名、条件、条件参数、排序
Cursor contactId = contentResolver.query(raw_contact_uri, new String[]{"contact_id"}, null, null, null);
//下面就跟操作普通数据库一样了
if (contactId != null) {
while (contactId.moveToNext()) {
//获取contact_id的值,它对应data表中raw_contact_id的值
String id = contactId.getString(contactId.getColumnIndex("contact_id"));
//获取data表的路径
Uri data_uri = Uri.parse("content://com.android.contacts/data");
//各个参数的意思,路径、列名、条件、条件参数、排序
Cursor dataCursor = contentResolver.query(data_uri, new String[]{"mimetype", "data1"},
"raw_contact_id=?", new String[]{id}, null);
if (dataCursor != null) {
//每次循环创建一个实例用于保存data表中的数据
ContactsData contactsData = new ContactsData();
while (dataCursor.moveToNext()) {
String type = dataCursor.getString(dataCursor.getColumnIndex("mimetype"));
switch (type) {
case "vnd.android.cursor.item/email_v2":
//这是邮箱信息
contactsData.setEmail(dataCursor.getString(dataCursor.getColumnIndex("data1")));
break;
case "vnd.android.cursor.item/phone_v2":
//这是手机号码信息
contactsData.setNumber(dataCursor.getString(dataCursor.getColumnIndex("data1")));
break;
case "vnd.android.cursor.item/name":
//这是联系人的名字
contactsData.setName(dataCursor.getString(dataCursor.getColumnIndex("data1")));
break;
}
}
//把查询到的信息添加到集合中
contactsDatas.add(contactsData);
dataCursor.close();
}
}
contactId.close();
}
Log.d("测试","开始打印");
public class ContactsData {
private String email;
private String number;
private String name;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "ContactsData{" +
"email='" + email + '\'' +
", number='" + number + '\'' +
", name='" + name + '\'' +
'}';
}
}
for (ContactsData c : contactsDatas) { Log.e("联系人", c.toString()); }
为了方便管理创建一个Javabean
public class ContactsData {
private String email;
private String number;
private String name;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "ContactsData{" +
"email='" + email + '\'' +
", number='" + number + '\'' +
", name='" + name + '\'' +
'}';
}
}
最后别忘了加上权限
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
如过是Android 6.0以上的版本还要动态获取权限
获取联系人的效果图
真正应用
通常不会这样直接写它的路径的,因为手机厂商会修改它的路径,还是这样写的话会报错,说不存在这一列,需要使用Android提供的API
/**
* 通过ContactsContract.Contacts.CONTENT_URI来获取_ID和DISPLAY_NAME
* _ID 该联系人的索引
* 通过这个ID可以在ContactsContract.CommonDataKinds.Phone.CONTENT_URI 中找到该联系人的电话号码
* 通过这个ID可以在ContactsContract.CommonDataKinds.Email.CONTENT_URI 找到该联系人的邮箱
* DISPLAY_NAME 是该联系人的姓名
*/
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
ContactsData contactsData = new ContactsData();
//获取该联系人的ID
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
//该联系人的姓名
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contactsData.setName(name);
/**
* 查找该联系人的phone信息
* 在ContactsContract.CommonDataKinds.Phone.CONTENT_URI 中查询
* 条件为ContactsContract.CommonDataKinds.Phone.CONTACT_ID = 上面查询到的ID
*/
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);
if (phones != null && phones.moveToNext()) {
//获取该联系人的手机号码
String number = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contactsData.setNumber(number);
phones.close();
}
/**
* 查找该联系人的email信息
* 在ContactsContract.CommonDataKinds.Email.CONTENT_URI 中查询
* 条件为ContactsContract.CommonDataKinds.Phone.CONTACT_ID = 上面查询到的ID
*/
Cursor emails = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + "=" + contactId, null, null);
if (emails != null && emails.moveToNext()) {
//获取该联系人的邮箱
String email = emails.getString(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
contactsData.setEmail(email);
emails.close();
}
contactsDatas.add(contactsData);
}
cursor.close();
}
Log.d("测试","开始打印");
for (ContactsData c : contactsDatas) {
Log.e("联系人", c.toString());
}
看起来好像有点复杂,我们先看看下面的图片再去看代码,可能会容易理解,这些代码一共操作了3个表,严格来说是视图,在这3个表中获得他们共同的ID,根据ID在这3个表中分别提取对应的姓名、电话号码、邮箱
项目源代码:http://download.csdn.net/download/qq_33200967/9929430