Retrieving Details for a Contact

这部分展示怎么获得一个详细的联系人信息,比如email,电话号码等。你可以显示全部信息,也可以显示部分信息,比如单单email。

这里假设你有一列ContactsContract.Contacts。

Retrieve all Details for a Contact (获得联系人所有的详细信息)

通过在ContactsContract.Data表格中查找包含列LOOKUP_KEY中匹配的行,返回查找的信息已获取联系人详细信息。由于ContactsContract.Contacts表格和ContactsContract.Data表格之间已经关联号,所以对应的列存在ContactsContract.Data中。在Retriving Contact Names中有详细介绍了LOOKUP_KEY

注意:获得一个联系人的详细信息会影响设备的性能,因为需要从ContactsContract.Data表格中获得所有的列,在实际应用中要考虑这个影响。

Request permissions (请求权限)

为了从Contact Provider读取数据,必须具备READ_CONTACTS的权限。通过下面代码来获得权限:

<uses-permission android:name="android.permission.READ_CONTACTS" />


Set up a projection (定义一个投射数组)

每行中可以有多个列,数据根据它们的类型位于不同的列中。为了保证获得所有列的数据类型,你必须在你的投射数据中添加所有的列名。如果你将查询结果用Cursor与ListView绑定,记得要获取联系人的Data._ID,不然无法绑定。为了保证可以分辨出每行的数据类型,添加Data.MIMETYPE。

    private static final String PROJECTION =
            {
                Data._ID,
                Data.MIMETYPE,
                Data.DATA1,
                Data.DATA2,
                Data.DATA3,
                Data.DATA4,
                Data.DATA5,
                Data.DATA6,
                Data.DATA7,
                Data.DATA8,
                Data.DATA9,
                Data.DATA10,
                Data.DATA11,
                Data.DATA12,
                Data.DATA13,
                Data.DATA14,
                Data.DATA15
            };

这个投射数组可以获得ContactsContract.Data的所有列,这些列名都定义在ContactsContract.Data中。

当然你也可以使用其他定义在ContactsContract.Data继承子类中。注意列SYN1到SYN2是为了用于同步的adapter,所以它们的数据没用。

Define the selection criteria (定义选择规则)

定义一个选择规则常量,一个数据用来保存选择的参数,一个变量用来保存选择的值。通过Contacts.LOOKUP_KEY列来查找联系人。

    // Defines the selection clause
    private static final String SELECTION = Data.LOOKUP_KEY + " = ?";
    // Defines the array to hold the search criteria
    private String[] mSelectionArgs = { "" };
    /*
     * Defines a variable to contain the selection value. Once you
     * have the Cursor from the Contacts table, and you've selected
     * the desired row, move the row's LOOKUP_KEY value into this
     * variable.
     */
    private String mLookupKey;

在你的选择表达式中添加”?“以便查找的结果是有绑定生成而不是SQL汇集的。这样可以消除其它SQL无用信息。


Define the sort order (定义排序顺序)

定义在结果的Cursor的排序顺序。为了保证所有相同的数据类型的行都在一块,可以以Data.MIMETYPE排序。这样可以使得所有的email行都在一块,所有的电话行都在一块等。

    /*
     * Defines a string that specifies a sort order of MIME type
     */
    private static final String SORT_ORDER = Data.MIMETYPE;

注意:一些数据类型不适用subtype,所以不同意subtype排序。

Initialize the Loader (初始化Loader)

记得通过另外一个进程从Contact Provider获取数据。可以使用在LoaderManager类和LoaderManager.LoaderCallbacks定义的Loader framework完成获取数据。

当你准备获取对应的行时,调用initLoader(),将一个整型标识符传入这个函数,这个标示符将传入到LoaderManager.LoaderCallbacks函数中。这个标示符可以让你在一个app中使用多个不同的loader。

下面代码展示如何初始化loader framework

public class DetailsFragment extends Fragment implements
        LoaderManager.LoaderCallbacks<Cursor> {
    ...
    // Defines a constant that identifies the loader
    DETAILS_QUERY_ID = 0;
    ...
    /*
     * Invoked when the parent Activity is instantiated
     * and the Fragment's UI is ready. Put final initialization
     * steps here.
     */
    @Override
    onActivityCreated(Bundle savedInstanceState) {
        ...
        // Initializes the loader framework
        getLoaderManager().initLoader(DETAILS_QUERY_ID, null, this);

Implement onCreateLoader() (实现onCreateLoader()函数)

当你调用initLoader后,系统会调用onCreateLoader()函数。在这个函数中返回一个CursorLoader。使用Data.CONTENT_URI作为content URI。

    @Override
    public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
        // Choose the proper action
        switch (loaderId) {
            case DETAILS_QUERY_ID:
            // Assigns the selection parameter
            mSelectionArgs[0] = mLookupKey;
            // Starts the query
            CursorLoader mLoader =
                    new CursorLoader(
                            getActivity(),
                            Data.CONTENT_URI,
                            PROJECTION,
                            SELECTION,
                            mSelectionArgs,
                            SORT_ORDER
                    );
            ...
    }


Implement onLoadFinished() and onLoaderReset() (实现onLoadFinished()和onLoaderReset()函数)

当Contracts Provider返回查找的结果时,loader framework会调用onLoadFinished()函数:

    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        switch (loader.getId()) {
            case DETAILS_QUERY_ID:
                    /*
                     * Process the resulting Cursor here.
                     */
                }
                break;
            ...
        }
    }
当loader framework发现返回的Cursor变化是,会调用onLoaderReset()函数。在这个函数中,记得将Cursor对应的引用设为null,不然回收器将不会回收这个老的cursor。

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        switch (loader.getId()) {
            case DETAILS_QUERY_ID:
                /*
                 * If you have current references to the Cursor,
                 * remove them here.
                 */
                }
                break;
    }

Retrieve Specific Details for a Contact (获取联系人的特定信息)

可以通过下面步骤获取联系人信息的特定项。

Projection (投射)

将你的投射数组改为你想获得的数据类型所在的列。使用定义在ContactsContract.CommonDataKinds子类中定义的数据类型名。

Selection (选择)

修改选择文本为你想要查找的数据类型对应的MIMETYPE

Sort order (排列顺序)

不需要按组将返回的Cursor排序

下面展示这些变化

Define a projection (定义一个投射数组)

使用ContactsContract.CommonDataKinds子类定义的你想要的数据类型的列名。如果你想将查找结果通过Cursor与ListView绑定,记得添加_ID列。下面例子展示获取email对应的projection:

    private static final String[] PROJECTION =
            {
                Email._ID,
                Email.ADDRESS,
                Email.TYPE,
                Email.LABEL
            };

注意这里使用的是类ContactsContract.CommonDataKinds定义的列名,而不是ContactsContract.Data定义的。对于列名,你也可以使用定义在ContactsContract.CommonDataKinds子类定义的。

Define selection criteria (定义选择规则)

定义查找的文本表达式,以便获取指定的LOOKUP_KEY和Data.MIMETYPE联系人所在的行。将MIMETYPE放在单引号内以区分边界,不然provider将会把这个常量解析成变量而不是一个字符串值。

    /*
     * Defines the selection clause. Search for a lookup key
     * and the Email MIME type
     */
    private static final String SELECTION =
            Data.LOOKUP_KEY + " = ?" +
            " AND " +
            Data.MIMETYPE + " = " +
            "'" + Email.CONTENT_ITEM_TYPE + "'";
    // Defines the array to hold the search criteria
    private String[] mSelectionArgs = { "" };

Define a sort order (定义排列顺序)

由于你获取的是指定的数据类型,因此不用排序,但是当你查找的数据中含有subtype,需要排序。比如:

    private static final String SORT_ORDER = Email.TYPE + " ASC ";




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值