Android读取、增删联系人(二)

本文仅做我本人的学习笔记 以防自己找不到几位前辈的写的资料 想看原文的可以点击本文链接

原博客地址这里

1.查找、增加、删除、修改联系人

直接贴代码:

ContactsManager.java


 
 
  1. package com.example.siqi.contacts;
  2. import java.util.ArrayList;
  3. import android.content.ContentProviderOperation;
  4. import android.content.ContentResolver;
  5. import android.database.Cursor;
  6. import android.provider.ContactsContract;
  7. import android.util.Log;
  8. public class ContactsManager {
  9. private ContentResolver contentResolver;
  10. private static final String TAG = "ContactsManager";
  11. /**
  12. * Use a simple string represents the long.
  13. */
  14. private static final String COLUMN_CONTACT_ID =
  15. ContactsContract.Data.CONTACT_ID;
  16. private static final String COLUMN_RAW_CONTACT_ID =
  17. ContactsContract.Data.RAW_CONTACT_ID;
  18. private static final String COLUMN_MIMETYPE =
  19. ContactsContract.Data.MIMETYPE;
  20. private static final String COLUMN_NAME =
  21. ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME;
  22. private static final String COLUMN_NUMBER =
  23. ContactsContract.CommonDataKinds.Phone.NUMBER;
  24. private static final String COLUMN_NUMBER_TYPE =
  25. ContactsContract.CommonDataKinds.Phone.TYPE;
  26. private static final String COLUMN_EMAIL =
  27. ContactsContract.CommonDataKinds.Email.DATA;
  28. private static final String COLUMN_EMAIL_TYPE =
  29. ContactsContract.CommonDataKinds.Email.TYPE;
  30. private static final String MIMETYPE_STRING_NAME =
  31. ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE;
  32. private static final String MIMETYPE_STRING_PHONE =
  33. ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
  34. private static final String MIMETYPE_STRING_EMAIL =
  35. ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;
  36. public ContactsManager(ContentResolver contentResolver) {
  37. this.contentResolver = contentResolver;
  38. }
  39. /**
  40. * Search and fill the contact information by the contact name given.
  41. * @param contact Only the name is necessary.
  42. */
  43. public Contact searchContact(String name) {
  44. Log.w(TAG, "**search start**");
  45. Contact contact = new Contact();
  46. contact.setName(name);
  47. Log.d(TAG, "search name: " + contact.getName());
  48. String id = getContactID(contact.getName());
  49. contact.setId(id);
  50. if(id.equals( "0")) {
  51. Log.d(TAG, contact.getName() + " not exist. exit.");
  52. } else {
  53. Log.d(TAG, "find id: " + id);
  54. //Fetch Phone Number
  55. Cursor cursor = contentResolver.query(
  56. android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
  57. new String[]{COLUMN_NUMBER, COLUMN_NUMBER_TYPE},
  58. COLUMN_CONTACT_ID + "='" + id + "'", null, null);
  59. while(cursor.moveToNext()) {
  60. contact.setNumber(cursor.getString(cursor.getColumnIndex(COLUMN_NUMBER)));
  61. contact.setNumberType(cursor.getString(cursor.getColumnIndex(COLUMN_NUMBER_TYPE)));
  62. Log.d(TAG, "find number: " + contact.getNumber());
  63. Log.d(TAG, "find numberType: " + contact.getNumberType());
  64. }
  65. //cursor.close();
  66. //Fetch email
  67. cursor = contentResolver.query(
  68. android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI,
  69. new String[]{COLUMN_EMAIL, COLUMN_EMAIL_TYPE},
  70. COLUMN_CONTACT_ID + "='" + id + "'", null, null);
  71. while(cursor.moveToNext()) {
  72. contact.setEmail(cursor.getString(cursor.getColumnIndex(COLUMN_EMAIL)));
  73. contact.setEmailType(cursor.getString(cursor.getColumnIndex(COLUMN_EMAIL_TYPE)));
  74. Log.d(TAG, "find email: " + contact.getEmail());
  75. Log.d(TAG, "find emailType: " + contact.getEmailType());
  76. }
  77. cursor.close();
  78. }
  79. Log.w(TAG, "**search end**");
  80. return contact;
  81. }
  82. /**
  83. *
  84. * @param contact The contact who you get the id from. The name of
  85. * the contact should be set.
  86. * @return 0 if contact not exist in contacts list. Otherwise return
  87. * the id of the contact.
  88. */
  89. public String getContactID(String name) {
  90. String id = "0";
  91. Cursor cursor = contentResolver.query(
  92. android.provider.ContactsContract.Contacts.CONTENT_URI,
  93. new String[]{android.provider.ContactsContract.Contacts._ID},
  94. android.provider.ContactsContract.Contacts.DISPLAY_NAME +
  95. "='" + name + "'", null, null);
  96. if(cursor.moveToNext()) {
  97. id = cursor.getString(cursor.getColumnIndex(
  98. android.provider.ContactsContract.Contacts._ID));
  99. }
  100. return id;
  101. }
  102. /**
  103. * You must specify the contact's ID.
  104. * @param contact
  105. * @throws Exception The contact's name should not be empty.
  106. */
  107. public void addContact(Contact contact) {
  108. Log.w(TAG, "**add start**");
  109. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
  110. String id = getContactID(contact.getName());
  111. if(!id.equals( "0")) {
  112. Log.d(TAG, "contact already exist. exit.");
  113. } else if(contact.getName().trim().equals( "")){
  114. Log.d(TAG, "contact name is empty. exit.");
  115. } else {
  116. ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
  117. .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
  118. .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
  119. .build());
  120. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
  121. .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
  122. .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_NAME)
  123. .withValue(COLUMN_NAME, contact.getName())
  124. .build());
  125. Log.d(TAG, "add name: " + contact.getName());
  126. if(!contact.getNumber().trim().equals( "")) {
  127. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
  128. .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
  129. .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_PHONE)
  130. .withValue(COLUMN_NUMBER, contact.getNumber())
  131. .withValue(COLUMN_NUMBER_TYPE, contact.getNumberType())
  132. .build());
  133. Log.d(TAG, "add number: " + contact.getNumber());
  134. }
  135. if(!contact.getEmail().trim().equals( "")) {
  136. ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
  137. .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
  138. .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_EMAIL)
  139. .withValue(COLUMN_EMAIL, contact.getEmail())
  140. .withValue(COLUMN_EMAIL_TYPE, contact.getEmailType())
  141. .build());
  142. Log.d(TAG, "add email: " + contact.getEmail());
  143. }
  144. try {
  145. contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
  146. Log.d(TAG, "add contact success.");
  147. } catch (Exception e) {
  148. Log.d(TAG, "add contact failed.");
  149. Log.e(TAG, e.getMessage());
  150. }
  151. }
  152. Log.w(TAG, "**add end**");
  153. }
  154. /**
  155. * Delete contacts who's name equals contact.getName();
  156. * @param contact
  157. */
  158. public void deleteContact(Contact contact) {
  159. Log.w(TAG, "**delete start**");
  160. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
  161. String id = getContactID(contact.getName());
  162. //delete contact
  163. ops.add(ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI)
  164. .withSelection(ContactsContract.RawContacts.CONTACT_ID+ "="+id, null)
  165. .build());
  166. //delete contact information such as phone number,email
  167. ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
  168. .withSelection(COLUMN_CONTACT_ID + "=" + id, null)
  169. .build());
  170. Log.d(TAG, "delete contact: " + contact.getName());
  171. try {
  172. contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
  173. Log.d(TAG, "delete contact success");
  174. } catch (Exception e) {
  175. Log.d(TAG, "delete contact failed");
  176. Log.e(TAG, e.getMessage());
  177. }
  178. Log.w(TAG, "**delete end**");
  179. }
  180. /**
  181. * @param contactOld The contact wants to be updated. The name should exists.
  182. * @param contactNew
  183. */
  184. public void updateContact(Contact contactOld, Contact contactNew) {
  185. Log.w(TAG, "**update start**");
  186. String id = getContactID(contactOld.getName());
  187. if(id.equals( "0")) {
  188. Log.d(TAG, contactOld.getName()+ " not exist.");
  189. } else if(contactNew.getName().trim().equals( "")){
  190. Log.d(TAG, "contact name is empty. exit.");
  191. } else if(!getContactID(contactNew.getName()).equals( "0")){
  192. Log.d(TAG, "new contact name already exist. exit.");
  193. } else {
  194. ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
  195. //update name
  196. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  197. .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
  198. new String[]{id, MIMETYPE_STRING_NAME})
  199. .withValue(COLUMN_NAME, contactNew.getName())
  200. .build());
  201. Log.d(TAG, "update name: " + contactNew.getName());
  202. //update number
  203. if(!contactNew.getNumber().trim().equals( "")) {
  204. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  205. .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
  206. new String[]{id, MIMETYPE_STRING_PHONE})
  207. .withValue(COLUMN_NUMBER, contactNew.getNumber())
  208. .withValue(COLUMN_NUMBER_TYPE, contactNew.getNumberType())
  209. .build());
  210. Log.d(TAG, "update number: " + contactNew.getNumber());
  211. }
  212. //update email if mail
  213. if(!contactNew.getEmail().trim().equals( "")) {
  214. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  215. .withSelection(COLUMN_CONTACT_ID + "=? AND " + COLUMN_MIMETYPE + "=?",
  216. new String[]{id, MIMETYPE_STRING_EMAIL})
  217. .withValue(COLUMN_EMAIL, contactNew.getEmail())
  218. .withValue(COLUMN_EMAIL_TYPE, contactNew.getEmailType())
  219. .build());
  220. Log.d(TAG, "update email: " + contactNew.getEmail());
  221. }
  222. try {
  223. contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
  224. Log.d(TAG, "update success");
  225. } catch (Exception e) {
  226. Log.d(TAG, "update failed");
  227. Log.e(TAG, e.getMessage());
  228. }
  229. }
  230. Log.w(TAG, "**update end**");
  231. }
  232. }
Contact.java


 
 
  1. package com.example.siqi.contacts;
  2. public class Contact {
  3. private String email;
  4. private String emailType;
  5. private String id;
  6. private String name;
  7. private String number;
  8. private String numberType;
  9. public Contact(){
  10. }
  11. public Contact(Contact contact){
  12. this.name = contact.getName();
  13. this.number = contact.getNumber();
  14. this.numberType = contact.getNumberType();
  15. this.email = contact.getEmail();
  16. this.emailType = contact.getEmailType();
  17. }
  18. public String getEmail() {
  19. return email;
  20. }
  21. public String getEmailType() {
  22. return emailType;
  23. }
  24. public String getId() {
  25. return id;
  26. }
  27. public String getName() {
  28. return name;
  29. }
  30. public String getNumber() {
  31. return number;
  32. }
  33. public String getNumberType() {
  34. return numberType;
  35. }
  36. public void setEmail(String email) {
  37. this.email = email;
  38. }
  39. public void setEmailType(String emailType) {
  40. this.emailType = emailType;
  41. }
  42. public void setId(String id) {
  43. this.id = id;
  44. }
  45. public void setName(String name) {
  46. this.name = name;
  47. }
  48. public void setNumber(String number) {
  49. this.number = number;
  50. }
  51. public void setNumberType(String numberType) {
  52. this.numberType = numberType;
  53. }
  54. }
MainActivity.java


 
 
  1. package com.example.siqi.contacts;
  2. import android.os.Bundle;
  3. import android.app.Activity;
  4. import android.view.Menu;
  5. public class MainActivity extends Activity {
  6. @Override
  7. public void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity_main);
  10. ContactsManager cm = new ContactsManager( this.getContentResolver());
  11. cm.searchContact( "张一");
  12. Contact contact = new Contact();
  13. contact.setName( "张一");
  14. contact.setEmail( "test@test.com");
  15. contact.setNumber( "123456789");
  16. //test addContact
  17. cm.addContact(contact);
  18. cm.searchContact( "张一");
  19. //test updateContact
  20. Contact contactNew = new Contact(contact);
  21. contactNew.setName( "张二");
  22. contactNew.setNumber( "987654321");
  23. contactNew.setEmail( "newEmail@test");
  24. cm.updateContact(contact, contactNew);
  25. cm.searchContact( "张一");
  26. cm.searchContact( "张二");
  27. //test deleteContact
  28. cm.deleteContact(contactNew);
  29. cm.searchContact( "张二");
  30. }
  31. @Override
  32. public boolean onCreateOptionsMenu(Menu menu) {
  33. getMenuInflater().inflate(R.menu.activity_main, menu);
  34. return true;
  35. }
  36. }
项目需要添加权限:

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

结果:


 
 
  1. 11- 07 15: 20: 00.873: W/ContactsManager( 30113): **search start**
  2. 11- 07 15: 20: 00.873: D/ContactsManager( 30113): search name: 张一
  3. 11- 07 15: 20: 00.943: D/ContactsManager( 30113): 张一 not exist. exit.
  4. 11- 07 15: 20: 00.943: W/ContactsManager( 30113): **search end**
  5. 11- 07 15: 20: 00.943: W/ContactsManager( 30113): **add start**
  6. 11- 07 15: 20: 00.973: D/ContactsManager( 30113): add name: 张一
  7. 11- 07 15: 20: 01.004: D/ContactsManager( 30113): add number: 123456789
  8. 11- 07 15: 20: 01.004: D/ContactsManager( 30113): add email: test @test.com
  9. 11- 07 15: 20: 01.224: D/ContactsManager( 30113): add contact success.
  10. 11- 07 15: 20: 01.224: W/ContactsManager( 30113): **add end**
  11. 11- 07 15: 20: 01.224: W/ContactsManager( 30113): **search start**
  12. 11- 07 15: 20: 01.224: D/ContactsManager( 30113): search name: 张一
  13. 11- 07 15: 20: 01.243: D/ContactsManager( 30113): find id: 30
  14. 11- 07 15: 20: 01.273: D/ContactsManager( 30113): find number: 123456789
  15. 11- 07 15: 20: 01.273: D/ContactsManager( 30113): find numberType: null
  16. 11- 07 15: 20: 01.323: D/ContactsManager( 30113): find email: test @test.com
  17. 11- 07 15: 20: 01.323: D/ContactsManager( 30113): find emailType: null
  18. 11- 07 15: 20: 01.334: W/ContactsManager( 30113): **search end**
  19. 11- 07 15: 20: 01.334: W/ContactsManager( 30113): **update start**
  20. 11- 07 15: 20: 01.393: D/ContactsManager( 30113): update name: 张二
  21. 11- 07 15: 20: 01.403: D/ContactsManager( 30113): update number: 987654321
  22. 11- 07 15: 20: 01.403: D/ContactsManager( 30113): update email: newEmail @test
  23. 11- 07 15: 20: 01.723: D/ContactsManager( 30113): update success
  24. 11- 07 15: 20: 01.723: W/ContactsManager( 30113): **update end**
  25. 11- 07 15: 20: 01.723: W/ContactsManager( 30113): **search start**
  26. 11- 07 15: 20: 01.723: D/ContactsManager( 30113): search name: 张一
  27. 11- 07 15: 20: 01.743: D/ContactsManager( 30113): 张一 not exist. exit.
  28. 11- 07 15: 20: 01.743: W/ContactsManager( 30113): **search end**
  29. 11- 07 15: 20: 01.743: W/ContactsManager( 30113): **search start**
  30. 11- 07 15: 20: 01.754: D/ContactsManager( 30113): search name: 张二
  31. 11- 07 15: 20: 01.773: D/ContactsManager( 30113): find id: 30
  32. 11- 07 15: 20: 01.803: D/ContactsManager( 30113): find number: 987654321
  33. 11- 07 15: 20: 01.813: D/ContactsManager( 30113): find numberType: null
  34. 11- 07 15: 20: 01.844: D/ContactsManager( 30113): find email: newEmail @test
  35. 11- 07 15: 20: 01.844: D/ContactsManager( 30113): find emailType: null
  36. 11- 07 15: 20: 01.853: W/ContactsManager( 30113): **search end**
  37. 11- 07 15: 20: 01.853: W/ContactsManager( 30113): **delete start**
  38. 11- 07 15: 20: 01.874: D/ContactsManager( 30113): delete contact: 张二
  39. 11- 07 15: 20: 01.953: D/ContactsManager( 30113): delete contact success
  40. 11- 07 15: 20: 01.953: W/ContactsManager( 30113): **delete end**
  41. 11- 07 15: 20: 01.953: W/ContactsManager( 30113): **search start**
  42. 11- 07 15: 20: 01.953: D/ContactsManager( 30113): search name: 张二
  43. 11- 07 15: 20: 01.973: D/ContactsManager( 30113): 张二 not exist. exit.
  44. 11- 07 15: 20: 01.973: W/ContactsManager( 30113): **search end**

源代码中的Log.d以及Log.w是android输出日志的API,就当作System.out吧。
这这是一段简单的示例。在android中,同一个联系人可以对应多个号码和邮件,当然也还有其他的信息,比如邮编地址,webpage等等,这些都没有在这里实现。在这里,默认每个联系人只有一个号码和一个邮件。


对联系人的添加/更新,只需要添加/更新数据(name,number,email)到表data就可以了,data表的结构:

系统会自动的在raw_contacts,和contacts添加/更新联系人的ID和NAME以及其他的信息。

删除要删除表raw_contacts和表data的相应数据。但是在删除后发现data表的数据可以删除,但是raw_contacts的数据没有删除,只是一些标志位改变了,例如raw_contact_id变成了空。



另:我试了很多方式,试图删除raw_contacts的记录,但是没有成功。希望有谁知道怎么删除的告诉我。

ContentProvider机制读写联系人信息

本文转自[这里](https://blog.csdn.net/liuhe688/article/details/7006556)

今天我们来讲解一下如何利用ContentProvider机制读写联系人信息。

在Android中,ContentProvider是一种数据包装器,适合在不同进程间实现信息的共享。例如,在Android中SQLite数据库是一个典型的数据源,我们可以把它封装到ContentProvider中,这样就可以很好的为其他应用提供信息共享服务。其他应用在访问ContentProvider时,可以使用一组类似REST的URI的方式进行数据操作,大大简化了读写信息的复杂度。例如,如果要从封装图书数据库的ContentProvider获取一组图书,需要使用类似以下形式的URI:

content://com.scott.book.BookProvider/books

而要从图书数据库中获取指定图书(比如23号图书),需要使用类似以下形式的URI:

content://com.scott.book.BookProvider/books/23

注:ContentProvider是一个抽象类,定义了一系列操作数据的方法模板,BookProvider需要实现这些方法,实现图书信息的各种操作。

那么,现在知道了具体的URI之后,我们又如何操作进而取得数据呢?

此时,我们就要了解ContentResolver这个类,它跟ContentProvider是对应的关系,我们正是通过它来与ContentProvider进行数据交换的。android.content.Context类为我们定义了getContentResolver()方法,用于获取一个ContentResolver对象,如果我们在运行期可以通过getContext()获取当前Context实例对象,就可以通过这个实例对象所提供的getContentResolver()方法获取到ContentResolver类型的实例对象,进而可以操作对应的数据。

下面我们就通过联系人实例对这种机制进行演示。

在Android中,联系人的操作都是通过一个统一的途径来读写数据的,我们打开/data/data/com.android.providers.contacts可以看到联系人的数据源:


有兴趣的朋友可以导出这个文件,用专业的工具软件打开看一下表结构。

对这个SQLite类型的数据源的封装后,联系人就以ContentProvider的形式为其他应用进程提供联系人的读写服务,我们就可以顺利成章的操作自己的联系人信息了。

为了方便测试,我们先添加两个联系人到数据源中,如图所示:



我们看到,每个联系人都有两个电话号码和两个邮箱账号,分别为家庭座机号码、移动手机号码、家庭邮箱账号和工作邮箱账号。当然在添加联系人时有很多其他信息,我们这里都没有填写,只选择了最常用的电话和邮箱,主要是方便演示这个过程。

在演示代码之前,我们需要了解一下android.provider.ContactsContract这个类(注:在较早的版本中是android.provider.Contacts这个类,不过现在已被废弃,不建议使用),它定义了各种联系人相关的URI和每一种类型信息的属性信息:


有兴趣的朋友还可以读一下源代码,不过比较多,而且内部类使用的特别多,读起来有一定的困难,还是要做好心理准备。

下面我们通过一个项目,来演示一下联系人操作的具体过程。新建一个名为provider的项目,创建一个名为ContactsReadTest的测试用例,如下:


 
 
  1. package com.scott.provider;
  2. import java.util.ArrayList;
  3. import android.content.ContentResolver;
  4. import android.database.Cursor;
  5. import android.net.Uri;
  6. import android.provider.ContactsContract;
  7. import android.test.AndroidTestCase;
  8. import android.util.Log;
  9. public class ContactsReadTest extends AndroidTestCase {
  10. private static final String TAG = "ContactsReadTest";
  11. //[content://com.android.contacts/contacts]
  12. private static final Uri CONTACTS_URI = ContactsContract.Contacts.CONTENT_URI;
  13. //[content://com.android.contacts/data/phones]
  14. private static final Uri PHONES_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
  15. //[content://com.android.contacts/data/emails]
  16. private static final Uri EMAIL_URI = ContactsContract.CommonDataKinds.Email.CONTENT_URI;
  17. private static final String _ID = ContactsContract.Contacts._ID;
  18. private static final String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
  19. private static final String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
  20. private static final String CONTACT_ID = ContactsContract.Data.CONTACT_ID;
  21. private static final String PHONE_NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
  22. private static final String PHONE_TYPE = ContactsContract.CommonDataKinds.Phone.TYPE;
  23. private static final String EMAIL_DATA = ContactsContract.CommonDataKinds.Email.DATA;
  24. private static final String EMAIL_TYPE = ContactsContract.CommonDataKinds.Email.TYPE;
  25. public void testReadContacts() {
  26. ContentResolver resolver = getContext().getContentResolver();
  27. Cursor c = resolver.query(CONTACTS_URI, null, null, null, null);
  28. while (c.moveToNext()) {
  29. int _id = c.getInt(c.getColumnIndex(_ID));
  30. String displayName = c.getString(c.getColumnIndex(DISPLAY_NAME));
  31. Log.i(TAG, displayName);
  32. ArrayList<String> phones = new ArrayList<String>();
  33. ArrayList<String> emails = new ArrayList<String>();
  34. String selection = CONTACT_ID + "=" + _id; //the 'where' clause
  35. //获取手机号
  36. int hasPhoneNumber = c.getInt(c.getColumnIndex(HAS_PHONE_NUMBER));
  37. if (hasPhoneNumber > 0) {
  38. Cursor phc = resolver.query(PHONES_URI, null, selection, null, null);
  39. while (phc.moveToNext()) {
  40. String phoneNumber = phc.getString(phc.getColumnIndex(PHONE_NUMBER));
  41. int phoneType = phc.getInt(phc.getColumnIndex(PHONE_TYPE));
  42. phones.add(getPhoneTypeNameById(phoneType) + " : " + phoneNumber);
  43. }
  44. phc.close();
  45. }
  46. Log.i(TAG, "phones: " + phones);
  47. //获取邮箱
  48. Cursor emc = resolver.query(EMAIL_URI, null, selection, null, null);
  49. while (emc.moveToNext()) {
  50. String emailData = emc.getString(emc.getColumnIndex(EMAIL_DATA));
  51. int emailType = emc.getInt(emc.getColumnIndex(EMAIL_TYPE));
  52. emails.add(getEmailTypeNameById(emailType) + " : " + emailData);
  53. }
  54. emc.close();
  55. Log.i(TAG, "emails: " + emails);
  56. }
  57. c.close();
  58. }
  59. private String getPhoneTypeNameById(int typeId) {
  60. switch (typeId) {
  61. case ContactsContract.CommonDataKinds.Phone.TYPE_HOME: return "home";
  62. case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE: return "mobile";
  63. case ContactsContract.CommonDataKinds.Phone.TYPE_WORK: return "work";
  64. default: return "none";
  65. }
  66. }
  67. private String getEmailTypeNameById(int typeId) {
  68. switch (typeId) {
  69. case ContactsContract.CommonDataKinds.Email.TYPE_HOME: return "home";
  70. case ContactsContract.CommonDataKinds.Email.TYPE_WORK: return "work";
  71. case ContactsContract.CommonDataKinds.Email.TYPE_OTHER: return "other";
  72. default: return "none";
  73. }
  74. }
  75. }
为了使这个测试用例运行起来,我们需要在AndroidManifest.xml中配置一下测试设备的声明,它与<application>元素处于同一级别位置:


 
 
  1. <!-- 配置测试设备的主类和目标包 -->
  2. <instrumentation android:name="android.test.InstrumentationTestRunner"
  3. android:targetPackage= "com.scott.provider"/>
然后再配置使用测试类库声明,它与<activity>元素处于同一级别位置:


 
 
  1. <!-- 配置测试要使用的类库 -->
  2. <uses-library android:name="android.test.runner"/>
最后,还有一个重要的声明需要配置,就是读取联系人权限,声明如下:


 
 
  1. <!-- 读取联系人 -->
  2. <uses-permission android:name="android.permission.READ_CONTACTS"/>
经过以上准备工作,这个测试用例就可以运转起来了,我们运行一下testReadContacts()方法,打印结果如下:


看来联系人里的信息都被我们准确无误的读取出来了。

如果我们在一个Activity里运行读取联系人的代码,不仅可以使用ContentResolver直接进行读取操作(即查询),还可以使用Activity提供的managedQuery方法方便的实现同样的效果,我们来看一下这个方法的具体代码:


 
 
  1. public final Cursor managedQuery(Uri uri,
  2. String[] projection,
  3. String selection,
  4. String[] selectionArgs,
  5. String sortOrder)
  6. {
  7. Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
  8. if (c != null) {
  9. startManagingCursor(c);
  10. }
  11. return c;
  12. }
我们发现,其实它还是使用了ContentResolver进行查询操作,但是多了一步startManagingCursor的操作,它会根据Activity的生命周期对Cursor对象进行管理,避免了一些因Cursor是否释放引起的问题,所以非常方便,大大简化了我们的工作量。

接下来我们将要尝试将一个联系人信息添加到系统联系人的数据源中,实现对联系人的写入操作。我们新建一个名为ContactsWriteTest的测试用例,如下:


 
 
  1. package com.scott.provider;
  2. import java.util.ArrayList;
  3. import android.content.ContentProviderOperation;
  4. import android.content.ContentProviderResult;
  5. import android.content.ContentResolver;
  6. import android.net.Uri;
  7. import android.provider.ContactsContract;
  8. import android.test.AndroidTestCase;
  9. import android.util.Log;
  10. public class ContactsWriteTest extends AndroidTestCase {
  11. private static final String TAG = "ContactsWriteTest";
  12. //[content://com.android.contacts/raw_contacts]
  13. private static final Uri RAW_CONTACTS_URI = ContactsContract.RawContacts.CONTENT_URI;
  14. //[content://com.android.contacts/data]
  15. private static final Uri DATA_URI = ContactsContract.Data.CONTENT_URI;
  16. private static final String ACCOUNT_TYPE = ContactsContract.RawContacts.ACCOUNT_TYPE;
  17. private static final String ACCOUNT_NAME = ContactsContract.RawContacts.ACCOUNT_NAME;
  18. private static final String RAW_CONTACT_ID = ContactsContract.Data.RAW_CONTACT_ID;
  19. private static final String MIMETYPE = ContactsContract.Data.MIMETYPE;
  20. private static final String NAME_ITEM_TYPE = ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE;
  21. private static final String DISPLAY_NAME = ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME;
  22. private static final String PHONE_ITEM_TYPE = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
  23. private static final String PHONE_NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
  24. private static final String PHONE_TYPE = ContactsContract.CommonDataKinds.Phone.TYPE;
  25. private static final int PHONE_TYPE_HOME = ContactsContract.CommonDataKinds.Phone.TYPE_HOME;
  26. private static final int PHONE_TYPE_MOBILE = ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE;
  27. private static final String EMAIL_ITEM_TYPE = ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;
  28. private static final String EMAIL_DATA = ContactsContract.CommonDataKinds.Email.DATA;
  29. private static final String EMAIL_TYPE = ContactsContract.CommonDataKinds.Email.TYPE;
  30. private static final int EMAIL_TYPE_HOME = ContactsContract.CommonDataKinds.Email.TYPE_HOME;
  31. private static final int EMAIL_TYPE_WORK = ContactsContract.CommonDataKinds.Email.TYPE_WORK;
  32. private static final String AUTHORITY = ContactsContract.AUTHORITY;
  33. public void testWriteContacts() throws Exception {
  34. ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
  35. ContentProviderOperation operation = ContentProviderOperation.newInsert(RAW_CONTACTS_URI)
  36. .withValue(ACCOUNT_TYPE, null)
  37. .withValue(ACCOUNT_NAME, null)
  38. .build();
  39. operations.add(operation);
  40. //添加联系人名称操作
  41. operation = ContentProviderOperation.newInsert(DATA_URI)
  42. .withValueBackReference(RAW_CONTACT_ID, 0)
  43. .withValue(MIMETYPE, NAME_ITEM_TYPE)
  44. .withValue(DISPLAY_NAME, "Scott Liu")
  45. .build();
  46. operations.add(operation);
  47. //添加家庭座机号码
  48. operation = ContentProviderOperation.newInsert(DATA_URI)
  49. .withValueBackReference(RAW_CONTACT_ID, 0)
  50. .withValue(MIMETYPE, PHONE_ITEM_TYPE)
  51. .withValue(PHONE_TYPE, PHONE_TYPE_HOME)
  52. .withValue(PHONE_NUMBER, "01034567890")
  53. .build();
  54. operations.add(operation);
  55. //添加移动手机号码
  56. operation = ContentProviderOperation.newInsert(DATA_URI)
  57. .withValueBackReference(RAW_CONTACT_ID, 0)
  58. .withValue(MIMETYPE, PHONE_ITEM_TYPE)
  59. .withValue(PHONE_TYPE, PHONE_TYPE_MOBILE)
  60. .withValue(PHONE_NUMBER, "13034567890")
  61. .build();
  62. operations.add(operation);
  63. //添加家庭邮箱
  64. operation = ContentProviderOperation.newInsert(DATA_URI)
  65. .withValueBackReference(RAW_CONTACT_ID, 0)
  66. .withValue(MIMETYPE, EMAIL_ITEM_TYPE)
  67. .withValue(EMAIL_TYPE, EMAIL_TYPE_HOME)
  68. .withValue(EMAIL_DATA, "scott@android.com")
  69. .build();
  70. operations.add(operation);
  71. //添加工作邮箱
  72. operation = ContentProviderOperation.newInsert(DATA_URI)
  73. .withValueBackReference(RAW_CONTACT_ID, 0)
  74. .withValue(MIMETYPE, EMAIL_ITEM_TYPE)
  75. .withValue(EMAIL_TYPE, EMAIL_TYPE_WORK)
  76. .withValue(EMAIL_DATA, "scott@msapple.com")
  77. .build();
  78. operations.add(operation);
  79. ContentResolver resolver = getContext().getContentResolver();
  80. //批量执行,返回执行结果集
  81. ContentProviderResult[] results = resolver.applyBatch(AUTHORITY, operations);
  82. for (ContentProviderResult result : results) {
  83. Log.i(TAG, result.uri.toString());
  84. }
  85. }
  86. }
在上面的代码中,我们把整个操作分为几个ContentProviderOperation操作,并将他们做批处理操作,我们也许注意到,从第二个操作开始,每一项都有一个withValueBackReference(RAW_CONTACT_ID, 0)步骤,它参照了第一项操作新添加的联系人的id,因为是批处理,我们插入数据前并不知道id的值,不过这个不用担心,在进行批处理插入数据时,它会重新引用新的id值,不会影响最终的结果。

当然,这个也不能忘了配置写入联系人的权限声明:


 
 
  1. <!-- 写入联系人 -->
  2. <uses-permission android:name="android.permission.WRITE_CONTACTS" />
经过以上步骤之后,我们运行一下testWriteContacts()方法,看看联系人是否添加进去了:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值