联系人数据读取

QuibblerQuibbler 2020-05-29 约 12 分钟 1622 次阅读

联系人数据读取

之前介绍了Android短信的操作(短信操作:原来用户隐私这么容易暴露)。这回来看看联系人数据的获取,首先需要申请读取联系人的权限:

<!-- 读联系人的权限 -->
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <!-- 写联系人的权限 -->
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />

1、ContactsProvider

联系人相关的内容提供程序在/packages/providers/ContactsProvider中。/packages/providers/还有其它类型(比如:短信、多媒体等)的内容提供器。

1.1、ContactsProvider2

其中ContactsProvider2继承AbstractContactsProvider实现联系人数据的增删改查功能。近万行代码实现联系人的增删改查Provider。

public class ContactsProvider2 extends AbstractContactsProvider implements OnAccountsUpdateListener {
        ...
    }

AbstractContactsProvider又继承了ContentProvider。

public abstract class AbstractContactsProvider extends ContentProvider
        implements SQLiteTransactionListener {
        ...
    }

2、ContactsContract

定义在framework层:/frameworks/base/core/java/android/provider/,提供给开发者使用。

2.1、ContactsContract

ContactsContract.java,定义了联系人Uri、及联系人相关数据库字段。以前还有一个Contacts类,但是该类已经被标记为deprecated,重构之后该类移到ContactsContract中成为一个静态内部类。


2.2、ContactsContract.Contacts

Contacts静态内部类定义了联系人相关数据库字段。

2.3、ContactsContract.CommonDataKinds

CommonDataKinds类定义了联系人存储的各种类别的信息,比如电话号码、地址、邮箱、网站等信息。通常先从Contacts表中获取联系人的id,再来这个表中查询联系人的数据信息。

3、查询

查询联系人。

3.1、Uri

ContactsContract中定义的最基本的Uri。

/** 联系人提供者的authority */
    public static final String AUTHORITY = "com.android.contacts";
    
    /** A content:// style uri to the authority for the contacts provider */
    public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);

各个子表都有自己的Uri字段,可以直接使用:

①ContactsContract.Contacts.CONTENT_URI:查询联系人表

②ContactsContract.CommonDataKinds.Phone.CONTENT_URI:该表与关联的原始联系人和汇总联系人数据结合在一起。

3.2、常用字段

①ContactsContract.Contacts._ID:联系人id

②ContactsContract.Contacts.DISPLAY_NAME:联系人姓名

③ContactsContract.CommonDataKinds.Phone.NUMBER:电话号码,同一个联系人可以有多个电话号码

④ContactsContract.CommonDataKinds.Phone.CONTACT_ID:对应上面联系人的_ID

3.3、模糊查询

借助SQL查询语句即可完成搜索,比起先查询到所有数据再进行匹配搜索更直接。查询数据库的时候使用like关键字查询短信数据

Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, 
                                                  null,
                                                  ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " like ? ",
                                                  new String[]{"%" + inputName + "%"}, 
                                                  null);

3.4、完整查询代码段

获取联系人数据的代码段:

ContentResolver contentResolver = getContentResolver();
    if (null == contentResolver) {
        return;
    }
    
    Uri uri = ContactsContract.Contacts.CONTENT_URI;
    String[] contactProjection = new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};
    Cursor cursor = contentResolver.query(uri, contactProjection, null, null, null);
    if (null != cursor) {
        if (cursor.moveToFirst()) {
            do {
                //联系人姓名
                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY));
                //联系人表中的_id
                String _id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
                
                //前面获取到联系人的_id,再来查询获取联系人所有号码
                String[] phoneProjection = new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER};
                String phoneSelection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?";
                String[] phoneSelectionArgs = new String[]{String.valueOf(_id)};
                Cursor phoneCursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
                                                           phoneProjection, phoneSelection, phoneSelectionArgs, null);
                if (null != phoneCursor && phoneCursor.moveToFirst()) {
                    do {
                        String number = phoneCursor.getString(phoneCursor
                                                             .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        Log.d("ContactActivity_TAG", "联系人名:" + name + "\t_id:" + _id + "\tnumber : " + number);
                    } while (phoneCursor.moveToNext());
                    phoneCursor.close();
                }
                
            } while (cursor.moveToNext());
        }
        cursor.close();
    }


相关博客:

        Android联系人详解

        Android读取通讯录数据

        Android 联系人数据库介绍以及对联系人的基本操作

        Android 联系人数据库表详解

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w