Android编程,通过ContentResolver调用系统URI实现的通讯录示例

Android的四大组件之一,ContentProvider,分为两个部分:一是数据组织工具ContentProvider,一是数据调用工具ContentResolver。对于系统已经提供的URI,如通讯录、多媒体、短信等,通常可以不需要再建立额外的数据库,再用ContentProvider进行组织,而是可以直接用ContentResolver调用这些URI,对系统数据库进行增删改查等操作,从而保证整个Android设备中数据的统一。

下面这个链接是本人前段时间为了参加MM论坛的一个小比赛所做的通讯录小demo的源码。因为最近工作和生活的一些原因,把比赛的截止日期给耽误了,所以到最后也没做美工。

如下是对通讯录表进行添加和删除的处理类ContactHandler:

[java] view
plain
copy

  1. import android.content.ContentResolver;
  2. import android.content.ContentUris;
  3. import android.content.ContentValues;
  4. import android.content.Context;
  5. import android.provider.ContactsContract.Data;
  6. import android.provider.ContactsContract.RawContacts;
  7. import android.provider.ContactsContract.CommonDataKinds.Phone;
  8. import android.provider.ContactsContract.CommonDataKinds.StructuredName;
  9. public class ContactHandler {
  10. private Context context;
  11. public ContactHandler(Context context) {
  12. this.context = context;
  13. }
  14. public void create(ContactItem item) {
  15. ContentResolver resolver = context.getContentResolver();
  16. ContentValues values = new ContentValues();
  17. long rawContactId = ContentUris.parseId(resolver.insert(RawContacts.CONTENT_URI, values));
  18. values.clear();
  19. values.put(Data.RAW_CONTACT_ID, rawContactId);
  20. values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
  21. values.put(StructuredName.DISPLAY_NAME, item.getValue(ContactItem.TYPE_NAME));
  22. resolver.insert(Data.CONTENT_URI, values);
  23. values.clear();
  24. values.put(Data.RAW_CONTACT_ID, rawContactId);
  25. values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
  26. values.put(Phone.NUMBER, item.getValue(ContactItem.TYPE_PHONE));
  27. values.put(Phone.TYPE, Phone.TYPE_MOBILE);
  28. resolver.insert(Data.CONTENT_URI, values);
  29. }
  30. public void delete(ContactItem item) {
  31. ContentResolver resolver = context.getContentResolver();
  32. String[] args = {item.getValue(ContactItem.TYPE_CONTACT_ID)};
  33. resolver.delete(RawContacts.CONTENT_URI, Data.CONTACT_ID + "=?", args);
  34. resolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=?", args);
  35. }
  36. }

如下是一次性获取通讯录列表信息的类ContractGenerator:

[java] view
plain
copy

  1. import java.io.InputStream;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import android.content.ContentResolver;
  5. import android.content.ContentUris;
  6. import android.content.Context;
  7. import android.database.Cursor;
  8. import android.graphics.Bitmap;
  9. import android.graphics.BitmapFactory;
  10. import android.net.Uri;
  11. import android.provider.ContactsContract.Contacts;
  12. import android.provider.ContactsContract.CommonDataKinds.Phone;
  13. import android.provider.ContactsContract.CommonDataKinds.Photo;
  14. public class ContactGenerator {
  15. private Context context;
  16. private static final String[] PROJECTECTION = {
  17. Phone.DISPLAY_NAME,
  18. Phone.NUMBER,
  19. Photo.PHOTO_ID,
  20. Phone.CONTACT_ID,
  21. };
  22. private static final int DISPLAY_NAME_INDEX = 0;
  23. private static final int PHONE_NUMBER_INDEX = 1;
  24. private static final int PHOTO_ID_INDEX = 2;
  25. private static final int CONTACT_ID_INDEX = 3;
  26. public ContactGenerator(Context context) {
  27. this.context = context;
  28. }
  29. public List<ContactItem> generateList() {
  30. List<ContactItem> list = new ArrayList<ContactItem>();
  31. ContentResolver resolver = context.getContentResolver();
  32. Cursor cursor = resolver.query(Phone.CONTENT_URI, PROJECTECTION, null, null,  PROJECTECTION[DISPLAY_NAME_INDEX] + " ASC");
  33. while (cursor.moveToNext()) {
  34. String name = cursor.getString(DISPLAY_NAME_INDEX);
  35. String phone = cursor.getString(PHONE_NUMBER_INDEX);
  36. long photoId = cursor.getLong(PHOTO_ID_INDEX);
  37. long contactId = cursor.getLong(CONTACT_ID_INDEX);
  38. Bitmap head = null;
  39. if (photoId > 0) {
  40. Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
  41. InputStream input = Contacts.openContactPhotoInputStream(resolver, uri);
  42. head = BitmapFactory.decodeStream(input);
  43. }
  44. ContactItem item = new ContactItem(context, name, phone, head);
  45. item.setContactId(contactId);
  46. list.add(item);
  47. }
  48. return list;
  49. }
  50. }

对系统通讯录数据库进行操作,需要在AndroidManifest.xml文件中添加如下两个用户权限:

[html] view
plain
copy

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

对于ContentResolver的使用,主要是如下几个步骤:

1.      通过Context的getContentResolver()方法获取ContentResolver实例;

2.      调用ContentResolver的insert、delete、update、query方法对数据表进行增删改查操作,对数据表的指定是通过系统URI来完成,这些URI会作为参数传入上述4个方法中。详情参见Android API文档。

另外,如下的博文分享了包括通讯录、多媒体、短信在内的系统URI:

http://blog.csdn.net/lyx2007825/article/details/7280043

就本文中的示例而言,Java源码文件如下图:

除了前述两个对ContentResolver的操作外,本通讯录的UI控件主要基于二级列表ExpandableListView,所以有继承自BaseExpandableListAdapter的二级列表数据处理适配器类ContactAdapter。另外,ContactItem是数据实体类。其余两个Activity类的界面类。

最后需要说明的是,对于系统已经提供了URI的数据资源,没有必要再用ContentProvider对其进行封装管理,因而本示例中并没有用到ContentProvider,只用到ContentResolver。

微天下版主修改 www.imvbo.com

时间: 2024-10-20 06:10:21

Android编程,通过ContentResolver调用系统URI实现的通讯录示例的相关文章

【Android】使用Intent调用系统其它程序,使用onKeyDown对音量键的监听,长按事件

Intent在安卓编程中非常常见,在<[Android]多个Activity之间利用bundle传递数值>(点击打开链接)中已经展示了它可以唤醒其它Activity并在Activity之间传递数据.其实Intent的作用远非于此,它还可以调用系统中其它固有程序,比如拨打电话.发送短信等.onKeyDown也是如此,不仅仅可以对设备的菜单键进行监听,这在<[Android]各式各样的弹出框与对菜单键.返回键的监听>(点击打开链接)中已经展示过的,对设备的音量调节键也是可以监听的, 下

Android图片裁剪功能——调用系统裁剪

花了两天时间看了下android的图片裁剪功能的实现.其实刚开始做这个我挺虚的,以为整个功能都需要自己写出来,但查了些资料,发现android已经提供了裁剪功能,需要的话自己调用就成了.soga,这下轻松多了. 首先推荐几篇博客 Android大图片裁剪终极解决方案 要想弄明白裁剪功能,这系列博客非常重要,你可以不看我下面总结的,但你一定要看他这系列的几篇文章. Android 图片裁剪功能实现详解(类似QQ自定义头像裁剪) 这篇也不错,比较喜欢他的注释.虽然也有些误导,比如说他有一段对setD

高版本Android如何利用反射调用系统隐藏的远程服务拦截来电

要说拦截Android系统来电,就不得不说起在低版本的时候Android提供给开发者使用的一个方法:endCall(),但由于谷歌后来考虑到对于一部手机来说,最重要的功能就是打电话了,如果这个功能随随便便就被人屏蔽了,安全性太差,所以在高版本的Android将这个方法屏蔽了,不再在TelephoneManager中暴露这个方法. 那么我们下面的目标就是要想办法调用到这个方法,当然首先我们还是需要实现一个广播接收者,来接收电话状态改变的广播,这里使用在服务中动态注册广播接收者的方法来实现,主要好处

Android连接wifi,调用系统API【转】

本文转载自:http://blog.csdn.net/aaa1050070637/article/details/54136472 直接上代码,简单粗暴,一看就懂 [java] view plain copy import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.ScanResult; impor

【读书笔记-《Android游戏编程之从零开始》】6.Android 游戏开发常用的系统控件(TabHost、ListView)

3.9 TabSpec与TabHost TabHost类官方文档地址:http://developer.android.com/reference/android/widget/TabHost.html Android 实现tab视图有2种方法,一种是在布局页面中定义<tabhost>标签,另一种就是继承tabactivity.但是我比较喜欢第二种方式,应为如果页面比较复杂的话你的XML文件会写得比较庞大,用第二种方式XML页面相对要简洁得多. <?xml version="1

Android 实例讲解添加本地图片和调用系统拍照图片

在项目的开发过程我们离不开图片,而有时候需要调用本地的图片,有时候需要调用拍照图片.同时实现拍照的方法有两种,一种是调用系统拍照功能,另一种是自定义拍照功能.而本博文目前只讲解第一种方法,第二种方法后期在加以讲解. 添加本地图片和调用系统拍照图片主要是通过调用acitivity跳转startActivityForResult(Intent intent, int requestCode)方法和activity返回结果onActivityResult(int requestCode, int re

Android 调用系统通讯录

这个过程有三步:1)许可向你的应用程序的manifest中添加读取通讯录数据的许可  <uses-permission android:name="android.permission.READ_CONTACTS" />    <uses-permission android:name="android.permission.WRITE_CONTACTS" /> 2)调用Contact Picker在你的activity中,创建一个Inten

Android调用系统相机和相册

准备工作 权限 <!-- 往SDCard写入数据权限 --> <uses-permission android:name="android.permission. WRITE_EXTERNAL_STORAGE" /> <!--请求访问使用照相设备--> <uses-permission android:name="android.permission.CAMERA" /> 常量 public final static

Android上传图片之调用系统拍照和从相冊选择图片

Android上传图片之调用系统拍照和从相冊选择图片 本篇文章已授权微信公众号 guolin_blog (郭霖)独家公布 前言: 万丈高楼平底起,万事起于微末.不知不觉距离上篇博文已近四个月,2015年12月17日下午发了第一篇博文.如今是2016年4月6日.时间间隔长的过分啊,我自己都看不下去了. 原因呢?当然是自己的原因.事实上是有非常多时间来些博客的,可是这些时间都花在DOTA上了(还是太年轻啊).请原谅我的过错--. 一.概述: 如今差点儿应用都会用到上传图片的功能,而要上传图片,首先得