Android联系人数据库全解析(1)

来源:互联网 发布:linux io负载高的排查 编辑:程序博客网 时间:2024/05/19 12:39
Android 联系人说明

学习应用Android联系人数据库,在掌握Android SQLite的基础上,还要熟练应用数据指针(cursor)。我们可以查看有关Android SQLite 和 Cursor的文章来获取更多的内容。谷歌(Google)更换了Android 1.x和2.x的联系人数控库版本。本文分为三节,第一节将介绍Android 2.0的联系人。第二节将介绍怎么处理Android 1.6以及以前版本的联系人。而第三节,将会把这两个版本结合起来。创建一个类来抽象各个版本的操作类,并创建一套类来对联系人记录进行管理。

在Eclipse中新建一个项目,名为TestContacts。创建Android 2.0支持。

Android 2.0联系人API

查询许可

在查询联系人数据之前。我们必须得到查询许可。方法就是在根目录的AndroidManifest.xml文件中配置如下权限:<uses-permission  android:name="android.permission.READ_CONTACTS" />

查询联系人数据库

检索联系人详细信息


为了规范化,基本的联系人信息放在联系人表里,而其他的详细信息则被储存在独立的数据表中。在Android 2.0中,要查询基本的联系人记录,URI被指定在People.CONTENT_URI变量中。  ContactsContract.Contacts.CONTENT_URI. 
Java代码  收藏代码
[html] view plaincopy
  1. package higherpass.TestContacts;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.ContentResolver;  
  5. import android.database.Cursor;  
  6. import android.os.Bundle;  
  7. import android.provider.ContactsContract;  
  8.   
  9. public class TestContacts extends Activity {  
  10.     /** Called when the activity is first created. */  
  11.     @Override  
  12.     public void onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.         setContentView(R.layout.main);  
  15.         ContentResolver cr = getContentResolver();  
  16.         Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,  
  17.                 null, null, null, null);  
  18.         if (cur.getCount() > 0) {  
  19.         while (cur.moveToNext()) {  
  20.             String id = cur.getString(  
  21.                         cur.getColumnIndex(ContactsContract.Contacts._ID));  
  22.         String name = cur.getString(  
  23.                         cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));  
  24.         if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {  
  25.             //Query phone here.  Covered next  
  26.             }  
  27.             }  
  28.     }  
  29.     }  
  30. }  


这个应用像其他应用一样。首先创建一个ContentResolver实例 的引用cr。然后用这个实例去查询数据库。返回一个包含联系人列表的Cursor。这个查询URI是ContactsContract.Contacts.CONTENT_URI。然后检查是否包含数据,如果有则循环遍历。记录ID存储在id变量中,它在后面将被用做条件参数。联系人显示名称责备存储在name字符串中。想知道更多cursor的用法,请参考Android Cursor教程

手机号码
手机号码存储在自己的表中,需要单独查询。查询这个表要用到ContactsContract.CommonDataKinds.Phone.CONTENT_URI,用一个WHERE 条件从句来获得指定联系人的号码。
Java代码  收藏代码
[html] view plaincopy
  1.      if (Integer.parseInt(cur.getString(  
  2.             cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {  
  3.          Cursor pCur = cr.query(  
  4. ContactsContract.CommonDataKinds.Phone.CONTENT_URI,   
  5. null,   
  6. ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",   
  7. new String[]{id}, null);  
  8.    while (pCur.moveToNext()) {  
  9. // Do something with phones  
  10.    }   
  11.    pCur.close();  


这里演示了一个对联系人数据的间接查询。手机号码的URI存储在ContactsContract.CommonDataKinds.Phone.CONTENT_URI中。联系人ID存储在ContactsContract.CommonDataKinds.Phone.CONTACT_ID字段中。WHERE从句是限制条件。用来限制查询结果。

电子邮箱地址

查询电子邮箱地址,跟查询手机号码相似。只是URI不同:
Java代码  收藏代码
[html] view plaincopy
  1. Cursor emailCur = cr.query(   
  2.     ContactsContract.CommonDataKinds.Email.CONTENT_URI,   
  3.     null,  
  4.     ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",   
  5.     new String[]{id}, null);   
  6. while (emailCur.moveToNext()) {   
  7.     // This would allow you get several email addresses  
  8.            // if the email addresses were stored in an array  
  9.     String email = emailCur.getString(  
  10.                      emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));  
  11.         String emailType = emailCur.getString(  
  12.                      emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));   
  13.     }   
  14.     emailCur.close();  


想手机号码一样,邮箱数据表也是在ContactsContract.CommonDataKinds中。查询URI是ContactsContract.CommonDataKinds.Email.CONTENT_URI 。查询的时候联系人的
id要跟ContactsContract.CommonDataKinds.Email.CONTACT_ID对应。因为邮箱地址可以为多个,所以要循环遍历查询结果。

备注

自定义备注可以被加入到联系人数据中,ContactsContract.CommonDataKinds.Email.CONTACT_ID这些被存储在独立的表中,但与联系人的ID建立了外键关联。
Java代码  收藏代码

[html] view plaincopy
  1.       String noteWhere = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";   
  2.       String[] noteWhereParams = new String[]{id,   
  3.     ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE};   
  4.               Cursor noteCur = cr.query(ContactsContract.Data.CONTENT_URI, null, noteWhere, noteWhereParams, null);   
  5. if (noteCur.moveToFirst()) {   
  6.     String note = noteCur.getString(noteCur.getColumnIndex(ContactsContract.CommonDataKinds.Note.NOTE));  
  7. }   
  8. noteCur.close();  

备注被存储在Android联系人的通用data表中。当查询特定的数据时,WHERE从句需要两个条件从句。首先是标准ID,然后是MIMETYPE 。Android SDK包含了一系列自动生成的变量来维护这个字段。用ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE来限定备注记录。data表URI在ContactsContract.Data.CONTENT_UR中。最后备注的字段名保存在ContactsContract.CommonDataKinds.Note.NOTE

邮政地址

Android可以为联系人存储多个邮政地址,地址跟备注一样也是被保存在data表中,URI是ContactsContract.Data.CONTENT_URI与备注类似。我们需要一个MIMETYPE 作为WHERE条件从句。在2.0中,地址数据被分为多个区域,包含了地址的不同部分:(邮箱,街道,城市,地区,邮政编码)在Android SDK的早期版本中,这只是一个不规则的字符。
Java代码  收藏代码

[html] view plaincopy
  1. String addrWhere = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";   
  2. String[] addrWhereParams = new String[]{id,   
  3.     ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE};   
  4. Cursor addrCur = cr.query(ContactsContract.Data.CONTENT_URI,   
  5.                null, where, whereParameters, null);   
  6. while(addrCur.moveToNext()) {  
  7.     String poBox = addrCur.getString(  
  8.                     addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POBOX));  
  9.         String street = addrCur.getString(  
  10.                     addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));  
  11.         String city = addrCur.getString(  
  12.                     addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));  
  13.         String state = addrCur.getString(  
  14.                     addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));  
  15.         String postalCode = addrCur.getString(  
  16.                     addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE));  
  17.         String country = addrCur.getString(  
  18.                     addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY));  
  19.         String type = addrCur.getString(  
  20.                     addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.TYPE));  
  21.     }   
  22.     addrCur.close();  

这段代码与之前的例子类似。请注意该字段名称都保存在 ContactsContract.CommonDataKinds.StructuredPostal.

即时消息
即时消息的查询就像备注和地址。IM的相关数据里的主要字段名称保存在
ContactsContract.CommonDataKinds.Im
Java代码  收藏代码
[html] view plaincopy
  1. String imWhere = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";   
  2. String[] imWhereParams = new String[]{id,   
  3.     ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE};   
  4. Cursor imCur = cr.query(ContactsContract.Data.CONTENT_URI,   
  5.           null, imWhere, imWhereParams, null);   
  6. if (imCur.moveToFirst()) {   
  7.     String imName = imCur.getString(  
  8.                imCur.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA));  
  9.     String imType;  
  10.     imType = imCur.getString(  
  11.                imCur.getColumnIndex(ContactsContract.CommonDataKinds.Im.TYPE));  
  12. }   
  13. imCur.close();  


组织机构

最后要讲述的联系人记录是机构数据。Android 联系人记录包含的信息有雇主,专业,社会关系,以及角色与职位,这些资料记录都保存在ContactsContract.Data.CONTENT_URI主要的机构数据里的主要字段名称则保存在ContactsContract.CommonDataKinds.Organization

Java代码  收藏代码
[html] view plaincopy
  1. String orgWhere = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";   
  2.     String[] orgWhereParams = new String[]{id,   
  3.         ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE};   
  4.     Cursor orgCur = cr.query(ContactsContract.Data.CONTENT_URI,   
  5.                 null, orgWhere, orgWhereParams, null);  
  6.     if (orgCur.moveToFirst()) {   
  7.         String orgName = orgCur.getString(orgCur.getColumnIndex(ContactsContract.CommonDataKinds.Organization.DATA));  
  8.         String title = orgCur.getString(orgCur.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TITLE));  
  9.     }   
  10.     orgCur.close();