android 联系人 增删改查

 

一.前言

     1.1 Android的电话本的机制.

Android的电话本通过contentProvider封装好的。我们只要通过sdk提供的Uri和字段来对其进行增、删、改、查。

     1.2 权限 

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

     1.3 找到ContentProvider维护的Sqlist数据库文件( .db)

ContentProvider其实自己管理一个Sqlist数据库文件( .db)。这个文件的路径为/data/data/com.android.providers.contacts/databases/contacts2.db。如图:



     1.4 查看ContentProvider维护的Sqlist数据库文件( .db)

在模拟器中的电话本里创建几个联系人,打开1.2中的.db文件,可以用数据库查看工具SQLite Expert Professional打开看下,如图:

 

      从上图,可以看出左边是.db文件的表,点开各表后可以看出主要的表有raw_contacts,contacts,data


二. api

      2.1 三张主表.

从api中可以看到android.provider.ContactsContract是sdk2.0的类库,从api和上面的图都可以看出关于电话本主要信息都存在 ContactsContract.Data ContactsContract.RawContacts ContactsContract.Contacts 三张表里

  2.1.1 以上三张表的关联关系.

ContactsContract.Data, ContactsContract.RawContacts, ContactsContract.Contacts 三张表的关联,

ContactsContract.RawContacts表里包含ContactsContract.Contacts的contact_id;ContactsContract.Data表里有ContactsContract.RawContacts的raw_contact_id,和ContactsContract.Contacts的contact_id

      

     2.2 各数据对应的类库,电话本各字段的数据结构

    2.2.1 Email 对应ContactsContract.CommonDataKinds.Email

Type Alias Data column
String ADDRESS DATA1 Email address itself.
int TYPE DATA2 Allowed values are:

String LABEL DATA3  
Email数据有三个字段存储:ADDRESS为Email值;TYPE为类型,当为自定义(TYPE_CUSTOM)时,LABEL字段要写入用户自定义的类型;

   2.2.2 IM 对应 ContactsContract.CommonDataKinds.Im 

Type Alias Data column
String DATA DATA1  
int TYPE DATA2 Allowed values are:

String LABEL DATA3  
String PROTOCOL DATA5

Allowed values:

String CUSTOM_PROTOCOL DATA6

Im有5个字段

  2.2.3 Phone 对应 ContactsContract.CommonDataKinds.Phone

Type Alias Data column
String NUMBER DATA1  
int TYPE DATA2 Allowed values are:

String LABEL DATA3

2.2.4 Postal address 通讯地址 对应 ContactsContract.CommonDataKinds.StructuredPostal

Type Alias Data column
String FORMATTED_ADDRESS DATA1  
int TYPE DATA2 Allowed values are:

String LABEL DATA3  
String STREET DATA4  
String POBOX DATA5 Post Office Box number
String NEIGHBORHOOD DATA6  
String CITY DATA7  
String REGION DATA8  
String POSTCODE DATA9  
String COUNTRY DATA10

最长用的有 TYPE:类型;STREET:街道;CITY:市;REGION:省;POSTCODE:邮政编码;

三.代码

     3.1根据API写代码.

在api里 ContactsContract.Data 和ContactsContract.RawContacts文档里有关于insert ,update, delete,query的代码,显示出操作各自的表的代码。可以根据这些来完成我们自己的逻辑。

     3.2 查询 (查出全部联系人,在只显示姓名)需要如图:


   需求分析:由于列表中只需要姓名,所以在查询表时就只查询出姓名信息就好。当点击某个联系人再查出Email,phone等详细信息。

   3.2.1 查询联系人总表代码:

说明:由于姓名可以直接在ContactsContract.Contacts表里查到,所以如下

  1. public static final String[] PROJECTION_CONTACTS = { Contacts._ID,  
  2.             Contacts.PHOTO_ID, Contacts.IN_VISIBLE_GROUP,  
  3.             Contacts.HAS_PHONE_NUMBER, Contacts.DISPLAY_NAME,  
  4.             Contacts.CUSTOM_RINGTONE };  
  5.   
  6.     /** 
  7.      * wu0wu 
  8.      *  
  9.      * 功能:查询所有联系人PROJECTION_CONTACTS信息 
  10.      *  
  11.      * */  
  12.     public static void _getContacts(ContentResolver cr) {  
  13.         Cursor cursorContact = null;  
  14.   
  15.         try {  
  16.             cursorContact = cr.query(ContactsContract.Contacts.CONTENT_URI,  
  17.                     PROJECTION_CONTACTS, Contacts.IN_VISIBLE_GROUP + "=1",  
  18.                     nullnull);  
  19.             Log.e("wu0wu""联系人个数=" + cursorContact.getCount());  
  20.             int[] indexs = getColumnIndexs(PROJECTION_CONTACTS, cursorContact);  
  21.   
  22.             while (cursorContact.moveToNext()) {  
  23.                 Log.e("wu0wu""------------------------------------");  
  24.                 for (int i = 0; i < PROJECTION_CONTACTS.length; i++) {  
  25.                     String value = cursorContact.getString(indexs[i]);  
  26.                     Log.e("wu0wu", PROJECTION_CONTACTS[i] + "=" + value);  
  27.                 }  
  28.             }  
  29.         } catch (Exception e) {  
  30.             Log.e("wu0wu", e.toString());  
  31.         } finally {  
  32.             if (cursorContact != null) {  
  33.                 cursorContact.close();  
  34.             }  
  35.         }  
  36.     }  
  37.   
  38.     private static int[] getColumnIndexs(String[] projections, Cursor c) {  
  39.         int[] ret = new int[projections.length];  
  40.         for (int i = 0; i < projections.length; i++) {  
  41.             ret[i] = c.getColumnIndex(projections[i]);  
  42.         }  
  43.         return ret;  
  44.     }  

3.2.2 根据contactId查询联系人详细

  1. // phone   
  2.     private static final String[] PROJECTION_PHONENUMBER_CONTACT = {  
  3.             Phone.NUMBER, Phone.TYPE, Phone.LABEL };  
  4.     /* DISPLAY_NAME唯一性 */  
  5.     private static final String[] PROJECTION_DISPLAYNAME_CONTACT = { StructuredName.DISPLAY_NAME };  
  6.     // Email   
  7.     private static final String[] PROJECTION_EAMIL_CONTACT = { Email.DATA1,  
  8.             Email.TYPE, Email.LABEL };  
  9.     // IM   
  10.     private static final String[] PROJECTION_IM_CONTACT = new String[] {  
  11.             Im.DATA, Im.TYPE, Im.LABEL, Im.PROTOCOL };  
  12.     // address   
  13.     private static final String[] PROJECTION_ADDRESS_CONTACT = new String[] {  
  14.             StructuredPostal.STREET, StructuredPostal.CITY,  
  15.             StructuredPostal.REGION, StructuredPostal.POSTCODE,  
  16.             StructuredPostal.COUNTRY, StructuredPostal.TYPE,  
  17.             StructuredPostal.LABEL, StructuredPostal.POBOX,  
  18.             StructuredPostal.NEIGHBORHOOD, };  
  19.     // Organization   
  20.     private static final String[] PROJECTION_ORGANIZATION_CONTACT = new String[] {  
  21.             Organization.COMPANY, Organization.TYPE, Organization.LABEL,  
  22.             Organization.TITLE };  
  23.     // note   
  24.     private static final String[] PROJECTION_NOTES_CONTACT = new String[] { Note.NOTE };  
  25.     // nickname   
  26.     private static final String[] PROJECTION_NICKNAMES_CONTACT = new String[] {  
  27.             Nickname.NAME, Nickname.TYPE, Nickname.LABEL };  
  28.     // website   
  29.     private static final String[] PROJECTION_WEBSITES_CONTACT = new String[] {  
  30.             Website.URL, Website.TYPE, Website.LABEL };  
  31.   
  32.     /** 
  33.      * 功能:根据contactId查询联系人详细 
  34.      *  
  35.      * 在android.provider.ContactsContract.Data表里查询 
  36.      * */  
  37.     public static void _getContactByContactId(ContentResolver cr,  
  38.             String contactId) {  
  39.         Cursor c = null;  
  40.   
  41.         c = cr.query(Data.CONTENT_URI, null, Data.CONTACT_ID + "=?",  
  42.                 new String[] { contactId }, null);  
  43.   
  44.         String mimeType = null;  
  45.         String[] contentValue = null;  
  46.   
  47.         ArrayList<String[]> displayNameList = new ArrayList<String[]>();// 存显示名   
  48.         ArrayList<String[]> phoneList = new ArrayList<String[]>();// 存电话号码,可多个   
  49.         ArrayList<String[]> emailList = new ArrayList<String[]>();// 存Email,可多个   
  50.         ArrayList<String[]> imList = new ArrayList<String[]>();// 存im,可多个   
  51.         ArrayList<String[]> postalList = new ArrayList<String[]>();// 存postal地址,可多个   
  52.         ArrayList<String[]> organizationList = new ArrayList<String[]>();// 存organization组织,可多个   
  53.         ArrayList<String[]> noteList = new ArrayList<String[]>();// 存note备注   
  54.         ArrayList<String[]> nicknameList = new ArrayList<String[]>();// 存Nickname昵称   
  55.         ArrayList<String[]> websiteList = new ArrayList<String[]>();// 存Website网站   
  56.   
  57.         while (c.moveToNext()) {  
  58.             // 根据mimeType分类信息   
  59.             mimeType = c.getString(c.getColumnIndex(Data.MIMETYPE));  
  60.             if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {  
  61.                 contentValue = MyUtils.getStringInContactCursor(c,  
  62.                         PROJECTION_DISPLAYNAME_CONTACT);  
  63.                 displayNameList.add(contentValue);  
  64.             } else if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {  
  65.                 // 每个contentValue存一类PROJECTION_PHONENUMBER_CONTACT数据   
  66.                 contentValue = MyUtils.getStringInContactCursor(c,  
  67.                         PROJECTION_PHONENUMBER_CONTACT);  
  68.                 phoneList.add(contentValue);  
  69.             } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {  
  70.                 contentValue = MyUtils.getStringInContactCursor(c,  
  71.                         PROJECTION_EAMIL_CONTACT);  
  72.                 emailList.add(contentValue);  
  73.             } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType)) {  
  74.                 contentValue = MyUtils.getStringInContactCursor(c,  
  75.                         PROJECTION_IM_CONTACT);  
  76.                 imList.add(contentValue);  
  77.             } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType)) {  
  78.                 contentValue = MyUtils.getStringInContactCursor(c,  
  79.                         PROJECTION_ADDRESS_CONTACT);  
  80.                 postalList.add(contentValue);  
  81.             } else if (Organization.CONTENT_ITEM_TYPE.equals(mimeType)) {  
  82.                 contentValue = MyUtils.getStringInContactCursor(c,  
  83.                         PROJECTION_ORGANIZATION_CONTACT);  
  84.                 organizationList.add(contentValue);  
  85.             } else if (Note.CONTENT_ITEM_TYPE.equals(mimeType)) {  
  86.                 contentValue = MyUtils.getStringInContactCursor(c,  
  87.                         PROJECTION_NOTES_CONTACT);  
  88.                 noteList.add(contentValue);  
  89.             } else if (Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) {  
  90.                 contentValue = MyUtils.getStringInContactCursor(c,  
  91.                         PROJECTION_NICKNAMES_CONTACT);  
  92.                 nicknameList.add(contentValue);  
  93.             } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType)) {  
  94.                 contentValue = MyUtils.getStringInContactCursor(c,  
  95.                         PROJECTION_WEBSITES_CONTACT);  
  96.                 websiteList.add(contentValue);  
  97.             }  
  98.         }  
  99.         c.close();  
  100.   
  101.         // log   
  102.         MyUtils.logContactsDetails("displayName",PROJECTION_DISPLAYNAME_CONTACT, displayNameList);  
  103.         MyUtils.logContactsDetails("phoneNumber",PROJECTION_PHONENUMBER_CONTACT, phoneList);  
  104.         MyUtils.logContactsDetails("Email", PROJECTION_EAMIL_CONTACT,emailList);  
  105.         MyUtils.logContactsDetails("IM", PROJECTION_IM_CONTACT, imList);  
  106.         MyUtils.logContactsDetails("Address", PROJECTION_ADDRESS_CONTACT,postalList);  
  107.         MyUtils.logContactsDetails("Organization",PROJECTION_ORGANIZATION_CONTACT, organizationList);  
  108.         MyUtils.logContactsDetails("Note", PROJECTION_NOTES_CONTACT, noteList);  
  109.         MyUtils.logContactsDetails("NickName", PROJECTION_NICKNAMES_CONTACT,nicknameList);  
  110.         MyUtils.logContactsDetails("WebSit", PROJECTION_WEBSITES_CONTACT,websiteList);  
  111.     }  

用到的两个方法:

  1. public static String[] getStringInContactCursor(Cursor c,  
  2.             String[] projection) {  
  3.         String[] contentValue = new String[projection.length];  
  4.         for (int i = 0; i < contentValue.length; i++) {  
  5.             String value = c.getString(c.getColumnIndex(projection[i]));  
  6.             if (value == null) {  
  7.                 contentValue[i] = "";  
  8.             } else {  
  9.                 contentValue[i] = value;  
  10.             }  
  11.         }  
  12.         return contentValue;  
  13.     }  
  14.   
  15.     public static void logContactsDetails(String title, String[] projection,  
  16.             ArrayList<String[]> data) {  
  17.         Log.e("wu0wu""--------" + title + "--------");  
  18.       
  19.         for (int i = 0; i < data.size(); i++) {  
  20.             for (int j = 0; j < data.get(i).length; j++) {  
  21.                 Log.e("wu0wu", projection[j] + "=" + data.get(i)[j]);  
  22.             }  
  23.         }  
  24.     }  


3.3 新建联系人

接口方法:

  1. /** 
  2.      * 新建联系人的接口 
  3.      *  
  4.      * @param String 
  5.      *            accountName,accountType 为账号名账号类型,一般为NULL 
  6.      * @throws RemoteException 
  7.      * @throws OperationApplicationException 
  8.      */  
  9.   
  10.     public static String _insertContact(ContentResolver cr, String accountName,  
  11.             String accountType, String displayName, ArrayList<String[]> phone,  
  12.             ArrayList<String[]> email, ArrayList<String[]> im,  
  13.             ArrayList<String[]> address, ArrayList<String[]> organization,  
  14.             ArrayList<String[]> notes, ArrayList<String[]> nickname,  
  15.             ArrayList<String[]> website) throws RemoteException,  
  16.             OperationApplicationException {  
  17.   
  18.         ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();  
  19.   
  20.         String rawId = "";  
  21.         long rawContactId = insertRawContact(cr, accountName, accountType);  
  22.         rawId = Long.toString(rawContactId);  
  23.   
  24.         if (displayName != null) {  
  25.             insertContactDisplayname(ops, StructuredName.CONTENT_ITEM_TYPE,  
  26.                     rawId, displayName);  
  27.         }  
  28.         if (phone != null) {  
  29.             for (int j = 0; j < phone.size(); j++) {  
  30.                 String[] item = phone.get(j);  
  31.                 insertItemToContact(ops, Phone.CONTENT_ITEM_TYPE, rawId,  
  32.                         PROJECTION_PHONENUMBER_CONTACT, item);  
  33.             }  
  34.         }  
  35.         if (email != null) {  
  36.             for (int j = 0; j < email.size(); j++) {  
  37.                 String[] item = email.get(j);  
  38.                 insertItemToContact(ops, Email.CONTENT_ITEM_TYPE, rawId,  
  39.                         PROJECTION_EAMIL_CONTACT, item);  
  40.             }  
  41.         }  
  42.         if (im != null) {  
  43.             for (int j = 0; j < im.size(); j++) {  
  44.                 String[] item = im.get(j);  
  45.                 insertItemToContact(ops, Im.CONTENT_ITEM_TYPE, rawId,  
  46.                         PROJECTION_IM_CONTACT, item);  
  47.             }  
  48.         }  
  49.         if (address != null) {  
  50.             for (int j = 0; j < address.size(); j++) {  
  51.                 String[] item = address.get(j);  
  52.                 insertItemToContact(ops, StructuredPostal.CONTENT_ITEM_TYPE,  
  53.                         rawId, PROJECTION_ADDRESS_CONTACT, item);  
  54.             }  
  55.         }  
  56.         if (organization != null) {  
  57.             for (int j = 0; j < organization.size(); j++) {  
  58.                 String[] item = organization.get(j);  
  59.                 insertItemToContact(ops, Organization.CONTENT_ITEM_TYPE, rawId,  
  60.                         PROJECTION_ORGANIZATION_CONTACT, item);  
  61.             }  
  62.         }  
  63.         if (notes != null) {  
  64.             for (int j = 0; j < notes.size(); j++) {  
  65.                 String[] item = notes.get(j);  
  66.                 insertItemToContact(ops, Note.CONTENT_ITEM_TYPE, rawId,  
  67.                         PROJECTION_NOTES_CONTACT, item);  
  68.             }  
  69.         }  
  70.         if (nickname != null) {  
  71.             for (int j = 0; j < nickname.size(); j++) {  
  72.                 String[] item = nickname.get(j);  
  73.                 insertItemToContact(ops, Nickname.CONTENT_ITEM_TYPE, rawId,  
  74.                         PROJECTION_NICKNAMES_CONTACT, item);  
  75.             }  
  76.         }  
  77.         if (website != null) {  
  78.             for (int j = 0; j < website.size(); j++) {  
  79.                 String[] item = website.get(j);  
  80.                 insertItemToContact(ops, Website.CONTENT_ITEM_TYPE, rawId,  
  81.                         PROJECTION_WEBSITES_CONTACT, item);  
  82.             }  
  83.         }  
  84.         cr.applyBatch(ContactsContract.AUTHORITY, ops);  
  85.         return rawId;  
  86.     }  
  87.   
  88.     /* 
  89.      * 通过往ROWCONTACT里插入数据,获得rawId 
  90.      *  
  91.      * @param cr 
  92.      *  
  93.      * @param accountName 一般为NULL 
  94.      *  
  95.      * @param accountType 一般为NULL 
  96.      *  
  97.      * @return 
  98.      */  
  99.   
  100.     private static long insertRawContact(ContentResolver cr,  
  101.             String accountName, String accountType) {  
  102.   
  103.         ContentValues values = new ContentValues();  
  104.         values.put(RawContacts.ACCOUNT_NAME, accountName);  
  105.         values.put(RawContacts.ACCOUNT_TYPE, accountType);  
  106.         // values.put(Contacts.DISPLAY_NAME, displayName);   
  107.         Uri rawContactUri = cr.insert(RawContacts.CONTENT_URI, values);  
  108.         long rawContactId = ContentUris.parseId(rawContactUri);  
  109.         return rawContactId;  
  110.     }  
  111.   
  112.     private static void insertContactDisplayname(  
  113.             ArrayList<ContentProviderOperation> ops, String mimeType,  
  114.             String rawContactId, String displayName) throws RemoteException,  
  115.             OperationApplicationException {  
  116.   
  117.         ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI).withValue(  
  118.                 Data.MIMETYPE, mimeType).withValue(Data.RAW_CONTACT_ID,  
  119.                 rawContactId).withValue(StructuredName.DISPLAY_NAME,  
  120.                 displayName).build());  
  121.   
  122.     }  
  123.   
  124.     private static void insertItemToContact(  
  125.             ArrayList<ContentProviderOperation> ops, String mimeType,  
  126.             String rawContactId, String[] PROJECTION_CONTACT, String[] item)  
  127.             throws RemoteException, OperationApplicationException {  
  128.         // ContentValues values = new ContentValues();   
  129.         // values.put(Data.RAW_CONTACT_ID, rawContactId);   
  130.         // values.put(Data.MIMETYPE, mimeType);   
  131.         // for (int i = 0; i < PROJECTION_CONTACT.length; i++) {   
  132.         // values.put(PROJECTION_CONTACT[i], item[i]);   
  133.         // }   
  134.         // Uri dataUri = cr.insert(Data.CONTENT_URI, values);   
  135.   
  136.         Builder builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);  
  137.         builder.withYieldAllowed(true);  
  138.         builder.withValue(Data.RAW_CONTACT_ID, rawContactId);  
  139.         builder.withValue(Data.MIMETYPE, mimeType);  
  140.         for (int i = 0; i < PROJECTION_CONTACT.length; i++) {  
  141.             builder.withValue(PROJECTION_CONTACT[i], item[i]);  
  142.         }  
  143.         ops.add(builder.build());  
  144.     }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值