点石互动

导航

 

本篇开始讲如何从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.         
  17.         List<HashMap<String, String>> items = fillMaps();        
  18.         SimpleAdapter adapter = new SimpleAdapter(
  19.                         this,items,R.layout.list_item,
  20.                         new String[]{"name","key"}, 
  21.                         new int[]{R.id.item,R.id.item2});
  22.         this.setListAdapter(adapter);
  23.     }
  24.         private List<HashMap<String, String>> fillMaps() {
  25.                 List<HashMap<String, String>> items = new ArrayList<HashMap<String, String>>();
  26.                 Cursor cur = null;
  27.                 try {
  28.                         // Query using ContentResolver.query or Activity.managedQuery
  29.                         cur = getContentResolver().query(
  30.                                         ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
  31.                         if (cur.moveToFirst()) {
  32.                                 int idColumn = cur.getColumnIndex(
  33.                                                 ContactsContract.Contacts._ID);
  34.                         int displayNameColumn = cur.getColumnIndex(
  35.                                         ContactsContract.Contacts.DISPLAY_NAME);
  36.                                 // Iterate all users
  37.                         do {
  38.                                         String contactId;
  39.                                         String displayName;
  40.                                         String phoneNumber = "";
  41.                                         // Get the field values
  42.                                         contactId = cur.getString(idColumn);
  43.                                         displayName = cur.getString(displayNameColumn);
  44.                                         // Get number of user's phoneNumbers
  45.                                         int numberCount = cur.getInt(cur.getColumnIndex(
  46.                                                         ContactsContract.Contacts.HAS_PHONE_NUMBER));
  47.                                         if (numberCount>0) {
  48.                                                 Cursor phones = getContentResolver().query(
  49.                                                                 ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
  50.                                                                 null,
  51.                                                                 ContactsContract.CommonDataKinds.Phone.CONTACT_ID 
  52.                                                                 + " = " + contactId 
  53.                                                                 /*+ " and " + ContactsContract.CommonDataKinds.Phone.TYPE 
  54.                                                                 + "=" + ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE*/,
  55.                                                                 null, null);
  56.                                                 if (phones.moveToFirst()) {
  57.                                                         int numberColumn = phones.getColumnIndex(
  58.                                                                         ContactsContract.CommonDataKinds.Phone.NUMBER);
  59.                                                         // Iterate all numbers
  60.                                                         do {
  61.                                                                 phoneNumber += phones.getString(numberColumn) + ",";
  62.                                                         } while (phones.moveToNext());
  63.                                                 } 
  64.                                         }
  65.                                         // Add values to items
  66.                                         HashMap<String, String> i = new HashMap<String, String>();
  67.                                         i.put("name", displayName);
  68.                                         i.put("key", phoneNumber);
  69.                                         items.add(i);
  70.                                 } while (cur.moveToNext());
  71.                         } else {
  72.                                 HashMap<String, String> i = new HashMap<String, String>();
  73.                                 i.put("name", "Your Phone");
  74.                                 i.put("key", "Have No Contacts.");
  75.                                 items.add(i);
  76.                         }
  77.                 } finally {
  78.                         if (cur != null)
  79.                                 cur.close();
  80.                 }
  81.                 return items;
  82.         }
  83. }
复制代码


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);
复制代码

 

posted on 2013-12-23 14:28  点石互动  阅读(496)  评论(0编辑  收藏  举报