android联系人数据库一些知识点

Android对contacts.db数据库的表做了类的封装,表中的字段都有相应的静态常量, 更多详情可查阅官方文档: http://developer.android.com/ref ... vider/Contacts.html
Provider获取contacts2.db数据库联系人数据的一些常用URI contacts表也就是联系人表的URI —— content://com.android.contacts/contacts , 对应类静态常量为ContactsContract.Contacts.CONTENT_URI
联系人电话URI —— content://com.android.contacts/data/phones , 对应静态常量为ContactsContract.CommonDataKinds.Phone.CONTENT_URI
联系人邮箱URI —— content://com.android.contacts/data/emails, 对应静态常量为ContactsContract.CommonDataKinds.Email.CONTENT_URI
联系人地址URI —— content://com.android.contacts/data/postals , 对应静态常量为ContactsContract.CommonDataKinds.StructuredPostall.CONTENT_URI
所有联系人的Uri —— content://contacts/people
某个联系人x的Ur —— content://contacts/people/x
data表URI —— content://com.android.contacts/data , 对应静态常量为ContactsContract.Data.CONTENT_URI

data表中提供了data1-data15命名的表项,google不使用有实际意义的单词来命名是有原因的。 data表用于存放联系人的具体数据信息,包括姓名、地址、电话等等。 每一行为一个数据项信息 (比如姓名为一行数据,其中包括前缀名字段,中间名字段,后缀名字段等; 地址为一行数据,其中包括省份,城市,街道等)。 假如采用具体有实际意义的单词来作为字段名,以姓名数据需要的字段中间名来说,采用这个字段名,那么这个字段只有姓名数据需要, 而其它地址、电话等数据都不需要,那么它们就需要把这个字段值镂空。这么一来,整个表中就会有很多数据项镂空。 因此,采用data1-data15来命名字段,而每行数据区分data1-data15代表的实际意义依赖于外键字段mimetype_id(数据类型)来区别。
一下是一些数据类型data字段的部分意义: 当data行数据类型为名字时,data x表项代表意义:
PREFIX = "data4"; //名称前缀
MID_NAME = "data5";//中间名
GIVEN_NAME = "data2";//名字
FAMILY_NAME = "data3";//姓氏
MID_PINYIN="data8"; //中间名拼音
String FAMILY_NAME_PINYIN="data9"; //姓氏拼音
String SUFIX = "data6"; //名称后缀
String SUFIX_PINYIN="data7"; //名字拼音

当data行数据类型为电话类型时,data x表项代表意义:
phone: "data1";//号码
Type: "data2";//这个字段是整形值,指示电话类型,电话类型对应关系如下:
TYPE_CUSTOM = 0;
TYPE_HOME = 1;
TYPE_MOBILE = 2;
TYPE_WORK = 3;
TYPE_FAX_WORK = 4;
TYPE_FAX_HOME = 5;
TYPE_PAGER = 6;
TYPE_OTHER = 7;

当data行数据类型为邮箱时,data x表项代表意义:
Email: "data1";//邮箱地址
Type: "data2";//这个字段是整形值,指示Email类型,Email类型对应关系如下:
TYPE_CUSTOM = 0;
TYPE_HOME = 1;
TYPE_WORK = 2;
TYPE_OTHER = 3;
TYPE_MOBILE = 4;

当data行数据类型为地址时,data x表项代表意义:
STREET="data4";//街道
CITY="data8";//城市
STATE="data7";//州
ZIP_CODE="data9";//邮政编码
Type:"data2";//地址的类型,对应关系如下:
TYPE_CUSTOM = 0;
TYPE_HOME = 1;
TYPE_WORK = 2;
TYPE_OTHER = 3;

ContactsContract.Data类中对data、raw_contracts、contract表中大部分数据项做了封装,提供了大量静态常量对应表中的数据项, 如ContactsContract.Data._ID、ContactsContract.Data.RAW_CONTACT_ID等等
ContactsContract.RawContacts类对raw_contracts表封装,提供了ContactsContract.RawContacts._ID等静态常量字段。
ContactsContract.ContactsContract.CommonDataKinds.XXXX类对各种表项数据类型做了封装。

————————————————
关于data表和raw_contracts表的触发器(contracts表没有触发器):
1.data表的触发器:
CREATE TRIGGER data_updated AFTER 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;

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;

2、raw_contracts触发器:
CREATE TRIGGER raw_contacts_deleted BEFORE DELETE ON raw_contacts
BEGIN
DELETE 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_contacts WHERE contact_id=OLD.contact_id )=1;
END;

以下是我做单元测试的一下情况和推测:
1、单独向data表中插入新联系人数据,而没有先向raw_contacts表中插入新联系人相关信息来获取新联系人的raw_contact_id, 结果数据能插入到data表中,但是android系统自带的联系人程序中没有显示新联系人的信息,数据库中也没有因为data表中插入 了新的数据而自动更新raw_contacts表和contacts表数据。 原因应该在于data表中没有插入数据的触发器来处理这个事件,推测ContactProvider源代码中也没有处理这个情况的方法, 所以raw_contacts表和contacts表不会自动更新。 推测Android系统自带联系人程序中显示的联系人列表是根据raw_contact_id字段来读取,因为raw_contacts表中没有对新联系人创建新的id, 所以单纯向data表添加新联系人数据,系统自带联系人程序无法读取。 2、删除raw_contacts表中数据项,结果android系统自带联系人程序列表中对应联系人选项没有显示(删除?), 但是数据库中raw_contacts表中该表项数据依然存在,并且data表中对应联系人的数据依然存在。 变化的是raw_contacts表中该联系人的字段deleted字段值由原来的0变为1、contact_id字段值变为null、version值会增加, 还有contacts表中该联系人的数据被删除。 首先,系统自带联系人程序读取数据库依赖于raw_contact_id字段?可以肯定的是只要data表中联系人数据对应的外键raw_contact_id字段值 在raw_contacts表中不存在或者存在但deleted字段被标识为1,那么联系人程序就读取不到该联系人在data表中的具体信息。 从raw_contacts表中的触发器来看,触发的操作并没修改自身表的操作,对应的是删除data表、agg_exceptions表、contacts表中相应id的数据, 测试结果中后两个表中的数据确实被删除了,但data表中没有,猜测是ContactsProvider源代码中做的操作。 3、直接删除data表中联系人的数据。 这里分两种情况,一种是data表中要删除联系人的raw_contact_id在raw_contact表中不存在或deleted被标志为1, 那么将无法删除data表中该联系人的数据; 另一种是data表中要删除联系人的raw_contact_id在raw_contact表中存在且deleted字段值为0, data表中该联系人的数据将能被删除,删除的结果是android自带联系人程序该联系人选项显示“未知联系人”, 即没有联系人信息的联系人。由此,想要从数据库中删除联系人数据,应该遵循顺序先删除data表中联系人信息,再删除raw_contact表中数据。
2和3 是置delete字段为1 删除联系人,物理删除联系人数据即rawcontacts表中数据可以参考 http://blog.csdn.net/zhao7134/article/details/8477158

更多相关文章

  1. 在android studio中用SQLiteOpenHelper()方法建立数据库
  2. Android SQLcipher 数据库解密
  3. android 联系人 增删改查
  4. android 数据库操作初试
  5. 开源项目之Android DataFramework(数据库框架)
  6. Java/Android 中使用Protocol Buffers传输数据
  7. Android studio查看SQLIte数据库文件

随机推荐

  1. android sdk下载更新不了问题解决
  2. Android Dialog在底部显示且宽度match_pa
  3. Android 简单模仿AsyncHttpClient
  4. android 数据库操作
  5. android webView判断是否加载完成的2种办
  6. android 评分组件 RatingBar
  7. android之ArrayAdaper之Spinner
  8. 安卓应用开发基础:android Dev Guide的App
  9. Android AlertDialog背景透明
  10. Using cygwin with the Android NDK on W