Android手机的通讯录联系人全部都存在系统的数据库中,如果须要获得通讯里联系人的信息就须要访问系统的数据库,才能将信息拿出来。 这一篇文章我主要带领同学们熟悉Android的通讯录机制。

图中选中的数据库 contacts2.db就是系统储存联系人的数据库
 

打开contacts.db后 发面里面有一堆表,同学们先别慌张。今天我们主要讨论红框内的4个比较常用的表,后期我在介绍其它表的使用。这里说一下如果你想在真机上查看数据库的话必需要先获得root权限,否则无法查看。

 

 
1.contacts 表

_id :表的ID,主要用于其它表通过contacts 表中的ID可以查到相应的数据。
display_name: 联系人名称
photo_id:头像的ID,如果没有设置联系人头像,这个字段就为空
times_contacted:通话记录的次数
last_time_contacted: 最后的通话时间 
lookup :是一个持久化的储存 因为用户可能会改名子 但是它改不了lookup
 

2.data表
 

raw_contact_id:通过raw_contact_id可以找到 raw_contact表中相对的数据。

data1 到 data15 这里保存着联系人的信息 联系人名称 联系人电话号码 电子邮件 备注 等等。

3.phone_look_up表

data_id : 通过data_id可以找到 datat表中相对的数据。
raw_contact_id : 通过raw_contact_id 可以找到 raw_contact_表中相对的数据。
normalized_number: 这个字段就比较有意思了,它是将每个电话号码逆序排列。

 

4.raw_contact表

version :版本号,用于监听变化
deleted :删除标志, 0为默认 1 表示这行数据已经删除
display_name : 联系人名称
last_time_contacts : 最后联系的时间

 

有关这些的源码都在android.provider.ContactsContract这个类里面,如果想深入了解的话 可以去看看,数据库相关的操作 联查啊 啥的 都在里面。

下面说说代码是怎么用的

先说说 Phone.CONTENT_URI,获取联系人的时候需要去这个url中去找数据 。它所指向的其实是“content:// com.android.contacts/data/phones”。这个url 对应着contacts表 和 raw_contacts表 以及 data表
所以说我们的数据都是从这三个表中获取的。

这里强调一下query第二个参数

  1. private static final String[] PHONES_PROJECTION = new String[] {
  2. Phone.DISPLAY_NAME, Phone.NUMBER, Photo.PHOTO_ID,Phone.CONTACT_ID };

它的意思是只去表中找 显示名称 电话号码 头像ID 联系人ID 这4个数据 ,如果你须要其它数据 的话 就须要修改这里。

获得手机通讯录联系人信息

  1. /**得到手机通讯录联系人信息**/
  2. private void getPhoneContacts() {
  3. ContentResolver resolver = mContext.getContentResolver();
  4. // 获取手机联系人
  5. Cursor phoneCursor = resolver.query(Phone.CONTENT_URI,PHONES_PROJECTION, null, null, null);
  6. if (phoneCursor != null) {
  7. while (phoneCursor.moveToNext()) {
  8. //得到手机号码
  9. String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);
  10. //当手机号码为空的或者为空字段 跳过当前循环
  11. if (TextUtils.isEmpty(phoneNumber))
  12. continue;
  13. //得到联系人名称
  14. String contactName = phoneCursor.getString(PHONES_DISPLAY_NAME_INDEX);
  15. //得到联系人ID
  16. Long contactid = phoneCursor.getLong(PHONES_CONTACT_ID_INDEX);
  17. //得到联系人头像ID
  18. Long photoid = phoneCursor.getLong(PHONES_PHOTO_ID_INDEX);
  19. //得到联系人头像Bitamp
  20. Bitmap contactPhoto = null;
  21. //photoid 大于0 表示联系人有头像 如果没有给此人设置头像则给他一个默认的
  22. if(photoid > 0 ) {
  23. Uri uri =ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,contactid);
  24. InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(resolver, uri);
  25. contactPhoto = BitmapFactory.decodeStream(input);
  26. }else {
  27. contactPhoto = BitmapFactory.decodeResource(getResources(), R.drawable.contact_photo);
  28. }
  29. mContactsName.add(contactName);
  30. mContactsNumber.add(phoneNumber);
  31. mContactsPhonto.add(contactPhoto);
  32. }
  33. phoneCursor.close();
  34. }
  35. }

获得手机sim卡联系人信息

sim卡和手机本人 获取的方式类似 只是url有点不一样 ,须要注意的一点是 sim卡 是没有联系人头像的。

  1. /**得到手机SIM卡联系人人信息**/
  2. private void getSIMContacts() {
  3. ContentResolver resolver = mContext.getContentResolver();
  4. // 获取Sims卡联系人
  5. Uri uri = Uri.parse("content://icc/adn");
  6. Cursor phoneCursor = resolver.query(uri, PHONES_PROJECTION, null, null,
  7. null);
  8. if (phoneCursor != null) {
  9. while (phoneCursor.moveToNext()) {
  10. // 得到手机号码
  11. String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);
  12. // 当手机号码为空的或者为空字段 跳过当前循环
  13. if (TextUtils.isEmpty(phoneNumber))
  14. continue;
  15. // 得到联系人名称
  16. String contactName = phoneCursor
  17. .getString(PHONES_DISPLAY_NAME_INDEX);
  18. //Sim卡中没有联系人头像
  19. mContactsName.add(contactName);
  20. mContactsNumber.add(phoneNumber);
  21. }
  22. phoneCursor.close();
  23. }
  24. }
这个界面就可以看到联系人的 名称 号码 以及头像了。如果想在模拟器上看须要将图片拷贝到SD卡中,然后在联系人中设置一下,这里就可以看到头像了,或者 真机上会比较清楚、
 

 
任意点击一个联系人会调用系统拨打电话的界面 ,代码如下。
  1. //调用系统方法拨打电话
  2. Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri
  3. .parse("tel:" + mContactsNumber.get(position)));
  4. startActivity(dialIntent);

最重要的是须要AndroidManifest.xml中 加入权限 否则代码会报错的。 千万别忘了。

  1. <!-- 读取联系人权限 -->
  2. <uses-permission android:name="android.permission.READ_CONTACTS"/>
  3. <!-- 拨打电话权限 -->
  4. <uses-permission android:name="android.permission.CALL_PHONE"/>

下面给出完整的代码

  1. import java.io.InputStream;
  2. import java.util.ArrayList;
  3. import android.app.ListActivity;
  4. import android.content.ContentResolver;
  5. import android.content.ContentUris;
  6. import android.content.Context;
  7. import android.content.Intent;
  8. import android.database.Cursor;
  9. import android.graphics.Bitmap;
  10. import android.graphics.BitmapFactory;
  11. import android.net.Uri;
  12. import android.os.Bundle;
  13. import android.provider.ContactsContract;
  14. import android.provider.ContactsContract.CommonDataKinds.Phone;
  15. import android.provider.ContactsContract.CommonDataKinds.Photo;
  16. import android.text.TextUtils;
  17. import android.view.LayoutInflater;
  18. import android.view.View;
  19. import android.view.ViewGroup;
  20. import android.widget.AdapterView;
  21. import android.widget.BaseAdapter;
  22. import android.widget.ImageView;
  23. import android.widget.ListView;
  24. import android.widget.TextView;
  25. import android.widget.AdapterView.OnItemClickListener;
  26. public class ContactsActivity extends ListActivity {
  27. Context mContext = null;
  28. /**获取库Phon表字段**/
  29. private static final String[] PHONES_PROJECTION = new String[] {
  30. Phone.DISPLAY_NAME, Phone.NUMBER, Photo.PHOTO_ID,Phone.CONTACT_ID };
  31. /**联系人显示名称**/
  32. private static final int PHONES_DISPLAY_NAME_INDEX = 0;
  33. /**电话号码**/
  34. private static final int PHONES_NUMBER_INDEX = 1;
  35. /**头像ID**/
  36. private static final int PHONES_PHOTO_ID_INDEX = 2;
  37. /**联系人的ID**/
  38. private static final int PHONES_CONTACT_ID_INDEX = 3;
  39. /**联系人名称**/
  40. private ArrayList<String> mContactsName = new ArrayList<String>();
  41. /**联系人头像**/
  42. private ArrayList<String> mContactsNumber = new ArrayList<String>();
  43. /**联系人头像**/
  44. private ArrayList<Bitmap> mContactsPhonto = new ArrayList<Bitmap>();
  45. ListView mListView = null;
  46. MyListAdapter myAdapter = null;
  47. @Override
  48. public void onCreate(Bundle savedInstanceState) {
  49. mContext = this;
  50. mListView = this.getListView();
  51. /**得到手机通讯录联系人信息**/
  52. getPhoneContacts();
  53. myAdapter = new MyListAdapter(this);
  54. setListAdapter(myAdapter);
  55. mListView.setOnItemClickListener(new OnItemClickListener() {
  56. @Override
  57. public void onItemClick(AdapterView<?> adapterView, View view,
  58. int position, long id) {
  59. //调用系统方法拨打电话
  60. Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri
  61. .parse("tel:" + mContactsNumber.get(position)));
  62. startActivity(dialIntent);
  63. }
  64. });
  65. super.onCreate(savedInstanceState);
  66. }
  67. /**得到手机通讯录联系人信息**/
  68. private void getPhoneContacts() {
  69. ContentResolver resolver = mContext.getContentResolver();
  70. // 获取手机联系人
  71. Cursor phoneCursor = resolver.query(Phone.CONTENT_URI,PHONES_PROJECTION, null, null, null);
  72. if (phoneCursor != null) {
  73. while (phoneCursor.moveToNext()) {
  74. //得到手机号码
  75. String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);
  76. //当手机号码为空的或者为空字段 跳过当前循环
  77. if (TextUtils.isEmpty(phoneNumber))
  78. continue;
  79. //得到联系人名称
  80. String contactName = phoneCursor.getString(PHONES_DISPLAY_NAME_INDEX);
  81. //得到联系人ID
  82. Long contactid = phoneCursor.getLong(PHONES_CONTACT_ID_INDEX);
  83. //得到联系人头像ID
  84. Long photoid = phoneCursor.getLong(PHONES_PHOTO_ID_INDEX);
  85. //得到联系人头像Bitamp
  86. Bitmap contactPhoto = null;
  87. //photoid 大于0 表示联系人有头像 如果没有给此人设置头像则给他一个默认的
  88. if(photoid > 0 ) {
  89. Uri uri =ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI,contactid);
  90. InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(resolver, uri);
  91. contactPhoto = BitmapFactory.decodeStream(input);
  92. }else {
  93. contactPhoto = BitmapFactory.decodeResource(getResources(), R.drawable.contact_photo);
  94. }
  95. mContactsName.add(contactName);
  96. mContactsNumber.add(phoneNumber);
  97. mContactsPhonto.add(contactPhoto);
  98. }
  99. phoneCursor.close();
  100. }
  101. }
  102. /**得到手机SIM卡联系人人信息**/
  103. private void getSIMContacts() {
  104. ContentResolver resolver = mContext.getContentResolver();
  105. // 获取Sims卡联系人
  106. Uri uri = Uri.parse("content://icc/adn");
  107. Cursor phoneCursor = resolver.query(uri, PHONES_PROJECTION, null, null,
  108. null);
  109. if (phoneCursor != null) {
  110. while (phoneCursor.moveToNext()) {
  111. // 得到手机号码
  112. String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);
  113. // 当手机号码为空的或者为空字段 跳过当前循环
  114. if (TextUtils.isEmpty(phoneNumber))
  115. continue;
  116. // 得到联系人名称
  117. String contactName = phoneCursor
  118. .getString(PHONES_DISPLAY_NAME_INDEX);
  119. //Sim卡中没有联系人头像
  120. mContactsName.add(contactName);
  121. mContactsNumber.add(phoneNumber);
  122. }
  123. phoneCursor.close();
  124. }
  125. }
  126. class MyListAdapter extends BaseAdapter {
  127. public MyListAdapter(Context context) {
  128. mContext = context;
  129. }
  130. public int getCount() {
  131. //设置绘制数量
  132. return mContactsName.size();
  133. }
  134. @Override
  135. public boolean areAllItemsEnabled() {
  136. return false;
  137. }
  138. public Object getItem(int position) {
  139. return position;
  140. }
  141. public long getItemId(int position) {
  142. return position;
  143. }
  144. public View getView(int position, View convertView, ViewGroup parent) {
  145. ImageView iamge = null;
  146. TextView title = null;
  147. TextView text = null;
  148. if (convertView == null) {
  149. convertView = LayoutInflater.from(mContext).inflate(
  150. R.layout.colorlist, null);
  151. iamge = (ImageView) convertView.findViewById(R.id.color_image);
  152. title = (TextView) convertView.findViewById(R.id.color_title);
  153. text = (TextView) convertView.findViewById(R.id.color_text);
  154. }
  155. //绘制联系人名称
  156. title.setText(mContactsName.get(position));
  157. //绘制联系人号码
  158. text.setText(mContactsNumber.get(position));
  159. //绘制联系人头像
  160. iamge.setImageBitmap(mContactsPhonto.get(position));
  161. return convertView;
  162. }
  163. }
  164. }

列表的布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent" android:layout_height="wrap_content">
  4. <ImageView android:id="@+id/color_image"
  5. android:layout_width="40dip" android:layout_height="40dip" />
  6. <TextView android:id="@+id/color_title"
  7. android:layout_width="fill_parent" android:layout_height="wrap_content"
  8. android:layout_toRightOf="@+id/color_image"
  9. android:layout_alignParentBottom="true"
  10. android:layout_alignParentRight="true" android:singleLine="true"
  11. android:ellipsize="marquee"
  12. android:textSize="15dip"  />
  13. <TextView android:id="@+id/color_text"
  14. android:layout_width="fill_parent" android:layout_height="wrap_content"
  15. android:layout_toRightOf="@+id/color_image"
  16. android:layout_below="@+id/color_title"
  17. android:layout_alignParentBottom="true"
  18. android:layout_alignParentRight="true"
  19. android:singleLine="true"
  20. android:ellipsize="marquee"
  21. android:textSize="20dip" />
  22. </RelativeLayout>

Android软件开发之获取通讯录联系人信息的更多相关文章

  1. android利用ContentResolver访问者获取手机联系人信息

    转载自:http://www.jb51.net/article/106379.htm 首先需要在AndroidManifest.xml文件中添加权限: <uses-permission andr ...

  2. android软件开发之获取本地音乐属性

    歌曲的名称 :MediaStore.Audio.Media.TITLString tilte = cursor.getString(cursor.getColumnIndexOrThrow(Media ...

  3. Expo大作战(三十九)--expo sdk api之 DocumentPicker,Contacts(获取手机联系人信息),Branch

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  4. IOS 获取通讯录中信息

    获取通讯录中信息 一. 我们设置一个ABAddressBookRef类型的属性addressBook. 二. 要获得通讯录中的信息,我们需要获取访问通讯录的权限. 在运行下面的获取权限的方法的时候,系 ...

  5. Android自动化测试中AccessibilityService获取控件信息(1)

    Android自动化测试中AccessibilityService获取控件信息(1) 分类: android自动化测试2014-03-24 15:31 3455人阅读 评论(16) 收藏 举报 and ...

  6. 转: Android 软件开发之如何使用Eclipse Debug调试程序详解(七)

    转自: http://www.uml.org.cn/mobiledev/201110092.asp Android 软件开发之如何使用Eclipse Debug调试程序详解(七)   发布于2011- ...

  7. 向Android模拟器中批量导入通讯录联系人

    使用adb命令向Android模拟器中批量导入通讯录联系人的方法: 使用adb提供的命令, 可以非常方便地从PC中将通讯录批量导入android模拟器中. 首先要先准备好固定格式的vcf文件, 该文件 ...

  8. Android自动化测试中AccessibilityService获取控件信息(2)-三种方式对比

    Android自动化测试中AccessibilityService获取控件信息(2)-三种方式对比   上一篇文章: Android自动化测试中AccessibilityService获取控件信息(1 ...

  9. Android 获取手机联系人信息

    //获取联系人 Uri rawContacts = Uri.parse("content://com.android.contacts/raw_contacts"); Conten ...

随机推荐

  1. Emit学习(1)-Emit概览

    一.Emit概述 Emit,可以称为发出或者产生.在Framework中,与Emit相关的类基本都存在于System.Reflection.Emit命名空间下.可见Emit是作为反射的一个元素存在的. ...

  2. 学习笔记_过滤器详细_2(过滤器JavaWeb三大组件之一)

    过滤器详细 5 四种拦截方式 我们来做个测试,写一个过滤器,指定过滤的资源为b.jsp,然后我们在浏览器中直接访问b.jsp,你会发现过滤器执行了! 但是,当我们在a.jsp中request.getR ...

  3. 学习笔记_Java_day13_JSTL_自定义标签库(9)

    自定义标签 1 自定义标签概述 1.1 自定义标签的步骤 其实我们在JSP页面中使用标签就等于调用某个对象的某个方法一样,例如:<c:if test=””>,这就是在调用对象的方法一样.自 ...

  4. 几种JavaScript富应用MVC MVVM框架

    Ember.js.Backbone.js.Knockout.js.Spine.js.Batman.js , Angular.js 前端中的MVVM设计模式让UI与数据模型可以很轻松的相互更新,这意味着 ...

  5. JS获取日期和时间

    //获取日期和时间 function showDate(){ var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFul ...

  6. jQuery 源码分析2: jQuery.fn.init

    //jQuery.fn.intit 中使用到的外部变量: // 判断是否为HTML标签或#id rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w ...

  7. RPC实现原理(HSF、dubbo) 从头开始(一)

    前言 阔别了很久博客园,虽然看了以前写的很多东西感觉好幼稚,但是还是觉得应该把一些自己觉得有用的东西和大家分享.废话不多说,现在开始进入正题. 之前的六年工作经验,呆过了一些大公司,每个在大公司呆过的 ...

  8. Quartz2.2.1操作手册

    一.初识quartz JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1") ...

  9. 06_关于SqlSession

    一.SqlSession适用范围 (1).SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory 将Sql ...

  10. (CodeForces )540B School Marks 贪心 (中位数)

    Little Vova studies programming to p. Vova is very smart and he can write every test for any mark, b ...