本篇开始讲如何从Android中得到本机联系人的信息。
由于Android较快的版本升级,部分API已经发生了变化。本篇探究的通过ContentProvider机制获取联系人的API从Android2.0开始做了很大调整,原来的android.provider.Contacts类及其下相关类由android.provider.ContactsContract代替。原类体系标记为Deprecated(废弃),因为兼容的原因目前还存在,但不保证以后的更新版本中完全丢弃。

所以本文先从Android2.1以上平台的联系人读取开始说起,下面给出代码在Android2.1/2.2中运行的效果图,

<ignore_js_op>

首先,创建类ViewContacts继承ListActivity,并设为为应用的开始Activity。
ViewContacts.java 代码:

  1. package jtapp.contacts;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import android.app.ListActivity;
  6. import android.database.Cursor;
  7. import android.os.Bundle;
  8. import android.provider.ContactsContract;
  9. import android.widget.SimpleAdapter;
  10. public class ViewContacts extends ListActivity {
  11. /** Called when the activity is first created. */
  12. @Override
  13. public void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.main);
  16. List<HashMap<String, String>> items = fillMaps();
  17. SimpleAdapter adapter = new SimpleAdapter(
  18. this,items,R.layout.list_item,
  19. new String[]{"name","key"},
  20. new int[]{R.id.item,R.id.item2});
  21. this.setListAdapter(adapter);
  22. }
  23. private List<HashMap<String, String>> fillMaps() {
  24. List<HashMap<String, String>> items = new ArrayList<HashMap<String, String>>();
  25. Cursor cur = null;
  26. try {
  27. // Query using ContentResolver.query or Activity.managedQuery
  28. cur = getContentResolver().query(
  29. ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
  30. if (cur.moveToFirst()) {
  31. int idColumn = cur.getColumnIndex(
  32. ContactsContract.Contacts._ID);
  33. int displayNameColumn = cur.getColumnIndex(
  34. ContactsContract.Contacts.DISPLAY_NAME);
  35. // Iterate all users
  36. do {
  37. String contactId;
  38. String displayName;
  39. String phoneNumber = "";
  40. // Get the field values
  41. contactId = cur.getString(idColumn);
  42. displayName = cur.getString(displayNameColumn);
  43. // Get number of user's phoneNumbers
  44. int numberCount = cur.getInt(cur.getColumnIndex(
  45. ContactsContract.Contacts.HAS_PHONE_NUMBER));
  46. if (numberCount>0) {
  47. Cursor phones = getContentResolver().query(
  48. ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
  49. null,
  50. ContactsContract.CommonDataKinds.Phone.CONTACT_ID
  51. + " = " + contactId
  52. /*+ " and " + ContactsContract.CommonDataKinds.Phone.TYPE
  53. + "=" + ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE*/,
  54. null, null);
  55. if (phones.moveToFirst()) {
  56. int numberColumn = phones.getColumnIndex(
  57. ContactsContract.CommonDataKinds.Phone.NUMBER);
  58. // Iterate all numbers
  59. do {
  60. phoneNumber += phones.getString(numberColumn) + ",";
  61. } while (phones.moveToNext());
  62. }
  63. }
  64. // Add values to items
  65. HashMap<String, String> i = new HashMap<String, String>();
  66. i.put("name", displayName);
  67. i.put("key", phoneNumber);
  68. items.add(i);
  69. } while (cur.moveToNext());
  70. } else {
  71. HashMap<String, String> i = new HashMap<String, String>();
  72. i.put("name", "Your Phone");
  73. i.put("key", "Have No Contacts.");
  74. items.add(i);
  75. }
  76. } finally {
  77. if (cur != null)
  78. cur.close();
  79. }
  80. return items;
  81. }
  82. }

复制代码

main.xml 代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <TextView
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:text="show your phone's contacts:"
  11. />
  12. <ListView android:id="@id/android:list"
  13. android:layout_width="fill_parent"
  14. android:layout_height="0dip"
  15. android:layout_weight="1"
  16. android:drawSelectorOnTop="false"
  17. />
  18. </LinearLayout>

复制代码

list_item.xml 代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <TableRow android:id="@+id/TableRow01"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content">
  10. <TextView android:id="@+id/item"
  11. xmlns:android="http://schemas.android.com/apk/res/android"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. android:textSize="20px" />
  15. <TextView android:text=": "
  16. xmlns:android="http://schemas.android.com/apk/res/android"
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"
  19. android:textSize="20px" />
  20. <TextView android:id="@+id/item2"
  21. xmlns:android="http://schemas.android.com/apk/res/android"
  22. android:layout_width="wrap_content"
  23. android:layout_height="wrap_content"
  24. android:textSize="20px" />
  25. </TableRow>
  26. </LinearLayout>

复制代码

AndroidManifest.xml 增加uses权限READ_CONTACTS 代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="jtapp.contacts" android:versionCode="1" android:versionName="1.0">
  4. <application android:icon="@drawable/icon" android:label="@string/app_name">
  5. <activity android:name=".ViewContacts" android:label="@string/app_name">
  6. <intent-filter>
  7. <action android:name="android.intent.action.MAIN" />
  8. <category android:name="android.intent.category.LAUNCHER" />
  9. </intent-filter>
  10. </activity>
  11. </application>
  12. <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
  13. </manifest>

复制代码

以上文件编写好后,应用就能够在Android2.1模拟器上正确运行了。

那么该app如果在android1.6上运行,会怎么样呢?1.6上并没有ContactsContract类体系,所以就会报错了。需要注意,ContactContract类是在API Level 5增加的,之前的Android版本并不支持。
在Android 1.6 (API Level 4)上,获取联系人的方法将fillMaps()实现为如下:

  1. private List<HashMap<String, String>> fillMaps() {
  2. List<HashMap<String, String>> items = new ArrayList<HashMap<String, String>>();
  3. Cursor cur = null;
  4. try {
  5. // Form an array specifying which columns to return.
  6. String[] projection = new String[] {
  7. People._ID,
  8. People.NAME,
  9. People.NUMBER
  10. };
  11. // query using ContentResolver.query or Activity.managedQuery
  12. cur = getContentResolver().query(
  13. People.CONTENT_URI,projection, null,null, null);
  14. if (cur.moveToFirst()) {
  15. String name;
  16. String phoneNumber;
  17. int nameColumn = cur.getColumnIndex(People.NAME);
  18. int phoneColumn = cur.getColumnIndex(People.NUMBER);
  19. do {
  20. // Get the field values
  21. name = cur.getString(nameColumn);
  22. phoneNumber = cur.getString(phoneColumn);
  23. // Do something with the values.
  24. HashMap<String, String> i = new HashMap<String, String>();
  25. i.put("name", name);
  26. i.put("key", phoneNumber);
  27. items.add(i);
  28. } while (cur.moveToNext());
  29. } else {
  30. HashMap<String, String> i = new HashMap<String, String>();
  31. i.put("name", "Your Phone");
  32. i.put("key", "Have No Contacts.");
  33. items.add(i);
  34. }
  35. } finally {
  36. if (cur != null)
  37. cur.close();
  38. }
  39. return items;
  40. }

复制代码

那么就能在1.6上运行了,效果截图如下:

<ignore_js_op>

联系人API,在Android2.0后产生变化,如果使用如上1.6版本的调用,你会发现在2.1下姓名有了,但电话号码不显示了。仔细观察可以发现,People.CONTENT_URI等调用在2.0以上的sdk中都标记了Deprecated。这一点,对于编写希望能够同时兼容1.6与2.x版本的应用造成了困难。那么,如果应用涉及到联系人的读取,非得要编写多个版本的apk了吗? 其实,我们可以使用判断当前系统API Level的方法编写两套代码备用,这个就留给大家去实践了。

获得系统API level方法:

  1. int version = android.provider.Settings.System.getInt(context
  2. .getContentResolver(),
  3. android.provider.Settings.System.SYS_PROP_SETTING_VERSION,
  4. 3);

复制代码

读取手机中的联系人信息(android.provider.ContactsContract)的更多相关文章

  1. 在手机中预置联系人/Service Number

    代码分为两部分: Part One 将预置的联系人插入到数据库中: Part Two 保证预置联系人仅仅读,无法被编辑删除(在三个地方屏蔽对预置联系人进行编辑处理:联系人详情界面.联系人多选界面.新建 ...

  2. Android API之android.provider.ContactsContract

    android.provider.ContactsContract ContactsContract是联系人provider和app的contract.定义了已支持的URL和column.取代了之前的 ...

  3. Android API之android.provider.ContactsContract.Contacts

    android.provider.ContactsContract.Contacts 对应contacts数据表.RawContacts的一个聚合(aggregate)代表同一个人.每个人在数据表co ...

  4. Android API之android.provider.ContactsContract.RawContacts

    android.provider.ContactsContract.RawContacts Constants for the raw contacts table, which contains o ...

  5. Android API之android.provider.ContactsContract.Data

    android.provider.ContactsContract.Data Constants for the data table, which contains data points tied ...

  6. Android 手机卫士--获取联系人信息并显示与回显

    前面的文章已经实现相关的布局,本文接着进行相关的功能实现 本文地址:http://www.cnblogs.com/wuyudong/p/5951794.html,转载请注明出处. 读取系统联系人 当点 ...

  7. 读取iPhone中的通讯录信息

    添加AddressBook这个包:然后#import <AddressBook/AddressBook.h> //取得本地通信录名柄 ABAddressBookRef addressBoo ...

  8. 【转】Revit二次开发——读取cad中的文字信息

    Revit读取cad的文字信息需要借助Teigha的开源dll,在程序中添加下图中红色框的dll文件的引用,其他的dll文件全部放在同一个文件夹中即可,运行的时候,会自动把这些dll文件全部复制到bi ...

  9. IOS 获取系统通讯录中的联系人信息

    - (IBAction)getAllContactFromSystem { ABAddressBookRef ab = ABAddressBookCreateWithOptions(NULL, NUL ...

随机推荐

  1. x86架构:保护模式下加载并运行用户程序

    本章的代码分3个模块: MBR 引导:加载内核core程序 core:包含内核代码段(从磁盘加载用户程序并重定位).内核数据段(存放api名称.临时缓冲.字符串等).API段(供用户程序调用) 用户程 ...

  2. 当asp.net core偶遇docker二(打造个人docker镜像)

    网络上的docker容器总有一些不尽人意的感觉,这个时候,就需要自己diy一个自用的. 比如我们想在163的mysql 5.7内diy一下,结果发现,这个不带vim,我想改造一个自用的mysql镜像, ...

  3. Android Studio局部管理器

    1.LinearLayout(线性布局) 该布局将其中的View子控件按照水平或者垂直方向排列.但是需要注意不管是水平还是竖直,对应的每一行或列都只能放一个控件. 线性布局两种排法: 从左到右:and ...

  4. MySQL--->高级对象

    本章目标: 掌握MySQL视图 掌握MySQL存储过程 掌握MySQL触发器 1.视图: 视图就是一条select语句执行后返回的结果集. 使用场景:权限控制的时候不希望用户访问表中某些敏感信息的列 ...

  5. C语言学习笔记之杂七杂八容易忽略的点(以后看到一直补充)

    1.变量名可以由 数字 字母 下划线 组成.数字不能用在开头 2.取余%:  只能是整数取余 3.sizeof是个关键字  不是函数 4.printf("%10d\n",a); 共 ...

  6. System.out.println()相关源码

    System.out.println是一个Java语句,一般情况下是将传递的参数,打印到控制台. System:是 java.lang包中的一个final类.根据javadoc,“java.lang. ...

  7. 我能想到的最浪漫的Java网络教程之Socket,三步到位!!!

    简说 如果要使用Java中的TCP/IP通过网络连接到服务器,则需要创建一个java.net.Socket对象以连接到服务器.如果使用JavaNIO,则还可以在JavaNIO中创建SocketChan ...

  8. 2020-08-08:有一批气象观测站,现需要获取这些站点的观测数据,并存储到 Hive 中。但是气象局只提供了 api 查询,每次只能查询单个观测点。那么如果能够方便快速地获取到所有的观测点的数据?

    福哥答案2020-08-08: 参考答案:A.通过shell 或python 等调用api,结果先暂存本地,最后将本地文件上传到 Hive 中.B.通过 datax 的 httpReader 和 hd ...

  9. 题解 P1407

    建图方式:旧关系女人连男人,现关系男人连女人(当然,反过来也可以) 原因可以这样考虑: 如果一个男的把女的绿了,那么这个女人就会去找一个她曾经交往过的男人,也就是在这种情况下,某种"影响&q ...

  10. 虚拟化技术之kvm基础

    一.KVM简介 KVM的全称是kernel base virtual machine(基于内核的虚拟机)是一个开源的系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中. ...