您的位置:首页 > 移动开发 > Android开发

Android通讯录查询篇--ContactsContract.Data 二(续)

2011-07-25 16:10 411 查看
这次主要要做的就是根据姓名来查找电话,并且加强对通讯录的理解。

以前做一些用到数据库的东西的时候,可能光看代码也是不好联系起各个数据之间的关系,所以我先想到的还是数据库。幸运的是,它还真是一个数据库。

Android里面内置的是SQLite的数据库,虽然对数据库不怎么了解,但关系型数据库,基本操作也就那些,而且基本都一样,所以就直接用呗。

用命令行下的adbshell进入Android的模拟器,进入data/data目录下面,这里面就是安装的一些应用程序。找啊找,里面有一个com.android.providers.contacts,怎么看都是一个通讯录相关的程序,进入这个目录下,里面有一个databases,就它了,再进去就可以看到有个contacts2.db的文件。

用sqlite3打开这个数据库文件。查看里面的表。里面表很多,不过看两遍后发现表的名字很熟悉,像什么data,raw_contacts,contacts,minetypes等,前面几个都是我们上次说的那几个所谓的数据模型,它们还真是数据库。



查询一下data表里面的所有信息,可以发现里面的信息联系起来就都是我们通讯录里面的名片。虽然不是一条显示全部,但每个名字每个电话,每个E-mail都有,而且都是分开显示的。现在对于这个应该就有点感觉了。



再看一下表的结构,用”.schema”命令后会看到,类似如下的信息:

.schemadata

CREATETABLEdata(

_idINTEGERPRIMARYKEYAUTOINCREMENT,

package_idINTEGERREFERENCESpackage(_id),

mimetype_idINTEGERREFERENCESmimetype(_id)NOTNULL,

raw_contact_idINTEGERREFERENCESraw_contacts(_id)NOTNULL,

is_primaryINTEGERNOTNULLDEFAULT0,

is_super_primaryINTEGERNOTNULLDEFAULT0,

data_versionINTEGERNOTNULLDEFAULT0,

data1TEXT,

data2TEXT,

data3TEXT,

data4TEXT,

data5TEXT,

data6TEXT,

data7TEXT,

data8TEXT,

data9TEXT,

data10TEXT,

data11TEXT,

data12TEXT,

data13TEXT,

data14TEXT,

data15TEXT,

data_sync1TEXT,

data_sync2TEXT,

data_sync3TEXT,

data_sync4TEXT);

下面还有点索引和触发器的信息就不看了,结合查询的数据看一下。其中“_id”就是表的一个自增id字段。第二个package_id暂时没用到,数据里面全是空。第三个字段minetype_id应该就是MIMETYPE了(其实还是有点不一样的)。后的raw_contact_id就是名片的ID。再看后的data1,data2等字段,每条数据中的这几项都不大相同,准确的说,minetype_id字段不同的数据data1,data2等字段的数据就不同。

现在应该就有一个概念了,以前说的MIMETYPE的值确定Data.DATA1等的值的类型的意思就是在data数据库中通过mimetype_id的值就可以确定data1,data2等字段的真正意义。也就是说在data数据库中通过minetype_id的值可以确定那一条数据到底是存储的姓名,还是电话,还是E-mail或者其它。

这样一来,如果我们要查询某个特定的数据的时候就可以直接查询data表里面的data1,data2这类字段的值,而唯一的必要条件就是在where条件语句里面将minetype_id赋为对应的值。这样就有了一个统一的数据访问方法。而且可以通过这个表查到所以想要的数据。

所以如果想要通过姓名查找一个人的电话就可以这样了,先通过设置MIMETYPE为

ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,查找姓名所对应的RAW_CONTACT_ID。再将MIMETYPE设置为

ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,查找上面找到的RAW_CONTACT_ID所对应的电话就可以了。

按这个细路就可以写代码了:

01/**
02*通过姓名(uName)来查找通讯录,返回一个list。其中"display_name"保存姓名,"phone_number"保存电话
03*/
04publicList<HashMap<String,String>>getContactsByName(StringuName){
05List<HashMap<String,String>>list=newArrayList<HashMap<String,String>>();
06booleanisQueryAll=false;
07//cu姓名游标,cn电话号码游标
08Cursorcu,cn=null;
09//查询条件,SQL是的Where语句的后部分
10Stringselection=null;
11
12uName=uName.trim();
13//是否查询全部通讯录,如果姓名为空则是
14isQueryAll=uName.equals("")?true:false;
15
16if(isQueryAll){
17//查询全部时的,查询条件,主要用在cu游标上
18selection=ContactsContract.Data.MIMETYPE
19+"='"
20+ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
21+"'";
22//System.out.println("QueryForALl--"+selection);
23}else{
24//根据姓名查询时的,查询条件,主要用在cu游标上
25selection=ContactsContract.Data.MIMETYPE
26+"='"
27+ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
28+"'"
29+"AND"
30+ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME
31+"LIKE"+"'%"+uName+"%'";
32//System.out.println("QueryForSome--"+selection);
33}
34
35try{
36//根据姓名查询出完整姓名和通讯录ID
37cu=contentReso
38.query(
39URI,
40newString[]{
41ContactsContract.Data.RAW_CONTACT_ID,
42ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME},
43selection,null,null);
44//根据通讯录ID,查找对应的电话号码的查询条件,主要用于cn游标
45selection=ContactsContract.Data.MIMETYPE+"='"
46+ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
47+"'"
48+"AND"
49+ContactsContract.Data.RAW_CONTACT_ID
50+"=?";
51//System.out.println("NumberQuery--"+selection);
52while(cu.moveToNext()){
53StringcontactId=String.valueOf(cu.getInt());
54//开始查找电话号码
55//System.out.println("StartQueryNum");
56cn=contentReso
57.query(
58URI,
59newString[]{ContactsContract.CommonDataKinds.Phone.NUMBER},
60selection,newString[]{contactId},null);
61
62while(cn.moveToNext()){
63//将一组通讯录记录在HashMap中
64HashMap<String,String>map=newHashMap<String,String>();
65map.put("display_name",cu.getString(1));
66map.put("phone_number",cn.getString());
67//将查到通讯录添加到List中
68list.add(map);
69}
70}
71//关闭游标
72cu.close();
73cn.close();
74}catch(Exceptione){
75//TODO:handleexception
76}
77returnlist;
78}
79}
PS:

最后再说一下那个MIMETYPE,在data数据库里面它的值是整型,如果看一下官方文档的话,给它所赋的值像

ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME之类的都字符串,那么这些字符串和data里面的整型是怎么对应的呢。

其实就是通过mimetypes表来对应的。里面的对应列主要就是9个:

1|vnd.android.cursor.item/email_v2

2|vnd.android.cursor.item/im

3|vnd.android.cursor.item/postal-address_v2

4|vnd.android.cursor.item/photo

5|vnd.android.cursor.item/phone_v2

6|vnd.android.cursor.item/name

7|vnd.android.cursor.item/organization

8|vnd.android.cursor.item/nickname

9|vnd.android.cursor.item/group_membership

作者:
holmesZhang

来自博客园:
/detail/2503167860.html

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,否则保留追究法律责任的权利。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: