首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

Android学习札记-22_访问通信录中的联系人和添加联系人,使用事物添加联系人.

2013-03-19 
Android学习笔记---22_访问通信录中的联系人和添加联系人,使用事物添加联系人...Android学习笔记---22_访

Android学习笔记---22_访问通信录中的联系人和添加联系人,使用事物添加联系人...
Android学习笔记---22_访问通信录中的联系人和添加联系人,使用事物添加联系人...22_访问通信录中的联系人和添加联系人-----------------------------------1.ContentProvider,十分重要:比如短信里的信息,和呼叫记录,和图库中的图片,还有收藏夹,还有浏览器的书签都是通过ContentProvider,从手机卡上取得手机的信息等等,都要用到ContentProvider------------------------------------2.在界面添加联系人:  点击:应用程序中的通讯录应用,然后,点击menu按钮,然后添加联系人--------------------------3.联系人的内容是添加在一个数据库中的  com.android.providers.contacts//联系人的相关(数据库共享者的)应用  这个数据库文件就存在:data/data/com.android.providers.contacts/database下  contact2.db----------------------------------------  com.android.contacts//联系人的相关(界面的)应用  两者是分开的:-----------------------------------------------4.联系人的id,是通过这张表存的  联系人的各项数据,联系人的电话,email等存在data表中--------------------------------------  这张表和data表示一对多的-------------------------------5.a.在data表中,通过mimetype_id来区分是什么数据,比如电话,    姓名,email等  b.这个mimetype_id,是引用的mimetype这个表中的id;  c.data表中的部分字段    data2用来存,电话的类型,比如家庭电话,手机等    data1用来存手机号,姓和名    data2也用来存email的类型,和名字,data3存姓-----------------------------------------------------  d.cells表用来存呼叫记录---------------------------------------------  e.raw_contacts表    display_name是用来存放姓加名的组合,    通过这个表的id和data表中的一个外键,就可以知道某几行属于哪个联系人的信息----------------------------------------  f.当data表中插入姓名的时候,才会发出update更新raw_contacts.中的姓名字段    这个字段是用来快速的得到联系人名字的------------------------------------------------------3.当在界面中完成插入一个联系人以后,以及理解了三种表后,开始写代码取出相关联系人  数据------------------------4.利用junit test测试 a.新建contact项目 b./contact/src/com/credream/contact/ContactTest.java   package com.credream.contact;
import android.content.ContentResolver;import android.database.Cursor;import android.net.Uri;import android.test.AndroidTestCase;import android.util.Log;
public class ContactTest extends AndroidTestCase{public static final String TAG="ContactTest";//获取所有联系人,这时候涉及到联系人隐私,这里需要在清单文件添加权限//需要在:android_source2.2.zip\packages\providers\ContactsProvider目录下找到清单文件,copy相应的权限,放到清单文件中//android.permission.READ_CONTACTS /*<!--添加联系薄访问权限--> <uses-permission  android:name="android.permission.READ_CONTACTS"/>*/public void testContact()throws Exception{//要访问的业务提供者,在源码的//android_source2.2.zip\packages\providers\ContactsProvider这个路径下//打开清单文件:AndroidManifest.xml//找到这个内容提供者:/*   <provider android:name="ContactsProvider2"            android:authorities="contacts;com.android.contacts"           uri-permission android:pathPattern=".*" />        </provider>*///那么怎么通过这个uri,访问内容提供者的固定的哪个数据//可以在源码中找到这个路径下的类:ContactsProvider2//android_source2.2.zip\packages\providers\ContactsProvider\src\com\android\providers\contacts//   private static final ProfileAwareUriMatcher sUriMatcher =       // new ProfileAwareUriMatcher(UriMatcher.NO_MATCH);//由于把业务路径都封装在了这里//可以通过sUriMatcher来查找业务路径,找到了如下路径// static {        // Contacts URI matching table/*        final UriMatcher matcher = sUriMatcher;        matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS);}每一个业务路径代表什么意思呢?通过英文单词猜测意思matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS);操作所有联系人        matcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);//操作某个联系人        matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_ID_DATA);//联系人有很多数据,操作某个联系人的数据*/Uri uri=Uri.parse("content://com.android.contacts/contacts");//访问通讯录中的所有的联系人//这时候得到的是raw_contacts数据ContentResolver resolver=getContext().getContentResolver();Cursor cursor=resolver.query(uri, new String[]{"_id"}, null, null, null);while (cursor.moveToNext()){StringBuilder sb=new StringBuilder("contactid=");int contactid=cursor.getInt(0);sb.append(contactid);uri=Uri.parse("content://com.android.contacts/contacts/"+contactid+"/data");//通过这个路径可以查询到这个联系人的所有数据Cursor dataCursor=resolver.query(uri, new String[]{"mimetype","data1","data2"}, null, null, null);while(dataCursor.moveToNext()){String data=dataCursor.getString(dataCursor.getColumnIndex("data1"));String type=dataCursor.getString(dataCursor.getColumnIndex("mimetype"));if("vnd.android.cursor.item/name".equals(type)){//姓名数据sb.append("name="+data);}else if ("vnd.android.cursor.item/email_v2".equals(type)) {//email数据sb.append("email="+data);}else if ("vnd.android.cursor.item/phone_v2".equals(type)) {//phone数据sb.append("phone="+data);}}Log.i(TAG, sb.toString());}}}------------------------------c./contact/AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.credream.contact"    android:versionCode="1"    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="8" />
    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name" >        <activity            android:label="@string/app_name"            android:name=".ContactActivity" >            <intent-filter >                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>              <uses-library android:name="android.test.runner" />            </application> <instrumentation android:name="android.test.InstrumentationTestRunner"  android:targetPackage="com.credream.contact" android:label="Tests for My App" /> <!--添加联系薄访问权限--> <uses-permission  android:name="android.permission.READ_CONTACTS"/> </manifest>-----------------------------1.异常原因:java.lang.IllegalArgumentException: URI: content://com.android.contacts/contacts1/data, calling user: com.credream.contact, calling package:com.credream.contactat android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:144)at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:114)at android.content.ContentProviderProxy.bulkQueryInternal(ContentProviderNative.java:330)at android.content.ContentProviderProxy.query(ContentProviderNative.java:366)at android.content.ContentResolver.query(ContentResolver.java:245)at com.credream.contact.ContactTest.testContact(ContactTest.java:56)at java.lang.reflect.Method.invokeNative(Native Method)at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:520)at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)-------------------------------------原因由于:uri=Uri.parse("content://com.android.contacts/contacts"+contactid+"/data");uri出错,正确写的应该是这样的:uri=Uri.parse("content://com.android.contacts/contacts/"+contactid+"/data");---------------------------8.a.添加意志过滤器  b.运行结果  03-16 15:26:00.310: I/ContactTest(21022): contactid=1name=785月03-16   15:26:00.390: I/ContactTest(21022): contactid=2phone=15355488name=李德伟  email=my@.souhu.com
---------------------------3.通常电话来了以后,要根据电话从通讯录中,查询出这个人的姓名,然后显示这个人的名字  在来电显示上---------------------3.1:根据电话,查询相关姓名的代码:在类中添加方法,并在junit test中执行----------------------------------------//根据号码获取联系人的姓名public void testContactName()throws Exception{//根据来电号码取得业务路径//电话是数据,所以找data//android_source2.2.zip\packages\providers\ContactsProvider\src\com\android\providers\contacts//data/phones/filter/*这个路径就可以了,看文档也可以找到  String phone="15355488";Uri uri=Uri.parse("content://com.android.contacts/data/phones/filter/"+phone);ContentResolver resolver=getContext().getContentResolver();Cursor cursor=resolver.query(uri, new String[]{"display_name"}, null, null, null);if(cursor.moveToFirst()){String name=cursor.getString(0);Log.i(TAG, name);}}-------------------------------------4.控制台执行结果03-16 15:48:35.500: I/ContactTest(25837): 李德伟
------------------------------------------------------5.添加联系人:代码://添加联系人public void testAddContact(){//第一步,在raw_contacts表中添加联系人id,raw_contacts代表操作data表中的数据//第二部将联系人的各项信息添加到data表中;Uri uri=Uri.parse("content://com.android.contacts/raw_contacts");ContentResolver resolver=getContext().getContentResolver();ContentValues values=new ContentValues(); long contactid=ContentUris.parseId(resolver.insert(uri, values));//可以得到uri的id//添加姓名//得到了联系人的iduri=Uri.parse("content://com.android.contacts/data");values.put("raw_contact_id", contactid);values.put("mimetype", "vnd.android.cursor.item/name");values.put("data2", "zhangxiaoxiao");//insert方法内容,先根据mimetype在mimetypes表中查找到相关数据,然后//再插入到data表中resolver.insert(uri, values);//uri//resolver.insert(uri, values)相当于得到了一个含有id的uri//content://com.android.contacts/raw_contacts/10号码,就是他的id//添加电话values.clear();values.put("raw_contact_id", contactid);values.put("mimetype", "vnd.android.cursor.item/phone_v2");values.put("data2", "2");values.put("data1", "13676548");resolver.insert(uri, values);//添加emailvalues.clear();values.put("raw_contact_id", contactid);values.put("mimetype", "vnd.android.cursor.item/email_v2");values.put("data2", "2");values.put("data1", "zhangxiaoxiao@csdn.net");resolver.insert(uri, values);//vnd.android.cursor.item/email_v2}-------------------------------------------------6.使用://在同一个事物中完成联系人各项事物的添加public void testAddContact2()throws Exception{Uri uri=Uri.parse("content://com.android.contacts/raw_contacts");ContentResolver resolver=getContext().getContentResolver();ArrayList<ContentProviderOperation> operations=new ArrayList<ContentProviderOperation>();ContentProviderOperation opi=ContentProviderOperation.newInsert(uri).withValue("account_name", null).build();//这个的作用是添加谷歌的账号,如果有的话,可以绑定谷歌的账号operations.add(opi);uri=Uri.parse("content://com.android.contacts/data");ContentProviderOperation op2=ContentProviderOperation.newInsert(uri).withValueBackReference("raw_contact_id", 0)//使用集合中0索引所对应的操作对象,执行后返回的记录id,作为这个值//使用索引为0的对象,执行插入后,返回的id值作为这个值.withValue("mimetype", "vnd.android.cursor.item/name").withValue("data2", "创梦").build();operations.add(op2); ContentProviderOperation op3=ContentProviderOperation.newInsert(uri).withValueBackReference("raw_contact_id", 0)//使用集合中0索引所对应的操作对象,执行后返回的记录id,作为这个值//使用索引为0的对象,执行插入后,返回的id值作为这个值.withValue("mimetype", "vnd.android.cursor.item/phone_v2").withValue("data1", "15066659414").withValue("data2", "2").build();operations.add(op3);ContentProviderOperation op4=ContentProviderOperation.newInsert(uri).withValueBackReference("raw_contact_id", 0)//使用集合中0索引所对应的操作对象,执行后返回的记录id,作为这个值//使用索引为0的对象,执行插入后,返回的id值作为这个值.withValue("mimetype", "vnd.android.cursor.item/email_v2").withValue("data1", "lidewei@qq.com").withValue("data2", "2").build();operations.add(op4);resolver.applyBatch("com.android.contacts", operations);//begin()//底层的实现,开始事物/*for(op:options){//把操作迭代出来cp.app//执行每一个操作}*///然后事物提交}}--------------------------------------------------------------------------7.分别用junit执行然后,查看结果.  对两种实现联系人添加的方式,进行底层的比较-----------------------------------------------------

热点排行
Bad Request.