1.获取联系人姓名

一个简单的例子,这个函数获取设备上所有的联系人ID和联系人NAME。

public void fetchAllContacts() {ContentResolver contentResolver = this.getContentResolver();Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,null, null, null, null);cursor.getCount();while(cursor.moveToNext()) {System.out.println(cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID)));System.out.println(cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME)));}cursor.close();}


执行结果:

[java] view plain copy
  1. 11-0514:13:09.987:I/System.out(4692):13
  2. 11-0514:13:09.987:I/System.out(4692):张三
  3. 11-0514:13:09.987:I/System.out(4692):31
  4. 11-0514:13:09.987:I/System.out(4692):李四

解释:

[java] view plain copy
  1. ContentResolvercontentResolver=this.getContentResolver();

this在这里指的是MainActivity,ContentResolver直译为内容解析器,什么东东?Android中程序间数据的共享是通过Provider/Resolver进行的。提供数据(内容)的就叫Provider,Resovler提供接口对这个内容进行解读。

在这里,系统提供了联系人的Provider,那么我们就需要构建一个Resolver来读取联系人的内容。

[java] view plain copy
  1. Cursorcursor=contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
  2. null,null,null,null);
根据Android文档,

public finalCursorquery(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder)

第一个参数,uri,rui是什么呢?好吧,上面我们提到了Android提供内容的叫Provider,那么在Android中怎么区分各个Provider?有提供联系人的,有提供图片的等等。所以就需要有一个唯一的标识来标识这个Provider,Uri就是这个标识,android.provider.ContactsContract.Contacts.CONTENT_URI就是提供联系人的内容提供者,可惜这个内容提供者提供的数据很少。

第二个参数,projection,真不知道为什么要用这个单词,这个参数告诉Provider要返回的内容(列Column),比如Contacts Provider提供了联系人的ID和联系人的NAME等内容,如果我们只需要NAME,那么我们就应该使用:

[java] view plain copy
  1. Cursorcursor=contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
  2. newString[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME},null,null,null);
当然,下面打印的你就只能显示NAME了,因为你返回的结果不包含ID。用null表示返回Provider的所有内容(列Column)。

第三个参数,selection,设置条件,相当于SQL语句中的where。null表示不进行筛选。如果我们只想返回名称为张三的数据,第三个参数应该设置为:

[java] view plain copy
  1. Cursorcursor=contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
  2. newString[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME},
  3. android.provider.ContactsContract.Contacts.DISPLAY_NAME+"='张三'",null,null);
结果:

[java] view plain copy
  1. 11-0515:30:32.188:I/System.out(10271):张三
第四个参数,selectionArgs,这个参数是要配合第三个参数使用的,如果你在第三个参数里面有?,那么你在selectionArgs写的数据就会替换掉?,

[java] view plain copy
  1. Cursorcursor=contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
  2. newString[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME},
  3. android.provider.ContactsContract.Contacts.DISPLAY_NAME+"=?",
  4. newString[]{"张三"},null);

效果和上面一句的效果一样。

第五个参数,sortOrder,按照什么进行排序,相当于SQL语句中的Order by。如果想要结果按照ID的降序排列:

[java] view plain copy
  1. Cursorcursor=contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
  2. null,null,null,android.provider.ContactsContract.Contacts._ID+"DESC");
结果:

[java] view plain copy
  1. 11-0516:00:32.808:I/System.out(12523):31
  2. 11-0516:00:32.808:I/System.out(12523):李四
  3. 11-0516:00:32.817:I/System.out(12523):13
  4. 11-0516:00:32.817:I/System.out(12523):张三
升序,其实默认排序是升序,+" ASC"写不写效果都一样:

[java] view plain copy
  1. Cursorcursor=contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
  2. null,null,null,android.provider.ContactsContract.Contacts._ID+"ASC");
结果:

[java] view plain copy
  1. 11-0515:59:10.327:I/System.out(12406):13
  2. 11-0515:59:10.327:I/System.out(12406):张三
  3. 11-0515:59:10.327:I/System.out(12406):31
  4. 11-0515:59:10.327:I/System.out(12406):李四

Contacts 联系人详解

1.获取联系人详细信息

在(一)中我们只是获取了联系人的ID和NAME,但是这是远远不够的,怎么样获取其他的值呢?

public void fetchContactInformation() {String id,name,phoneNumber,email;ContentResolver contentResolver = this.getContentResolver();Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,null, null, null, null);while(cursor.moveToNext()) {id=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));name=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts.DISPLAY_NAME));//Fetch Phone NumberCursor phoneCursor = contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, android.provider.ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+id, null, null);while(phoneCursor.moveToNext()) {phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER));System.out.println("id="+id+" name="+name+" phoneNumber="+phoneNumber);}phoneCursor.close();//Fetch emailCursor emailCursor = contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, android.provider.ContactsContract.CommonDataKinds.Email.CONTACT_ID+"="+id, null, null);while(emailCursor.moveToNext()) {email = emailCursor.getString(emailCursor.getColumnIndex(android.provider.ContactsContract.CommonDataKinds.Email.DATA));System.out.println("id="+id+" name="+name+" email="+email);}emailCursor.close();}cursor.close();}

结果:

[java] view plain copy
  1. 11-0614:38:32.049:I/System.out(26534):id=4name=张三phoneNumber=1-234-56
  2. 11-0614:38:32.138:I/System.out(26534):id=5name=李四phoneNumber=654-321
  3. 11-0614:38:32.138:I/System.out(26534):id=5name=李四phoneNumber=987-654-321
  4. 11-0614:38:32.188:I/System.out(26534):id=5name=李四email=wssiqi@126.com
在这里,我们通过

android.provider.ContactsContract.Contacts.CONTENT_URI 来获取联系人的ID和NAME

android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI 获取联系人的电话号码

android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI 获取联系人的邮箱地址

关键是ContactsContract下面有很多类,很不容易找到到底哪个类包含我们需要的内容。怎样通过比较简单的方法获取所有信息呢?

为了更好的解决这个问题,我们需要先分析联系人的信息是怎样存储在Android上的。


2.Android 联系人存储方式

Android是将联系人信息存储在Sqlite数据库中的,如果想知道Sqlite的详细信息,请百度或者Google。

如何查看Sqlite中Contacts数据库,请参考http://www.cnblogs.com/luxiaofeng54/archive/2011/03/15/1985183.html,我也是从这里了解的。

2.1 联系人 表Contacts

上面这张图就是表contacts的内容,可以从中看出这张表的信息,常用的有_id,display_name

[java] view plain copy
  1. contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
  2. null,null,null,null);

编译后的内容是这样的:

SELECT times_contacted, contacts_status_updates.status AS contact_status, custom_ringtone, has_phone_number, contacts_status_updates.status_label AS contact_status_label, lookup, contacts_status_updates.status_icon AS contact_status_icon, last_time_contacted, display_name, in_visible_group, _id, starred, agg_presence.mode AS contact_presence, contacts_status_updates.status_res_package AS contact_status_res_package, contacts_status_updates.status_ts AS contact_status_ts, photo_id, send_to_voicemail FROM view_contacts_restricted LEFT OUTER JOIN agg_presence ON (_id = presence_contact_id) LEFT OUTER JOIN status_updates contacts_status_updates ON (status_update_id=contacts_status_updates.status_update_data_id)

省略掉我们不关心的内容,就成了这个:

[java] view plain copy
  1. SELECT*FROMview_contacts_restricted
view_contacts_restricted是一个视图,你可以把它当作一个表,view_contacts_restricted的主要内容来自于表contacts,所以我们只能从android.provider.ContactsContract.Contacts.CONTENT_URI获取到ID和DisplayName,要获取到其他信息,就需要从data表获取。

2.2 联系人 表data

这个表就是存储联系人相关信息的表。mimetype表如下:


获取Phone Number的URI:

[java] view plain copy
  1. contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
  2. null,null,null,null);

编译后的内容:

[java] view plain copy
  1. SELECTdata_version,contact_id,lookup,data12,data11,data10,mimetype,data15,data14,data13,data_sync1,data_sync3,data_sync2,data_sync4,account_type,custom_ringtone,status_updates.statusASstatus,data1,data4,data5,data2,data3,data8,data9,group_sourceid,data6,account_name,data7,display_name,in_visible_group,contacts_status_updates.status_res_packageAScontact_status_res_package,is_primary,contacts_status_updates.status_tsAScontact_status_ts,raw_contact_id,times_contacted,contacts_status_updates.statusAScontact_status,status_updates.status_res_packageASstatus_res_package,status_updates.status_iconASstatus_icon,contacts_status_updates.status_iconAScontact_status_icon,presence.modeASmode,version,last_time_contacted,res_package,_id,status_updates.status_tsASstatus_ts,dirty,is_super_primary,photo_id,send_to_voicemail,contacts_status_updates.status_labelAScontact_status_label,status_updates.status_labelASstatus_label,starred,agg_presence.modeAScontact_presence,sourceidFROMview_data_restricteddataLEFTOUTERJOINagg_presenceON(agg_presence.presence_contact_id=contact_id)LEFTOUTERJOINstatus_updatescontacts_status_updatesON(status_update_id=contacts_status_updates.status_update_data_id)LEFTOUTERJOINpresenceON(presence_data_id=data._id)LEFTOUTERJOINstatus_updatesON(status_updates.status_update_data_id=data._id)WHERE(1ANDmimetype='vnd.android.cursor.item/phone_v2')
主要的信息为:

[java] view plain copy
  1. SELECT*FROMview_data_restrictedwheremimetype='vnd.android.cursor.item/phone_v2'


获取Email的URI:

[java] view plain copy
  1. contentResolver.query(android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI,
  2. null,null,null,null);

编译后的内容:

[java] view plain copy
  1. SELECTdata_version,contact_id,lookup,data12,data11,data10,mimetype,data15,data14,data13,data_sync1,data_sync3,data_sync2,data_sync4,account_type,custom_ringtone,status_updates.statusASstatus,data1,data4,data5,data2,data3,data8,data9,group_sourceid,data6,account_name,data7,display_name,in_visible_group,contacts_status_updates.status_res_packageAScontact_status_res_package,is_primary,contacts_status_updates.status_tsAScontact_status_ts,raw_contact_id,times_contacted,contacts_status_updates.statusAScontact_status,status_updates.status_res_packageASstatus_res_package,status_updates.status_iconASstatus_icon,contacts_status_updates.status_iconAScontact_status_icon,presence.modeASmode,version,last_time_contacted,res_package,_id,status_updates.status_tsASstatus_ts,dirty,is_super_primary,photo_id,send_to_voicemail,contacts_status_updates.status_labelAScontact_status_label,status_updates.status_labelASstatus_label,starred,agg_presence.modeAScontact_presence,sourceidFROMview_data_restricteddataLEFTOUTERJOINagg_presenceON(agg_presence.presence_contact_id=contact_id)LEFTOUTERJOINstatus_updatescontacts_status_updatesON(status_update_id=contacts_status_updates.status_update_data_id)LEFTOUTERJOINpresenceON(presence_data_id=data._id)LEFTOUTERJOINstatus_updatesON(status_updates.status_update_data_id=data._id)WHERE(1ANDmimetype='vnd.android.cursor.item/email_v2')
主要的信息为: [java] view plain copy
  1. SELECT*FROMview_data_restrictedwheremimetype='vnd.android.cursor.item/email_v2'

可以看出,Phone number和Email的获取都是从同一张表获取的。 唯一的区别是 mimetype的类型不同。

view_data_restricted的主要内容来自于表data。
从表data可以看出,name,phone number,email存储的方式是一样的,都是data1,后面的data是更详细的信息,区分name,phone number,email 的唯一方式是mimetype_id,区分联系人的唯一标识是raw_contact_id,这个值是从上面的表contacts的_id获取的。


经过以上分析,我们可以知道,要想获取联系人的所有信息,需要先通过contacts表获取联系人ID,然后根据联系人的ID在表data获取想要的内容。

下面我们通过一个URI获取联系人的所有信息:

public void fetchContactInformationV2() {String id;String mimetype;ContentResolver contentResolver = this.getContentResolver();//只需要从Contacts中获取ID,其他的都可以不要,通过查看上面编译后的SQL语句,可以看出将第二个参数//设置成null,默认返回的列非常多,是一种资源浪费。Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,new String[]{android.provider.ContactsContract.Contacts._ID}, null, null, null);while(cursor.moveToNext()) {id=cursor.getString(cursor.getColumnIndex(android.provider.ContactsContract.Contacts._ID));//从一个Cursor获取所有的信息Cursor contactInfoCursor = contentResolver.query(android.provider.ContactsContract.Data.CONTENT_URI,new String[]{android.provider.ContactsContract.Data.CONTACT_ID,android.provider.ContactsContract.Data.MIMETYPE,android.provider.ContactsContract.Data.DATA1}, android.provider.ContactsContract.Data.CONTACT_ID+"="+id, null, null);while(contactInfoCursor.moveToNext()) {mimetype = contactInfoCursor.getString(contactInfoCursor.getColumnIndex(android.provider.ContactsContract.Data.MIMETYPE));String value = contactInfoCursor.getString(contactInfoCursor.getColumnIndex(android.provider.ContactsContract.Data.DATA1));if(mimetype.contains("/name")){System.out.println("姓名="+value);} else if(mimetype.contains("/im")){System.out.println("聊天(QQ)账号="+value);} else if(mimetype.contains("/email")) {System.out.println("邮箱="+value);} else if(mimetype.contains("/phone")) {System.out.println("电话="+value);} else if(mimetype.contains("/postal")) {System.out.println("邮编="+value);} else if(mimetype.contains("/photo")) {System.out.println("照片="+value);} else if(mimetype.contains("/group")) {System.out.println("组="+value);} }System.out.println("*********");contactInfoCursor.close();}cursor.close();}

结果:

[java] view plain copy
  1. 11-0617:16:59.068:I/System.out(3737):电话=1-234-56
  2. 11-0617:16:59.068:I/System.out(3737):姓名=张三
  3. 11-0617:16:59.068:I/System.out(3737):*********
  4. 11-0617:16:59.108:I/System.out(3737):电话=654-321
  5. 11-0617:16:59.108:I/System.out(3737):姓名=李四
  6. 11-0617:16:59.108:I/System.out(3737):电话=987-654-321
  7. 11-0617:16:59.108:I/System.out(3737):聊天(QQ)账号=123456
  8. 11-0617:16:59.108:I/System.out(3737):邮箱=wssiqi@126.com
  9. 11-0617:16:59.108:I/System.out(3737):*********
Contacts 查找,增加,更新,删除联系

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

直接贴代码:

ContactsManager.java

[java] view plain copy
  1. packagecom.example.siqi.contacts;
  2. importjava.util.ArrayList;
  3. importandroid.content.ContentProviderOperation;
  4. importandroid.content.ContentResolver;
  5. importandroid.database.Cursor;
  6. importandroid.provider.ContactsContract;
  7. importandroid.util.Log;
  8. publicclassContactsManager{
  9. privateContentResolvercontentResolver;
  10. privatestaticfinalStringTAG="ContactsManager";
  11. /**
  12. *Useasimplestringrepresentsthelong.
  13. */
  14. privatestaticfinalStringCOLUMN_CONTACT_ID=
  15. ContactsContract.Data.CONTACT_ID;
  16. privatestaticfinalStringCOLUMN_RAW_CONTACT_ID=
  17. ContactsContract.Data.RAW_CONTACT_ID;
  18. privatestaticfinalStringCOLUMN_MIMETYPE=
  19. ContactsContract.Data.MIMETYPE;
  20. privatestaticfinalStringCOLUMN_NAME=
  21. ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME;
  22. privatestaticfinalStringCOLUMN_NUMBER=
  23. ContactsContract.CommonDataKinds.Phone.NUMBER;
  24. privatestaticfinalStringCOLUMN_NUMBER_TYPE=
  25. ContactsContract.CommonDataKinds.Phone.TYPE;
  26. privatestaticfinalStringCOLUMN_EMAIL=
  27. ContactsContract.CommonDataKinds.Email.DATA;
  28. privatestaticfinalStringCOLUMN_EMAIL_TYPE=
  29. ContactsContract.CommonDataKinds.Email.TYPE;
  30. privatestaticfinalStringMIMETYPE_STRING_NAME=
  31. ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE;
  32. privatestaticfinalStringMIMETYPE_STRING_PHONE=
  33. ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
  34. privatestaticfinalStringMIMETYPE_STRING_EMAIL=
  35. ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;
  36. publicContactsManager(ContentResolvercontentResolver){
  37. this.contentResolver=contentResolver;
  38. }
  39. /**
  40. *Searchandfillthecontactinformationbythecontactnamegiven.
  41. *@paramcontactOnlythenameisnecessary.
  42. */
  43. publicContactsearchContact(Stringname){
  44. Log.w(TAG,"**searchstart**");
  45. Contactcontact=newContact();
  46. contact.setName(name);
  47. Log.d(TAG,"searchname:"+contact.getName());
  48. Stringid=getContactID(contact.getName());
  49. contact.setId(id);
  50. if(id.equals("0")){
  51. Log.d(TAG,contact.getName()+"notexist.exit.");
  52. }else{
  53. Log.d(TAG,"findid:"+id);
  54. //FetchPhoneNumber
  55. Cursorcursor=contentResolver.query(
  56. android.provider.ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
  57. newString[]{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,"findnumber:"+contact.getNumber());
  63. Log.d(TAG,"findnumberType:"+contact.getNumberType());
  64. }
  65. //cursor.close();
  66. //Fetchemail
  67. cursor=contentResolver.query(
  68. android.provider.ContactsContract.CommonDataKinds.Email.CONTENT_URI,
  69. newString[]{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,"findemail:"+contact.getEmail());
  75. Log.d(TAG,"findemailType:"+contact.getEmailType());
  76. }
  77. cursor.close();
  78. }
  79. Log.w(TAG,"**searchend**");
  80. returncontact;
  81. }
  82. /**
  83. *
  84. *@paramcontactThecontactwhoyougettheidfrom.Thenameof
  85. *thecontactshouldbeset.
  86. *@return0ifcontactnotexistincontactslist.Otherwisereturn
  87. *theidofthecontact.
  88. */
  89. publicStringgetContactID(Stringname){
  90. Stringid="0";
  91. Cursorcursor=contentResolver.query(
  92. android.provider.ContactsContract.Contacts.CONTENT_URI,
  93. newString[]{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. returnid;
  101. }
  102. /**
  103. *Youmustspecifythecontact'sID.
  104. *@paramcontact
  105. *@throwsExceptionThecontact'snameshouldnotbeempty.
  106. */
  107. publicvoidaddContact(Contactcontact){
  108. Log.w(TAG,"**addstart**");
  109. ArrayList<ContentProviderOperation>ops=newArrayList<ContentProviderOperation>();
  110. Stringid=getContactID(contact.getName());
  111. if(!id.equals("0")){
  112. Log.d(TAG,"contactalreadyexist.exit.");
  113. }elseif(contact.getName().trim().equals("")){
  114. Log.d(TAG,"contactnameisempty.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,"addname:"+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,"addnumber:"+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,"addemail:"+contact.getEmail());
  143. }
  144. try{
  145. contentResolver.applyBatch(ContactsContract.AUTHORITY,ops);
  146. Log.d(TAG,"addcontactsuccess.");
  147. }catch(Exceptione){
  148. Log.d(TAG,"addcontactfailed.");
  149. Log.e(TAG,e.getMessage());
  150. }
  151. }
  152. Log.w(TAG,"**addend**");
  153. }
  154. /**
  155. *Deletecontactswho'snameequalscontact.getName();
  156. *@paramcontact
  157. */
  158. publicvoiddeleteContact(Contactcontact){
  159. Log.w(TAG,"**deletestart**");
  160. ArrayList<ContentProviderOperation>ops=newArrayList<ContentProviderOperation>();
  161. Stringid=getContactID(contact.getName());
  162. //deletecontact
  163. ops.add(ContentProviderOperation.newDelete(ContactsContract.RawContacts.CONTENT_URI)
  164. .withSelection(ContactsContract.RawContacts.CONTACT_ID+"="+id,null)
  165. .build());
  166. //deletecontactinformationsuchasphonenumber,email
  167. ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
  168. .withSelection(COLUMN_CONTACT_ID+"="+id,null)
  169. .build());
  170. Log.d(TAG,"deletecontact:"+contact.getName());
  171. try{
  172. contentResolver.applyBatch(ContactsContract.AUTHORITY,ops);
  173. Log.d(TAG,"deletecontactsuccess");
  174. }catch(Exceptione){
  175. Log.d(TAG,"deletecontactfailed");
  176. Log.e(TAG,e.getMessage());
  177. }
  178. Log.w(TAG,"**deleteend**");
  179. }
  180. /**
  181. *@paramcontactOldThecontactwantstobeupdated.Thenameshouldexists.
  182. *@paramcontactNew
  183. */
  184. publicvoidupdateContact(ContactcontactOld,ContactcontactNew){
  185. Log.w(TAG,"**updatestart**");
  186. Stringid=getContactID(contactOld.getName());
  187. if(id.equals("0")){
  188. Log.d(TAG,contactOld.getName()+"notexist.");
  189. }elseif(contactNew.getName().trim().equals("")){
  190. Log.d(TAG,"contactnameisempty.exit.");
  191. }elseif(!getContactID(contactNew.getName()).equals("0")){
  192. Log.d(TAG,"newcontactnamealreadyexist.exit.");
  193. }else{
  194. ArrayList<ContentProviderOperation>ops=newArrayList<ContentProviderOperation>();
  195. //updatename
  196. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  197. .withSelection(COLUMN_CONTACT_ID+"=?AND"+COLUMN_MIMETYPE+"=?",
  198. newString[]{id,MIMETYPE_STRING_NAME})
  199. .withValue(COLUMN_NAME,contactNew.getName())
  200. .build());
  201. Log.d(TAG,"updatename:"+contactNew.getName());
  202. //updatenumber
  203. if(!contactNew.getNumber().trim().equals("")){
  204. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  205. .withSelection(COLUMN_CONTACT_ID+"=?AND"+COLUMN_MIMETYPE+"=?",
  206. newString[]{id,MIMETYPE_STRING_PHONE})
  207. .withValue(COLUMN_NUMBER,contactNew.getNumber())
  208. .withValue(COLUMN_NUMBER_TYPE,contactNew.getNumberType())
  209. .build());
  210. Log.d(TAG,"updatenumber:"+contactNew.getNumber());
  211. }
  212. //updateemailifmail
  213. if(!contactNew.getEmail().trim().equals("")){
  214. ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
  215. .withSelection(COLUMN_CONTACT_ID+"=?AND"+COLUMN_MIMETYPE+"=?",
  216. newString[]{id,MIMETYPE_STRING_EMAIL})
  217. .withValue(COLUMN_EMAIL,contactNew.getEmail())
  218. .withValue(COLUMN_EMAIL_TYPE,contactNew.getEmailType())
  219. .build());
  220. Log.d(TAG,"updateemail:"+contactNew.getEmail());
  221. }
  222. try{
  223. contentResolver.applyBatch(ContactsContract.AUTHORITY,ops);
  224. Log.d(TAG,"updatesuccess");
  225. }catch(Exceptione){
  226. Log.d(TAG,"updatefailed");
  227. Log.e(TAG,e.getMessage());
  228. }
  229. }
  230. Log.w(TAG,"**updateend**");
  231. }
  232. }
Contact.java

[java] view plain copy
  1. packagecom.example.siqi.contacts;
  2. publicclassContact{
  3. privateStringemail;
  4. privateStringemailType;
  5. privateStringid;
  6. privateStringname;
  7. privateStringnumber;
  8. privateStringnumberType;
  9. publicContact(){
  10. }
  11. publicContact(Contactcontact){
  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. publicStringgetEmail(){
  19. returnemail;
  20. }
  21. publicStringgetEmailType(){
  22. returnemailType;
  23. }
  24. publicStringgetId(){
  25. returnid;
  26. }
  27. publicStringgetName(){
  28. returnname;
  29. }
  30. publicStringgetNumber(){
  31. returnnumber;
  32. }
  33. publicStringgetNumberType(){
  34. returnnumberType;
  35. }
  36. publicvoidsetEmail(Stringemail){
  37. this.email=email;
  38. }
  39. publicvoidsetEmailType(StringemailType){
  40. this.emailType=emailType;
  41. }
  42. publicvoidsetId(Stringid){
  43. this.id=id;
  44. }
  45. publicvoidsetName(Stringname){
  46. this.name=name;
  47. }
  48. publicvoidsetNumber(Stringnumber){
  49. this.number=number;
  50. }
  51. publicvoidsetNumberType(StringnumberType){
  52. this.numberType=numberType;
  53. }
  54. }
MainActivity.java

[java] view plain copy
  1. packagecom.example.siqi.contacts;
  2. importandroid.os.Bundle;
  3. importandroid.app.Activity;
  4. importandroid.view.Menu;
  5. publicclassMainActivityextendsActivity{
  6. @Override
  7. publicvoidonCreate(BundlesavedInstanceState){
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity_main);
  10. ContactsManagercm=newContactsManager(this.getContentResolver());
  11. cm.searchContact("张一");
  12. Contactcontact=newContact();
  13. contact.setName("张一");
  14. contact.setEmail("[email protected]");
  15. contact.setNumber("123456789");
  16. //testaddContact
  17. cm.addContact(contact);
  18. cm.searchContact("张一");
  19. //testupdateContact
  20. ContactcontactNew=newContact(contact);
  21. contactNew.setName("张二");
  22. contactNew.setNumber("987654321");
  23. contactNew.setEmail("[email protected]");
  24. cm.updateContact(contact,contactNew);
  25. cm.searchContact("张一");
  26. cm.searchContact("张二");
  27. //testdeleteContact
  28. cm.deleteContact(contactNew);
  29. cm.searchContact("张二");
  30. }
  31. @Override
  32. publicbooleanonCreateOptionsMenu(Menumenu){
  33. getMenuInflater().inflate(R.menu.activity_main,menu);
  34. returntrue;
  35. }
  36. }
项目需要添加权限:

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

结果:

[java] view plain copy
  1. 11-0715:20:00.873:W/ContactsManager(30113):**searchstart**
  2. 11-0715:20:00.873:D/ContactsManager(30113):searchname:张一
  3. 11-0715:20:00.943:D/ContactsManager(30113):张一notexist.exit.
  4. 11-0715:20:00.943:W/ContactsManager(30113):**searchend**
  5. 11-0715:20:00.943:W/ContactsManager(30113):**addstart**
  6. 11-0715:20:00.973:D/ContactsManager(30113):addname:张一
  7. 11-0715:20:01.004:D/ContactsManager(30113):addnumber:123456789
  8. 11-0715:20:01.004:D/ContactsManager(30113):addemail:test@test.com
  9. 11-0715:20:01.224:D/ContactsManager(30113):addcontactsuccess.
  10. 11-0715:20:01.224:W/ContactsManager(30113):**addend**
  11. 11-0715:20:01.224:W/ContactsManager(30113):**searchstart**
  12. 11-0715:20:01.224:D/ContactsManager(30113):searchname:张一
  13. 11-0715:20:01.243:D/ContactsManager(30113):findid:30
  14. 11-0715:20:01.273:D/ContactsManager(30113):findnumber:123456789
  15. 11-0715:20:01.273:D/ContactsManager(30113):findnumberType:null
  16. 11-0715:20:01.323:D/ContactsManager(30113):findemail:test@test.com
  17. 11-0715:20:01.323:D/ContactsManager(30113):findemailType:null
  18. 11-0715:20:01.334:W/ContactsManager(30113):**searchend**
  19. 11-0715:20:01.334:W/ContactsManager(30113):**updatestart**
  20. 11-0715:20:01.393:D/ContactsManager(30113):updatename:张二
  21. 11-0715:20:01.403:D/ContactsManager(30113):updatenumber:987654321
  22. 11-0715:20:01.403:D/ContactsManager(30113):updateemail:newEmail@test
  23. 11-0715:20:01.723:D/ContactsManager(30113):updatesuccess
  24. 11-0715:20:01.723:W/ContactsManager(30113):**updateend**
  25. 11-0715:20:01.723:W/ContactsManager(30113):**searchstart**
  26. 11-0715:20:01.723:D/ContactsManager(30113):searchname:张一
  27. 11-0715:20:01.743:D/ContactsManager(30113):张一notexist.exit.
  28. 11-0715:20:01.743:W/ContactsManager(30113):**searchend**
  29. 11-0715:20:01.743:W/ContactsManager(30113):**searchstart**
  30. 11-0715:20:01.754:D/ContactsManager(30113):searchname:张二
  31. 11-0715:20:01.773:D/ContactsManager(30113):findid:30
  32. 11-0715:20:01.803:D/ContactsManager(30113):findnumber:987654321
  33. 11-0715:20:01.813:D/ContactsManager(30113):findnumberType:null
  34. 11-0715:20:01.844:D/ContactsManager(30113):findemail:newEmail@test
  35. 11-0715:20:01.844:D/ContactsManager(30113):findemailType:null
  36. 11-0715:20:01.853:W/ContactsManager(30113):**searchend**
  37. 11-0715:20:01.853:W/ContactsManager(30113):**deletestart**
  38. 11-0715:20:01.874:D/ContactsManager(30113):deletecontact:张二
  39. 11-0715:20:01.953:D/ContactsManager(30113):deletecontactsuccess
  40. 11-0715:20:01.953:W/ContactsManager(30113):**deleteend**
  41. 11-0715:20:01.953:W/ContactsManager(30113):**searchstart**
  42. 11-0715:20:01.953:D/ContactsManager(30113):searchname:张二
  43. 11-0715:20:01.973:D/ContactsManager(30113):张二notexist.exit.
  44. 11-0715:20:01.973:W/ContactsManager(30113):**searchend**

源代码中的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的记录,但是没有成功。希望有谁知道怎么删除的告诉我。


更多相关文章

  1. Android(安卓)通讯录学习笔记之——调用系统添加成员功能
  2. Android开发艺术探索 第2章 IPC机制(部分内容)
  3. Android倒计时实现
  4. android dialog 背景透明的样式
  5. Android之动态改变控件大小
  6. android 获取手机通讯录以及 6.0 授权
  7. 【android 文件的基本操作】
  8. android 获取web 内容简单实现
  9. Android仿苹果关机界面实现代码

随机推荐

  1. Java的Grizzly为缓冲区占用了大量内存?
  2. Kotlin:相当于KClass的getClass()。
  3. 常用设计模式学习
  4. 关于Hadoop查看进程时jps命令出现Error:
  5. Android JVM的运行过程
  6. IT十八掌作业_java基础第20天_断点续传、
  7. Java常见对象之String
  8. JVM 性能调优监控工具
  9. Java的Web项目中Web.xml配置文件元素详解
  10. 如果服务器位于不同的位置,如何保存客户端