Android读取短信和联系人

  |   0 评论   |   0 浏览   |   夜雨飘零

读取短信和联系人经常会用到,要了解的是这是内容提供者(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 + '\'' +
                '}';
    }
}

最后别忘了加上权限

<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 个表中分别提取对应的姓名、电话号码、邮箱

项目源代码:https://resource.doiduoyi.com/#7y85q8m


标题:Android读取短信和联系人
作者:夜雨飘零
地址:https://blog.doiduoyi.com/articles/1584877543084.html

评论

发表评论