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.contact at 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 //添加姓名 //得到了联系人的id uri=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); //添加email values.clear(); values.put("raw_contact_id", contactid); values.put("mimetype", "vnd.android.cursor.item/email_v2"); values.put("data2", "2"); values.put("data1", "[email protected]"); 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", "[email protected]") .withValue("data2", "2") .build(); operations.add(op4); resolver.applyBatch("com.android.contacts", operations); //begin()//底层的实现,开始事物 /*for(op:options){//把操作迭代出来 cp.app//执行每一个操作 }*/ //然后事物提交 } } -------------------------------------------------------------------------- 7.分别用junit执行然后,查看结果. 对两种实现联系人添加的方式,进行底层的比较 ----------------------------------------------------- |
详细解决方案
Android学习札记-22_访问通信录中的联系人和添加联系人,使用事物添加联系人.
热度:45 发布时间:2016-05-01 11:15:53.0
相关解决方案
- android 读取byte[]中的元素解决方案
- android 标题栏兑现方式
- android 中Activity向BroadcastReceiver发送数据,该怎么解决
- Android 4.0 为什么模拟器老是提示小弟我谷歌拼音输入法已停止
- android:getSharedPreferences() 这是哪个类的方法解决思路
- android 怎么判断一个程序是否联网
- android 大量数据按周分组,该如何解决
- android RadioButton如何设置默认选中
- ksoap2-android-这个包,连接webService怎么设置超时
- android 怎么重新设置锚点
- android UI界面设计解决方案
- android 图片对象获取的有关问题
- android 怎么调用淘宝支付宝接口
- Android 沿袭InputMethodService自定义输入法
- android 关于服务连接的疑义
- android 两个activity如何通信
- android 怎么实现对view的放大和缩小
- android 教程解决方法
- android ID,该如何处理
- 准备复习2-3个月,看java+android,请问有经验者,怎么看效果最好》
- android UI线程与AsyncTask的有关问题
- android(java)中的java.net能不能和c#的system.net.sockets进行tcp通信,该如何解决
- android ListView 中的onItemClick Intent 没法跳转
- android(java) 中文乱码的有关问题
- c#c++,android,ios(iphone),php,java视屏课程 散分
- android Post文件到ASP.NET的有关问题,能收到参数收不到文件
- RIM 替 Android 开发者提供免费的 PlayBook!2月13日前
- android 动态设立控件高度
- Android test project 编译方法
- android -相机使用教程(1)解决方法