Android源码——通讯录联系人(一):Contacts数据库初识
2015-08-19 15:52
387 查看
下边讲讲我前段时间在公司做通讯录联系人所学习到的一些知识,跟大家分享一下。
一、Contacts数据库存放位置:
cmd->adb remount(如果remount succeeded)->adb shell ->cd data/data/com.android.providers.contacts ->cd databases ->会显示contacts的数据库名,例如contacts2.db ->sqlite3 contacts2.db ->
C:Documents and SettingsAdministrator>adb remount
remount succeeded
C:Documents and SettingsAdministrator>adb shell
# cd data/data/com.android.providers.contacts
cd data/data/com.android.providers.contacts
# cd databases
cd databases
# ls
ls
contacts2.db
# sqlite3 contacts2.db
sqlite3 contacts2.db
SQLite version 3.6.22
Enter “.help” for instructions
Enter SQL statements terminated with a “;”
二、contacts数据库初识:
1、.tables (显示contacts2数据库中所有的表):
sqlite> .tables
.tables
_sync_state settings
_sync_state_metadata status_updates
accounts 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
properties view_v1_photos
raw_contacts
在通讯录中主要用到的是:contacts表,raw_contacts表,data表 以及其他附表:groups(用于存储通讯录按字母排序时的分批信息),name_lookup(仅存储名字信息的表),phone_lookup(仅存储电话号码信息的表)等。最重要的是contacts、raw_contacts、data这三个表。
2、用.schema [tablename] 查看表结构
sqlite> .schema data
.schema data
CREATE TABLE data (_id INTEGER PRIMARY KEY AUTOINCREMENT,package_id INTEGER REFE
RENCES package(_id),mimetype_id INTEGER REFERENCES mimetype(_id) NOT NULL,raw_co
ntact_id INTEGER REFERENCES raw_contacts(_id) NOT NULL,is_primary INTEGER NOT NU
LL DEFAULT 0,is_super_primary INTEGER NOT NULL DEFAULT 0,data_version INTEGER NO
T NULL DEFAULT 0,data1 TEXT,data2 TEXT,data3 TEXT,data4 TEXT,data5 TEXT,data6 TE
XT,data7 TEXT,data8 TEXT,data9 TEXT,data10 TEXT,data11 TEXT,data12 TEXT,data13 T
EXT,data14 TEXT,data15 TEXT,data_sync1 TEXT, data_sync2 TEXT, data_sync3 TEXT, d
ata_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 AFTER UPDATE ON data BEGIN UPDATE data SET da
ta_version=OLD.data_version+1 WHERE _id=OLD._id; UPDATE raw_contacts
SET version=version+1 WHERE _id=OLD.raw_contact_id; END;
字段注解:
_id:data一条记录的id号,自增
package_id:
mimetype_id:决定当条记录的数据类型,在raw_contacts表中单挑记录即单个联系人只有一行记录,但是该联系人包含了名字、电话、地址等信息,每一种信息在data表中都是单一的一条记录插入,而mimetype_id的值就决定了该条data记录是什么类型的数据,比如插入的是电话类型的数据,那么此时的mimetype_id=5;mimetype_id的值对应的类型如下:
_id mimetype
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
这里特别注意,当你查询data表需要返回mimetype_id这一列结果时,字段名称应该为”mimetype”,而不是“mimetype_id”,否则会数据库查询会报错,因为在view_data表中的字段值为”mimetype”,而不是“mimetype_id”,view_data是data表的一个视图,比如你查询data表,实际查询的是view_data表,返回的结果可能并不是data表中的字段内容以及顺序;同时,这里返回的mimetype字段的值,我们在data表中看到的定义的是整形,但在view_data表中的类型时text类型,所以从查询得到Cursor结果中去取mimetype字段的值时,应该用getString(),而不应该用getInt(),否则得到的值并不是你想要的值,用getString()得到的值就是上表中的mimetype字段对应的这九种字串,如果需要转换成_id值,还需对该字串按照上面的表进行一一匹配。
raw_contact_id:即该条data记录与之关联的raw_contacts表的id
is_primary:
is_super_primary:
data_version:data的版本号,如果该条data记录有改动,则会刷新data_version的值,在前一个版本上加1;
data1-> data15:可存放任意类型的数据,每个字段应存放什么类型的数据根据mimetype_id的值来确定,比如如果是mimetype_id=5,即电话类型的数据,那么data1存放电话号码字串,data2存放电话号码类型,比如说是住宅电话,那么data2存”2”,data3存放电话号码的反字串,等等。。。
data_sync1:
data_sync2:
data_sync3:
data_sync4:
sqlite> .schema raw_contacts
.schema raw_contacts
CREATE TABLE raw_contacts (_id INTEGER PRIMARY KEY AUTOINCREMENT,is_restricted I
NTEGER DEFAULT 0,account_name STRING DEFAULT NULL, account_type STRING DEFAULT N
ULL, sourceid TEXT,version INTEGER NOT NULL DEFAULT 1,dirty INTEGER NOT NULL DEF
AULT 0,deleted INTEGER NOT NULL DEFAULT 0,contact_id INTEGER REFERENCES contacts
(_id),aggregation_mode INTEGER NOT NULL DEFAULT 0,aggregation_needed INTEGER NOT
NULL DEFAULT 1,custom_ringtone TEXT,send_to_voicemail INTEGER NOT NULL DEFAULT
0,times_contacted INTEGER NOT NULL DEFAULT 0,last_time_contacted INTEGER,starred
INTEGER NOT NULL DEFAULT 0,display_name TEXT,display_name_alt TEXT,display_name
_source INTEGER NOT NULL DEFAULT 0,phonetic_name TEXT,phonetic_name_style TEXT,s
ort_key TEXT COLLATE PHONEBOOK,sort_key_alt TEXT COLLATE PHONEBOOK,name_verified
INTEGER NOT NULL DEFAULT 0,contact_in_visible_group INTEGER NOT NULL DEFAULT 0,
sync1 TEXT, sync2 TEXT, sync3 TEXT, sync4 TEXT, raw_contact_type INTEGER NOT NUL
L DEFAULT 0 );
CREATE INDEX raw_contact_sort_key1_index ON raw_contacts (contact_in_visible_gro
up,sort_key);
CREATE INDEX raw_contact_sort_key2_index ON raw_contacts (contact_in_visible_gro
up,sort_key_alt);
CREATE INDEX raw_contacts_contact_id_index ON raw_contacts (contact_id);
CREATE INDEX raw_contacts_source_id_index ON raw_contacts (sourceid, account_typ
e, account_name);
CREATE TRIGGER raw_contacts_deleted BEFORE DELETE ON raw_contacts BEGIN DE
LETE FROM data WHERE raw_contact_id=OLD._id; DELETE FROM agg_exceptions
WHERE raw_contact_id1=OLD._id OR raw_contact_id2=OLD._id; DELETE FROM
contacts WHERE _id=OLD.contact_id AND (SELECT COUNT(*) FROM raw_conta
cts WHERE contact_id=OLD.contact_id )=1; END;
CREATE TRIGGER raw_contacts_marked_deleted AFTER UPDATE ON raw_contacts BEGIN
UPDATE raw_contacts SET version=OLD.version+1 WHERE _id=OLD._id
AND NEW.deleted!= OLD.deleted; END;
字段注解:
_id:raw_contacts表的id,自增
is_restricted:
account_name:
account_type:
sourceid:
version:
dirty:
deleted:
contact_id:该条记录对应的关联的contacts表的id
aggregation_mode:集成模型,有四种类型,
0:
1:
2:
3:
aggregation_needed:
custom_ringtone:
send_to_voicemail:
times_contacted:
last_time_contacted:
sqlite> .schema contacts
.schema contacts
CREATE TABLE contacts (_id INTEGER PRIMARY KEY AUTOINCREMENT,name_raw_contact_id
INTEGER REFERENCES raw_contacts(_id),photo_id INTEGER REFERENCES data(_id),cust
om_ringtone TEXT,send_to_voicemail INTEGER NOT NULL DEFAULT 0,times_contacted IN
TEGER NOT NULL DEFAULT 0,last_time_contacted INTEGER,starred INTEGER NOT NULL DE
FAULT 0,in_visible_group INTEGER NOT NULL DEFAULT 1,has_phone_number INTEGER NOT
NULL DEFAULT 0,lookup TEXT,status_update_id INTEGER REFERENCES data(_id),single
_is_restricted INTEGER NOT NULL DEFAULT 0,contact_type INTEGER NOT NULL DEFAULT
0);
CREATE INDEX contacts_has_phone_index ON contacts (has_phone_number);
CREATE INDEX contacts_name_raw_contact_id_index ON contacts (name_raw_contact_id
);
CREATE INDEX contacts_restricted_index ON contacts (single_is_restricted);
CREATE INDEX contacts_visible_index ON contacts (in_visible_group);
sqlite>
字段注解:
_id,当前记录contacts表中的id,通常表示为contact_id,对应raw_contacts表中的contact_id;
name_raw_contact_id:从name_lookup表中取到的raw_contact_id,基本上就是对应raw_contacts表中的id
photo_id:
custom_ringtone:
send_to_voicemail:
times_contacted:
last_time_contacted:
in_visible_group:
has_phone_number:
lookup:
status_update_id:
single_is_restricted:
contact_type:
3、查看表中的数据:select * from [tablename];
sqlite> select * from data;
select * from data;
62||5|34|0|0|0|112|1||211|||||||||||||||
63||6|34|0|0|0|dhdh||dhdh|||||||1|0||||||||
sqlite> select * from raw_contacts;
select * from raw_contacts;
34|0||||2|1|0|34|0|0||0|0||0|dhdh|dhdh|40||0|dhdh|dhdh|0|1|||||0
sqlite> select * from contacts;
select * from contacts;
34|34|||0|0|0|0|1|1|0r34-323A323A||0|0
sqlite>
一、Contacts数据库存放位置:
cmd->adb remount(如果remount succeeded)->adb shell ->cd data/data/com.android.providers.contacts ->cd databases ->会显示contacts的数据库名,例如contacts2.db ->sqlite3 contacts2.db ->
C:Documents and SettingsAdministrator>adb remount
remount succeeded
C:Documents and SettingsAdministrator>adb shell
# cd data/data/com.android.providers.contacts
cd data/data/com.android.providers.contacts
# cd databases
cd databases
# ls
ls
contacts2.db
# sqlite3 contacts2.db
sqlite3 contacts2.db
SQLite version 3.6.22
Enter “.help” for instructions
Enter SQL statements terminated with a “;”
二、contacts数据库初识:
1、.tables (显示contacts2数据库中所有的表):
sqlite> .tables
.tables
_sync_state settings
_sync_state_metadata status_updates
accounts 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
properties view_v1_photos
raw_contacts
在通讯录中主要用到的是:contacts表,raw_contacts表,data表 以及其他附表:groups(用于存储通讯录按字母排序时的分批信息),name_lookup(仅存储名字信息的表),phone_lookup(仅存储电话号码信息的表)等。最重要的是contacts、raw_contacts、data这三个表。
2、用.schema [tablename] 查看表结构
sqlite> .schema data
.schema data
CREATE TABLE data (_id INTEGER PRIMARY KEY AUTOINCREMENT,package_id INTEGER REFE
RENCES package(_id),mimetype_id INTEGER REFERENCES mimetype(_id) NOT NULL,raw_co
ntact_id INTEGER REFERENCES raw_contacts(_id) NOT NULL,is_primary INTEGER NOT NU
LL DEFAULT 0,is_super_primary INTEGER NOT NULL DEFAULT 0,data_version INTEGER NO
T NULL DEFAULT 0,data1 TEXT,data2 TEXT,data3 TEXT,data4 TEXT,data5 TEXT,data6 TE
XT,data7 TEXT,data8 TEXT,data9 TEXT,data10 TEXT,data11 TEXT,data12 TEXT,data13 T
EXT,data14 TEXT,data15 TEXT,data_sync1 TEXT, data_sync2 TEXT, data_sync3 TEXT, d
ata_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 AFTER UPDATE ON data BEGIN UPDATE data SET da
ta_version=OLD.data_version+1 WHERE _id=OLD._id; UPDATE raw_contacts
SET version=version+1 WHERE _id=OLD.raw_contact_id; END;
字段注解:
_id:data一条记录的id号,自增
package_id:
mimetype_id:决定当条记录的数据类型,在raw_contacts表中单挑记录即单个联系人只有一行记录,但是该联系人包含了名字、电话、地址等信息,每一种信息在data表中都是单一的一条记录插入,而mimetype_id的值就决定了该条data记录是什么类型的数据,比如插入的是电话类型的数据,那么此时的mimetype_id=5;mimetype_id的值对应的类型如下:
_id mimetype
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
这里特别注意,当你查询data表需要返回mimetype_id这一列结果时,字段名称应该为”mimetype”,而不是“mimetype_id”,否则会数据库查询会报错,因为在view_data表中的字段值为”mimetype”,而不是“mimetype_id”,view_data是data表的一个视图,比如你查询data表,实际查询的是view_data表,返回的结果可能并不是data表中的字段内容以及顺序;同时,这里返回的mimetype字段的值,我们在data表中看到的定义的是整形,但在view_data表中的类型时text类型,所以从查询得到Cursor结果中去取mimetype字段的值时,应该用getString(),而不应该用getInt(),否则得到的值并不是你想要的值,用getString()得到的值就是上表中的mimetype字段对应的这九种字串,如果需要转换成_id值,还需对该字串按照上面的表进行一一匹配。
raw_contact_id:即该条data记录与之关联的raw_contacts表的id
is_primary:
is_super_primary:
data_version:data的版本号,如果该条data记录有改动,则会刷新data_version的值,在前一个版本上加1;
data1-> data15:可存放任意类型的数据,每个字段应存放什么类型的数据根据mimetype_id的值来确定,比如如果是mimetype_id=5,即电话类型的数据,那么data1存放电话号码字串,data2存放电话号码类型,比如说是住宅电话,那么data2存”2”,data3存放电话号码的反字串,等等。。。
data_sync1:
data_sync2:
data_sync3:
data_sync4:
sqlite> .schema raw_contacts
.schema raw_contacts
CREATE TABLE raw_contacts (_id INTEGER PRIMARY KEY AUTOINCREMENT,is_restricted I
NTEGER DEFAULT 0,account_name STRING DEFAULT NULL, account_type STRING DEFAULT N
ULL, sourceid TEXT,version INTEGER NOT NULL DEFAULT 1,dirty INTEGER NOT NULL DEF
AULT 0,deleted INTEGER NOT NULL DEFAULT 0,contact_id INTEGER REFERENCES contacts
(_id),aggregation_mode INTEGER NOT NULL DEFAULT 0,aggregation_needed INTEGER NOT
NULL DEFAULT 1,custom_ringtone TEXT,send_to_voicemail INTEGER NOT NULL DEFAULT
0,times_contacted INTEGER NOT NULL DEFAULT 0,last_time_contacted INTEGER,starred
INTEGER NOT NULL DEFAULT 0,display_name TEXT,display_name_alt TEXT,display_name
_source INTEGER NOT NULL DEFAULT 0,phonetic_name TEXT,phonetic_name_style TEXT,s
ort_key TEXT COLLATE PHONEBOOK,sort_key_alt TEXT COLLATE PHONEBOOK,name_verified
INTEGER NOT NULL DEFAULT 0,contact_in_visible_group INTEGER NOT NULL DEFAULT 0,
sync1 TEXT, sync2 TEXT, sync3 TEXT, sync4 TEXT, raw_contact_type INTEGER NOT NUL
L DEFAULT 0 );
CREATE INDEX raw_contact_sort_key1_index ON raw_contacts (contact_in_visible_gro
up,sort_key);
CREATE INDEX raw_contact_sort_key2_index ON raw_contacts (contact_in_visible_gro
up,sort_key_alt);
CREATE INDEX raw_contacts_contact_id_index ON raw_contacts (contact_id);
CREATE INDEX raw_contacts_source_id_index ON raw_contacts (sourceid, account_typ
e, account_name);
CREATE TRIGGER raw_contacts_deleted BEFORE DELETE ON raw_contacts BEGIN DE
LETE FROM data WHERE raw_contact_id=OLD._id; DELETE FROM agg_exceptions
WHERE raw_contact_id1=OLD._id OR raw_contact_id2=OLD._id; DELETE FROM
contacts WHERE _id=OLD.contact_id AND (SELECT COUNT(*) FROM raw_conta
cts WHERE contact_id=OLD.contact_id )=1; END;
CREATE TRIGGER raw_contacts_marked_deleted AFTER UPDATE ON raw_contacts BEGIN
UPDATE raw_contacts SET version=OLD.version+1 WHERE _id=OLD._id
AND NEW.deleted!= OLD.deleted; END;
字段注解:
_id:raw_contacts表的id,自增
is_restricted:
account_name:
account_type:
sourceid:
version:
dirty:
deleted:
contact_id:该条记录对应的关联的contacts表的id
aggregation_mode:集成模型,有四种类型,
0:
1:
2:
3:
aggregation_needed:
custom_ringtone:
send_to_voicemail:
times_contacted:
last_time_contacted:
sqlite> .schema contacts
.schema contacts
CREATE TABLE contacts (_id INTEGER PRIMARY KEY AUTOINCREMENT,name_raw_contact_id
INTEGER REFERENCES raw_contacts(_id),photo_id INTEGER REFERENCES data(_id),cust
om_ringtone TEXT,send_to_voicemail INTEGER NOT NULL DEFAULT 0,times_contacted IN
TEGER NOT NULL DEFAULT 0,last_time_contacted INTEGER,starred INTEGER NOT NULL DE
FAULT 0,in_visible_group INTEGER NOT NULL DEFAULT 1,has_phone_number INTEGER NOT
NULL DEFAULT 0,lookup TEXT,status_update_id INTEGER REFERENCES data(_id),single
_is_restricted INTEGER NOT NULL DEFAULT 0,contact_type INTEGER NOT NULL DEFAULT
0);
CREATE INDEX contacts_has_phone_index ON contacts (has_phone_number);
CREATE INDEX contacts_name_raw_contact_id_index ON contacts (name_raw_contact_id
);
CREATE INDEX contacts_restricted_index ON contacts (single_is_restricted);
CREATE INDEX contacts_visible_index ON contacts (in_visible_group);
sqlite>
字段注解:
_id,当前记录contacts表中的id,通常表示为contact_id,对应raw_contacts表中的contact_id;
name_raw_contact_id:从name_lookup表中取到的raw_contact_id,基本上就是对应raw_contacts表中的id
photo_id:
custom_ringtone:
send_to_voicemail:
times_contacted:
last_time_contacted:
in_visible_group:
has_phone_number:
lookup:
status_update_id:
single_is_restricted:
contact_type:
3、查看表中的数据:select * from [tablename];
sqlite> select * from data;
select * from data;
62||5|34|0|0|0|112|1||211|||||||||||||||
63||6|34|0|0|0|dhdh||dhdh|||||||1|0||||||||
sqlite> select * from raw_contacts;
select * from raw_contacts;
34|0||||2|1|0|34|0|0||0|0||0|dhdh|dhdh|40||0|dhdh|dhdh|0|1|||||0
sqlite> select * from contacts;
select * from contacts;
34|34|||0|0|0|0|1|1|0r34-323A323A||0|0
sqlite>
相关文章推荐
- Android 环境配置第一节
- Android进程通信之binder驱动源码的理解
- Android layer-list的属性和使用详解
- Android中<uses-sdk>属性和target属性分析
- Android笔记(一)AndroidManifest.xml
- android 代码混淆后出现:TypeReference constructed without actual type information这个错误的解决方法
- 【Android应用开发技术:应用组件】Android事件处理机制
- Android用RadioGroup控件实现Tab选项卡效果
- 关于Android生命周期的一些知识
- Android manifest 标签学习
- Android中ActivityManager(AM)的方法解释和几个使用场景介绍
- 19 个 Android 开发工具
- Android fragment详解(一 )
- Android 判断当前线程是否为主线程
- Android Message和obtainMessage的区别
- Android Message和obtainMessage的区别
- Android应用的自动升级、更新模块的实现完整方案+参考程序
- Android View的小结
- 【Android】pull解析xml文件+将数据存储为xml格式,并保存在内存里
- Android(java)学习笔记177:BroadcastReceiver之 应用程序安装和卸载 的广播接收者