解剖Android联系人之一,基于2.1_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > 解剖Android联系人之一,基于2.1

解剖Android联系人之一,基于2.1

 2011/1/5 7:53:23  lucane  http://lucane.javaeye.com  我要评论(0)
  • 摘要:最近要做个联系人相关的东西,所以需要研究研究Android的联系人数据结构比较不同,看起来比较混乱,作为新手来讲的我。但还是得上啊,因为就我一个人先看了几天的API,References,源码之类的(当然不是时时在看,这会儿翻翻,那会儿看看),比较迷糊,也有点理解,理解最多的就是他不是常理中想像的那样。说到联系人,有个类不得不说,那就是ContactsContract,我是基于2.1看的,这个类有5000多行,也够多的说实话,Android里面内部类,回调这些玩意用的太多了。。
  • 标签:android
最近要做个联系人相关的东西,所以需要研究研究

Android的联系人数据结构比较不同,看起来比较混乱,作为新手来讲的我。

但还是得上啊,因为就我一个人

先看了几天的API,References,源码之类的(当然不是时时在看,这会儿翻翻,那会儿看看),比较迷糊,也有点理解,理解最多的就是他不是常理中想像的那样。

说到联系人,有个类不得不说,那就是ContactsContract,我是基于2.1看的,这个类有5000多行,也够多的

说实话,Android里面内部类,回调这些玩意用的太多了。。。

当然说了这么多的时候我还是不清楚联系人的结构

记得某位大神说的,理论不懂就实践,实践不懂就理论,我也比较喜欢这样,但我啥时候才能成为大神呢,至少是个小神吧

于是我开始实践,准备从数据库下手,它里面的数据最终是存在sqlite里面的,于是就要把这个数据库导出来瞧瞧

我开始想把我的Android Phone里的联系人给导出来,里面有些联系人的数据,或许可以用来分析,看下

但因为找不到数据线,就此作罢

于是开始导模拟器中的库,里面也是有数据的,是我测试的时候放进去的

位置位于/data/data/com.android.providers.contacts/databases/contacts2.db
不管是用命令adb pull,还是DDMS中的File Explorer都是可以导出到宿主机的
可能有些人上面这个文件的位置不一样,具体翻翻就知道他在哪了
然后就是sqlite3命令了
看客们不要高兴太早,我连自己都没有把握,接下来会是什么样子,我只是把这一个过程记录下来

$ sqlite3 contacts2.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> 

看到有.help命令,当然第一个就是输入他了

sqlite> .help
.backup ?DB? FILE      Backup DB (default "main") to FILE
.bail ON|OFF           Stop after hitting an error.  Default OFF
.databases             List names and files of attached databases
.dump ?TABLE? ...      Dump the database in an SQL text format
                         If TABLE specified, only dump tables matching
                         LIKE pattern TABLE.
.echo ON|OFF           Turn command echo on or off
.exit                  Exit this program
.explain ?ON|OFF?      Turn output mode suitable for EXPLAIN on or off.
                         With no args, it turns EXPLAIN on.
.genfkey ?OPTIONS?     Options are:
                         --no-drop: Do not drop old fkey triggers.
                         --ignore-errors: Ignore tables with fkey errors
                         --exec: Execute generated SQL immediately
                       See file tool/genfkey.README in the source 
                       distribution for further information.
.header(s) ON|OFF      Turn display of headers on or off
.help                  Show this message
.import FILE TABLE     Import data from FILE into TABLE
.indices ?TABLE?       Show names of all indices
                         If TABLE specified, only show indices for tables
                         matching LIKE pattern TABLE.
.load FILE ?ENTRY?     Load an extension library
.log FILE|off          Turn logging on or off.  FILE can be stderr/stdout
.mode MODE ?TABLE?     Set output mode where MODE is one of:
                         csv      Comma-separated values
                         column   Left-aligned columns.  (See .width)
                         html     HTML <table> code
                         insert   SQL insert statements for TABLE
                         line     One value per line
                         list     Values delimited by .separator string
                         tabs     Tab-separated values
                         tcl      TCL list elements
.nullvalue STRING      Print STRING in place of NULL values
.output FILENAME       Send output to FILENAME
.output stdout         Send output to the screen
.prompt MAIN CONTINUE  Replace the standard prompts
.quit                  Exit this program
.read FILENAME         Execute SQL in FILENAME
.restore ?DB? FILE     Restore content of DB (default "main") from FILE
.schema ?TABLE?        Show the CREATE statements
                         If TABLE specified, only show tables matching
                         LIKE pattern TABLE.
.separator STRING      Change separator used by output mode and .import
.show                  Show the current values for various settings
.tables ?TABLE?        List names of tables
                         If TABLE specified, only list tables matching
                         LIKE pattern TABLE.
.timeout MS            Try opening locked tables for MS milliseconds
.width NUM1 NUM2 ...   Set column widths for "column" mode
.timer ON|OFF          Turn the CPU timer measurement on or off


出来的东西目前也不是很有用,就是一些命令的用法,其中有个命令是.table,这是我们需要的,他这里的命令前面都是带dot symbol的,该死的,网络又断了,这么不给力的网

sqlite> .tables
_sync_state                       status_updates                  
_sync_state_metadata              v1_settings                     
activities                        view_contacts                   
agg_exceptions                    view_contacts_restricted        
android_metadata                  view_data                       
calls                             view_data_restricted            
contact_entities_view             view_groups                     
contact_entities_view_restricted  view_raw_contacts               
contacts                          view_raw_contacts_restricted    
data                              view_v1_contact_methods         
groups                            view_v1_extensions              
mimetypes                         view_v1_group_membership        
name_lookup                       view_v1_groups                  
nickname_lookup                   view_v1_organizations           
packages                          view_v1_people                  
phone_lookup                      view_v1_phones                  
raw_contacts                      view_v1_photos                  
settings                        


这下面一共有这么多表

前几天还是看过一些资料的,ContactsContract有很多个内部类,其中有Data,RawContacts,Contacts之类的
这表里面也有类似的这几个表,当然都要打开看看咯

sqlite> select * from contacts;
1|海 郭|||0|0|0|0|1|1|0nE044748D16||0


sqlite> select * from raw_contacts;  
1|0||||2|1|0|1|0|0||0|0||0|海 郭|40||||


sqlite> select * from data;
1||4|1|0|0|0|坏人|1|||||||||||||||||
2||5|1|0|0|0|http://lucane.javaeye.com|7|||||||||||||||||
3||3|1|0|0|0|长板坡宜昌, 湖北 443200|1||长板坡|||宜昌|湖北|443200||||||||||
4||6|1|0|0|0|非人||||||||||||||||||
5||7|1|0|0|0|1-504-115-9854|1||45895114051|||||||||||||||
6||7|1|0|0|0|1-226-548-89|2||988456221|||||||||||||||
7||2|1|0|0|0|304683630|3|||4||||||||||||||
8||8|1|0|0|0|home|1||翻译官|||||||||||||||
9||9|1|0|0|0|海 郭|海|郭||||||||||||||||
10||1|1|0|0|0|xscript#live.com|2|||||||||||||||||
11||1|1|0|0|0|xseaer#gmail.com|1|||||||||||||||||


这都是我自己的的信息,真真假假,假假真真
命令行看着不怎么清晰,我前几天还在找和安装sqlite的图形化界面,结果未遂

可能新手看官看不出来啥东西,不过我有点看清楚了,因为我知道这有些数据项是什么意思

当然这所有的表当中可能还有些是视图,感兴趣的也可以都select出来看看

当然这还有些表是要select出来看的,比如mimetypes,

sqlite> select * from mimetypes;
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/nickname
5|vnd.android.cursor.item/website
6|vnd.android.cursor.item/note
7|vnd.android.cursor.item/phone_v2
8|vnd.android.cursor.item/organization
9|vnd.android.cursor.item/name
10|vnd.android.cursor.item/photo
11|vnd.android.cursor.item/group_membership


sqlite> select * from view_data;
1|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/nickname|坏人|1|||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
2|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/website|http://lucane.javaeye.com|7|||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
3|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/postal-address_v2|长板坡宜昌, 湖北 443200|1||长板坡|||宜昌|湖北|443200||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
4|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/note|非人||||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
5|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/phone_v2|1-504-115-9854|1||45895114051|||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
6|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/phone_v2|1-226-548-89|2||988456221|||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
7|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/im|304683630|3|||4||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
8|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/organization|home|1||翻译官|||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
9|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/name|海 郭|海|郭||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
10|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/email_v2|xscript#live.com|2|||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
11|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/email_v2|xseaer#gmail.com|1|||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||


比如看到view_data里面的数据是不是又有点开心了呢?

顺路把其他几个view也查处来看看吧

sqlite> select * from view_contacts;
1||海 郭|1|1|0nE044748D16||1|0|0|0|0|


sqlite> select * from view_contacts_restricted;
1||海 郭|1|1|0nE044748D16||1|0|0|0|0|


sqlite> select * from view_data_restricted;
1|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/nickname|坏人|1|||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
2|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/website|http://lucane.javaeye.com|7|||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
3|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/postal-address_v2|长板坡宜昌, 湖北 443200|1||长板坡|||宜昌|湖北|443200||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
4|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/note|非人||||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
5|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/phone_v2|1-504-115-9854|1||45895114051|||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
6|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/phone_v2|1-226-548-89|2||988456221|||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
7|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/im|304683630|3|||4||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
8|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/organization|home|1||翻译官|||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
9|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/name|海 郭|海|郭||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
10|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/email_v2|xscript#live.com|2|||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||
11|1|1||||2|1|||||0|0|0||vnd.android.cursor.item/email_v2|xseaer@#mail.com|1|||||||||||||||||||0|0|0|0|海 郭|0nE044748D16||1||


比较让我失望的是android_metadata,settings这些表当中没有查询出什么数据
因为我总觉得这些mimetypes什么的应该和某个数字或字符相对应(后来发现了mimetypes中的文字就是和该表当中貌似第一列主键的这个东西对应的,在其他的表中也是直接存的这个数字)

恩,接着再往下看吧,该搞那块了?

这些表当中数据的存放不是通常的一个字段对应下面的数据都是这个意思,比如username字段下的数据都是用户名

在data表当中,至少我们现在可以明显的看出来在data表中,每行数据有指定他的类型,说他是什么,他就是什么

用原话来说基本就是这样Generic data column, the meaning is {@link #MIMETYPE} specific
大概可能就是说当每一条数据的MIMETYPE定了,那么它每一列代表的含义也就定了

这种方式大概就是为了扩展的需要吧,当年我们也有这么干的时候

不知道大家对这个查询出来的数据有没有和我们平时不同的感觉
我感觉它缺了个title,虽然他的title含义不是固定的,但我总想看看

于是想把他弄出来看看
还记得我们最开始的时候.help出来有很多命令,我们只用了.table这个最关键的
既然想看表的结构么,当然就是desc或者describe这些命令了,不才我虽然正式开始Rock Android才不久,但是以前还是搞SSH的,Oracle和MySQL还是略懂一二的

不过没有发现类似的命令,倒是发现了个.schema(Show the CREATE statements)命令,既然图形化的看不见,看SQL也是一样的

sqlite> .schema data
CREATE TABLE data (_id INTEGER PRIMARY KEY AUTOINCREMENT,package_id INTEGER REFERENCES package(_id),mimetype_id INTEGER REFERENCES mimetype(_id) NOT NULL,raw_contact_id INTEGER REFERENCES raw_contacts(_id) NOT NULL,is_primary INTEGER NOT NULL DEFAULT 0,is_super_primary INTEGER NOT NULL DEFAULT 0,data_version INTEGER NOT NULL DEFAULT 0,data1 TEXT,data2 TEXT,data3 TEXT,data4 TEXT,data5 TEXT,data6 TEXT,data7 TEXT,data8 TEXT,data9 TEXT,data10 TEXT,data11 TEXT,data12 TEXT,data13 TEXT,data14 TEXT,data15 TEXT,data_sync1 TEXT, data_sync2 TEXT, data_sync3 TEXT, data_sync4 TEXT );
CREATE INDEX data_mimetype_data1_index ON data (mimetype_id,data1);
CREATE INDEX data_raw_contact_id ON data (raw_contact_id);
CREATE TRIGGER data_deleted BEFORE DELETE ON data BEGIN    UPDATE raw_contacts     SET version=version+1      WHERE _id=OLD.raw_contact_id;   DELETE FROM phone_lookup     WHERE data_id=OLD._id;   DELETE FROM status_updates     WHERE status_update_data_id=OLD._id;   DELETE FROM name_lookup     WHERE data_id=OLD._id; END;
CREATE TRIGGER data_updated BEFORE UPDATE ON data BEGIN    UPDATE data     SET data_version=OLD.data_version+1      WHERE _id=OLD._id;   UPDATE raw_contacts     SET version=version+1      WHERE _id=OLD.raw_contact_id; END;


好长啊,又是表,又是索引,又是触发器,这么一个小数据库开是挺专业的
好吧,既然没有图形化的,我手动给他画个,刷个牙,回来再继续,晚上10点半了

引用
发表评论
用户名: 匿名