Android入门:增删改查通讯录

xiaoxiao2021-02-27  556

转自:http://blog.csdn.net/xiazdong/article/details/7713419

一、通讯录应用介绍

通讯录应用是Android自带的应用程序,我们看到此应用的时候,可能只认为这是一个应用,用数据库存储数据,但是实际上不是这样的。

通讯录是ContentProvider的应用,通讯录由两部分组成:

(1)com.android.providers.contacts的ContentProvider:真正存储数据的ContentProvider

(2)com.android.contacts:运用ContentResolver获取数据的图形用户界面;

二、获取ContactProvider的源代码

Android源代码:   http://my.oschina.net/zhanglubing/blog/40623 用Git获取;

如果要获取ContactProvider,则安装git,并打开git bash,输入

git clone https://android.googlesource.com/platform/packages/providers/ContactsProvider.git 即可;

目录结构如下:

为何要获取ContactProvider的源代码呢?

因为如果要访问ContentProvider,必须要了解URI的设置(authority,path等);只有查看源代码才能够知道;

AndroidManifest.xml为清单文件,列出了ContactProvider的authorities,以及要访问通讯录需要的权限;

[html]  view plain  copy <span style="font-family:KaiTi_GB2312;font-size:16px;"> <uses-permission android:name="android.permission.READ_CONTACTS" />    <uses-permission android:name="android.permission.WRITE_CONTACTS" /></span>  

主要的通讯录程序为ContactsProvider2.Java

authorities=contacts或com.android.contacts;

三、通讯录数据库结构介绍

表结构如下:

通讯录是存放在/data/data/com.android.providers.contacts/databases/contacts2.db,里面主要的表有:

(1)raw_contacts:存放联系人的ID,

_id属性为主键,声明为autoincrement,即不需要手动设置,其他属性也不需要手动设置就有默认值;

display_name属性为姓名;

(2)mimetypes:存放数据的类型,比如"vnd.android.cursor.item/name"表示“姓名”类型的数据,"vnd.android.cursor.item/phone_v2"表示“电话”类型的数据;

(3)data:存放具体的数据;

raw_contact_id属性用来连接raw_contacts表,每条记录表示一个具体数据;我们主要的数据(email、phone等)都存放在data表;

data1属性存放总数据;

data2属性:

-如果此记录存放姓名,则data2存放名;

-如果此记录存放电话,则data2存放类型,比如手机、家电;

-如果此记录存放组织,则data2存放类型,比如公司、其他;

-如果此记录存放地址,则data2存放类型,比如住宅,单位等;

四、编程提示

URI

对raw_contacts表添加、删除、更新操作: URI =  content://com.android.contacts/raw_contacts; 对data表添加、删除、更新操作: URI =  content://com.android.contacts/data; 根据email对data表查询

URI =     content://com.android.contacts/data/emails/filter/*

根据电话号码对data表查询

URI =     content://com.android.contacts/data/phone/filter/*

如果要根据ID查询电话,可以 URI = content://com.android.contacts/data; 然后where条件为:raw_contact_id=? and mimetype = ?

MIMETYPE 电话:vnd.android.cursor.item/phone_v2 姓名:vnd.android.cursor.item/name 邮件:vnd.android.cursor.item/email_v2 通信地址:vnd.android.cursor.item/postal-address_v2 组织:vnd.android.cursor.item/organization 照片:vnd.android.cursor.item/photo

Data中的常量

Data._ID: "_id"

Data.DISPLAY_NAME:“display_name”

Data.DATA1:“data1”

Data.DATA2:“data2”

Data.RAW_CONTACT_ID:“raw_contact_id”

Data.MIMETYPE:“mimetype”

五、对通信录做增删改查

简单的说:对通讯录操作就是对一个普通的ContentProvider操作;

1.Query

(1)根据电话号码查询姓名 [java]  view plain  copy //根据电话号码查询姓名(在一个电话打过来时,如果此电话在通讯录中,则显示姓名)       public void testReadNameByPhone(){           String phone = "12345678";           //uri=  content://com.android.contacts/data/phones/filter/#           Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/"+phone);               ContentResolver resolver = this.getContext().getContentResolver();           Cursor cursor = resolver.query(uri, new String[]{Data.DISPLAY_NAME}, nullnullnull); //从raw_contact表中返回display_name           if(cursor.moveToFirst()){               Log.i("Contacts""name="+cursor.getString(0));           }       }   (2)查询所有的联系人 [java]  view plain  copy //读取通讯录的全部的联系人   //需要先在raw_contact表中遍历id,并根据id到data表中获取数据   public void testReadAll(){       //uri = content://com.android.contacts/contacts       Uri uri = Uri.parse("content://com.android.contacts/contacts"); //访问raw_contacts表       ContentResolver resolver = this.getContext().getContentResolver();       Cursor cursor = resolver.query(uri, new String[]{Data._ID}, nullnullnull);  //获得_id属性       while(cursor.moveToNext()){           StringBuilder buf = new StringBuilder();           int id = cursor.getInt(0);//获得id并且在data中寻找数据           buf.append("id="+id);           uri = Uri.parse("content://com.android.contacts/contacts/"+id+"/data"); //如果要获得data表中某个id对应的数据,则URI为content://com.android.contacts/contacts/#/data           Cursor cursor2 = resolver.query(uri, new String[]{Data.DATA1,Data.MIMETYPE}, null,nullnull);  //data1存储各个记录的总数据,mimetype存放记录的类型,如电话、email等           while(cursor2.moveToNext()){               String data = cursor2.getString(cursor2.getColumnIndex("data1"));               if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/name")){       //如果是名字                   buf.append(",name="+data);               }               else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/phone_v2")){  //如果是电话                   buf.append(",phone="+data);               }               else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/email_v2")){  //如果是email                   buf.append(",email="+data);               }               else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/postal-address_v2")){ //如果是地址                   buf.append(",address="+data);               }               else if(cursor2.getString(cursor2.getColumnIndex("mimetype")).equals("vnd.android.cursor.item/organization")){  //如果是组织                   buf.append(",organization="+data);               }           }           String str = buf.toString();           Log.i("Contacts", str);       }   }   2.Insert (1)一步一步添加数据 注意:对某个联系人插入姓名、电话等记录时必须要插入Data.MIMETYPE(或者是"mimetype")属性,而不是插入"mimetype_id"!  比如:values.put(Data.MIMETYPE,"vnd.android.cursor.item/phone_v2"); [java]  view plain  copy //一步一步添加数据       public void testAddContacts(){           //插入raw_contacts表,并获取_id属性           Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");           ContentResolver resolver = this.getContext().getContentResolver();           ContentValues values = new ContentValues();           long contact_id = ContentUris.parseId(resolver.insert(uri, values));           //插入data表           uri = Uri.parse("content://com.android.contacts/data");           //add Name           values.put("raw_contact_id", contact_id);           values.put(Data.MIMETYPE,"vnd.android.cursor.item/name");           values.put("data2""zdong");           values.put("data1""xzdong");           resolver.insert(uri, values);           values.clear();           //add Phone           values.put("raw_contact_id", contact_id);           values.put(Data.MIMETYPE,"vnd.android.cursor.item/phone_v2");           values.put("data2""2");   //手机           values.put("data1""87654321");           resolver.insert(uri, values);           values.clear();           //add email           values.put("raw_contact_id", contact_id);           values.put(Data.MIMETYPE,"vnd.android.cursor.item/email_v2");           values.put("data2""2");   //单位           values.put("data1""xzdong@xzdong.com");           resolver.insert(uri, values);       }   (2)批量添加数据 核心代码: (1)ContentProviderOperation operation = ContentProviderOperation.newInsert(uri).withValue("key","value").build(); (2)resolver.applyBatch("authorities",operations);//批量提交 [java]  view plain  copy public void testAddContactsInTransaction() throws Exception {       Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");       ContentResolver resolver = this.getContext().getContentResolver();       ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();       // 向raw_contact表添加一条记录       //此处.withValue("account_name", null)一定要加,不然会抛NullPointerException       ContentProviderOperation operation1 = ContentProviderOperation               .newInsert(uri).withValue("account_name"null).build();       operations.add(operation1);       // 向data添加数据       uri = Uri.parse("content://com.android.contacts/data");       //添加姓名       ContentProviderOperation operation2 = ContentProviderOperation               .newInsert(uri).withValueBackReference("raw_contact_id"0)               //withValueBackReference的第二个参数表示引用operations[0]的操作的返回id作为此值               .withValue("mimetype""vnd.android.cursor.item/name")               .withValue("data2""xzdong").build();       operations.add(operation2);       //添加手机数据       ContentProviderOperation operation3 = ContentProviderOperation               .newInsert(uri).withValueBackReference("raw_contact_id"0)               .withValue("mimetype""vnd.android.cursor.item/phone_v2")               .withValue("data2""2").withValue("data1""0000000").build();       operations.add(operation3);       resolver.applyBatch("com.android.contacts", operations);   }  

3.Delete 核心思想: (1)先在raw_contacts表根据姓名(此处的姓名为name记录的data2的数据而不是data1的数据)查出id; (2)在data表中只要raw_contact_id匹配的都删除; [java]  view plain  copy public void testDelete()throws Exception{       String name = "xzdong";       //根据姓名求id       Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");       ContentResolver resolver = this.getContext().getContentResolver();       Cursor cursor = resolver.query(uri, new String[]{Data._ID},"display_name=?"new String[]{name}, null);       if(cursor.moveToFirst()){           int id = cursor.getInt(0);           //根据id删除data中的相应数据           resolver.delete(uri, "display_name=?"new String[]{name});           uri = Uri.parse("content://com.android.contacts/data");           resolver.delete(uri, "raw_contact_id=?"new String[]{id+""});       }   }   4.Update

核心思想:

(1)不需要更新raw_contacts,只需要更新data表;

(2)uri=content://com.android.contacts/data 表示对data表进行操作;

[java]  view plain  copy public void testUpdate()throws Exception{       int id = 1;       String phone = "999999";       Uri uri = Uri.parse("content://com.android.contacts/data");//对data表的所有数据操作       ContentResolver resolver = this.getContext().getContentResolver();       ContentValues values = new ContentValues();       values.put("data1", phone);       resolver.update(uri, values, "mimetype=? and raw_contact_id=?"new String[]{"vnd.android.cursor.item/phone_v2",id+""})    }  
转载请注明原文地址: https://www.6miu.com/read-201.html

最新回复(0)