今天我们来讲解一下如何利用ContentProvider机制读写联系人信息。
content://com.scott.book.BookProvider/books
而要从图书数据库中获取指定图书(比如23号图书),需要使用类似以下形式的URI:
content://com.scott.book.BookProvider/books/23
注:ContentProvider是一个抽象类,定义了一系列操作数据的方法模板,BookProvider需要实现这些方法,实现图书信息的各种操作。
那么,现在知道了具体的URI之后,我们又如何操作进而取得数据呢?
在Android中,联系人的操作都是通过一个统一的途径来读写数据的,我们打开/data/data/com.android.providers.contacts可以看到联系人的数据源:
有兴趣的朋友可以导出这个文件,用专业的工具软件打开看一下表结构。
对这个SQLite类型的数据源的封装后,联系人就以ContentProvider的形式为其他应用进程提供联系人的读写服务,我们就可以顺利成章的操作自己的联系人信息了。
有兴趣的朋友还可以读一下源代码,不过比较多,而且内部类使用的特别多,读起来有一定的困难,还是要做好心理准备。
下面我们通过一个项目,来演示一下联系人操作的具体过程。新建一个名为provider的项目,创建一个名为ContactsReadTest的测试用例,如下:
- package com.scott.provider;
- import java.util.ArrayList;
- import android.content.ContentResolver;
- import android.database.Cursor;
- import android.net.Uri;
- import android.provider.ContactsContract;
- import android.test.AndroidTestCase;
- import android.util.Log;
- public class ContactsReadTest extends AndroidTestCase {
- private static final String TAG = "ContactsReadTest";
- //[content://com.android.contacts/contacts]
- private static final Uri CONTACTS_URI = ContactsContract.Contacts.CONTENT_URI;
- //[content://com.android.contacts/data/phones]
- private static final Uri PHONES_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
- //[content://com.android.contacts/data/emails]
- private static final Uri EMAIL_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
- private static final String _ID = ContactsContract.Contacts._ID;
- private static final String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
- private static final String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
- private static final String CONTACT_ID = ContactsContract.Data.CONTACT_ID;
- private static final String PHONE_NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
- private static final String PHONE_TYPE = ContactsContract.CommonDataKinds.Phone.TYPE;
- private static final String EMAIL_DATA = ContactsContract.CommonDataKinds.Email.DATA;
- private static final String EMAIL_TYPE = ContactsContract.CommonDataKinds.Email.TYPE;
- public void testReadContacts() {
- ContentResolver resolver = getContext().getContentResolver();
- Cursor c = resolver.query(CONTACTS_URI, null, null, null, null);
- while (c.moveToNext()) {
- int _id = c.getInt(c.getColumnIndex(_ID));
- String displayName = c.getString(c.getColumnIndex(DISPLAY_NAME));
- Log.i(TAG, displayName);
- ArrayList<String> phones = new ArrayList<String>();
- ArrayList<String> emails = new ArrayList<String>();
- String selection = CONTACT_ID + "=" + _id; //the 'where' clause
- //获取手机号
- int hasPhoneNumber = c.getInt(c.getColumnIndex(HAS_PHONE_NUMBER));
- if (hasPhoneNumber > 0) {
- Cursor phc = resolver.query(PHONES_URI, null, selection, null, null);
- while (phc.moveToNext()) {
- String phoneNumber = phc.getString(phc.getColumnIndex(PHONE_NUMBER));
- int phoneType = phc.getInt(phc.getColumnIndex(PHONE_TYPE));
- phones.add(getPhoneTypeNameById(phoneType) + " : " + phoneNumber);
- }
- phc.close();
- }
- Log.i(TAG, "phones: " + phones);
- //获取邮箱
- Cursor emc = resolver.query(EMAIL_URI,null, selection, null, null);
- while (emc.moveToNext()) {
- String emailData = emc.getString(emc.getColumnIndex(EMAIL_DATA));
- int emailType = emc.getInt(emc.getColumnIndex(EMAIL_TYPE));
- emails.add(getEmailTypeNameById(emailType) + " : " + emailData);
- }
- emc.close();
- Log.i(TAG, "emails: " + emails);
- }
- c.close();
- }
- private String getPhoneTypeNameById(int typeId) {
- switch (typeId) {
- case ContactsContract.CommonDataKinds.Phone.TYPE_HOME: return "home";
- case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE: return "mobile";
- case ContactsContract.CommonDataKinds.Phone.TYPE_WORK: return "work";
- default: return "none";
- }
- }
- private String getEmailTypeNameById(int typeId) {
- switch (typeId) {
- case ContactsContract.CommonDataKinds.Email.TYPE_HOME: return "home";
- case ContactsContract.CommonDataKinds.Email.TYPE_WORK: return "work";
- case ContactsContract.CommonDataKinds.Email.TYPE_OTHER: return "other";
- default: return "none";
- }
- }
- }
最后,还有一个重要的声明需要配置,就是读取联系人权限,声明如下:
经过以上准备工作,这个测试用例就可以运转起来了,我们运行一下testReadContacts()方法,打印结果如下:
接下来我们将要尝试将一个联系人信息添加到系统联系人的数据源中,实现对联系人的写入操作。我们新建一个名为ContactsWriteTest的测试用例,如下:
- package com.scott.provider;
- import java.util.ArrayList;
- import android.content.ContentProviderOperation;
- import android.content.ContentProviderResult;
- import android.content.ContentResolver;
- import android.net.Uri;
- import android.provider.ContactsContract;
- import android.test.AndroidTestCase;
- import android.util.Log;
- public class ContactsWriteTest extends AndroidTestCase {
- private static final String TAG = "ContactsWriteTest";
- //[content://com.android.contacts/raw_contacts]
- private static final Uri RAW_CONTACTS_URI = ContactsContract.RawContacts.CONTENT_URI;
- //[content://com.android.contacts/data]
- private static final Uri DATA_URI = ContactsContract.Data.CONTENT_URI;
- private static final String ACCOUNT_TYPE = ContactsContract.RawContacts.ACCOUNT_TYPE;
- private static final String ACCOUNT_NAME = ContactsContract.RawContacts.ACCOUNT_NAME;
- private static final String RAW_CONTACT_ID = ContactsContract.Data.RAW_CONTACT_ID;
- private static final String MIMETYPE = ContactsContract.Data.MIMETYPE;
- private static final String NAME_ITEM_TYPE = ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE;
- private static final String DISPLAY_NAME = ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME;
- private static final String PHONE_ITEM_TYPE = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
- private static final String PHONE_NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
- private static final String PHONE_TYPE = ContactsContract.CommonDataKinds.Phone.TYPE;
- private static final int PHONE_TYPE_HOME = ContactsContract.CommonDataKinds.Phone.TYPE_HOME;
- private static final int PHONE_TYPE_MOBILE = ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE;
- private static final String EMAIL_ITEM_TYPE = ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;
- private static final String EMAIL_DATA = ContactsContract.CommonDataKinds.Email.DATA;
- private static final String EMAIL_TYPE = ContactsContract.CommonDataKinds.Email.TYPE;
- private static final int EMAIL_TYPE_HOME = ContactsContract.CommonDataKinds.Email.TYPE_HOME;
- private static final int EMAIL_TYPE_WORK = ContactsContract.CommonDataKinds.Email.TYPE_WORK;
- private static final String AUTHORITY = ContactsContract.AUTHORITY;
- public void testWriteContacts() throws Exception {
- ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
- ContentProviderOperation operation = ContentProviderOperation.newInsert(RAW_CONTACTS_URI)
- .withValue(ACCOUNT_TYPE, null)
- .withValue(ACCOUNT_NAME, null)
- .build();
- operations.add(operation);
- //添加联系人名称操作
- operation = ContentProviderOperation.newInsert(DATA_URI)
- .withValueBackReference(RAW_CONTACT_ID, 0)
- .withValue(MIMETYPE, NAME_ITEM_TYPE)
- .withValue(DISPLAY_NAME, "Scott Liu")
- .build();
- operations.add(operation);
- //添加家庭座机号码
- operation = ContentProviderOperation.newInsert(DATA_URI)
- .withValueBackReference(RAW_CONTACT_ID, 0)
- .withValue(MIMETYPE, PHONE_ITEM_TYPE)
- .withValue(PHONE_TYPE, PHONE_TYPE_HOME)
- .withValue(PHONE_NUMBER, "01034567890")
- .build();
- operations.add(operation);
- //添加移动手机号码
- operation = ContentProviderOperation.newInsert(DATA_URI)
- .withValueBackReference(RAW_CONTACT_ID, 0)
- .withValue(MIMETYPE, PHONE_ITEM_TYPE)
- .withValue(PHONE_TYPE, PHONE_TYPE_MOBILE)
- .withValue(PHONE_NUMBER, "13034567890")
- .build();
- operations.add(operation);
- //添加家庭邮箱
- operation = ContentProviderOperation.newInsert(DATA_URI)
- .withValueBackReference(RAW_CONTACT_ID, 0)
- .withValue(MIMETYPE, EMAIL_ITEM_TYPE)
- .withValue(EMAIL_TYPE, EMAIL_TYPE_HOME)
- .withValue(EMAIL_DATA, "scott@android.com")
- .build();
- operations.add(operation);
- //添加工作邮箱
- operation = ContentProviderOperation.newInsert(DATA_URI)
- .withValueBackReference(RAW_CONTACT_ID, 0)
- .withValue(MIMETYPE, EMAIL_ITEM_TYPE)
- .withValue(EMAIL_TYPE, EMAIL_TYPE_WORK)
- .withValue(EMAIL_DATA, "scott@msapple.com")
- .build();
- operations.add(operation);
- ContentResolver resolver = getContext().getContentResolver();
- //批量执行,返回执行结果集
- ContentProviderResult[] results = resolver.applyBatch(AUTHORITY, operations);
- for (ContentProviderResult result : results) {
- Log.i(TAG, result.uri.toString());
- }
- }
- }
经过以上步骤之后,我们运行一下testWriteContacts()方法,看看联系人是否添加进去了:
来源:http://blog.csdn.net/liuhe688/article/details/7006556