android 数据库 联系人数据的一些常用URI

来源:互联网 发布:蓝牙网络连接有个叉 编辑:程序博客网 时间:2024/06/07 03:13
收集了使用Provider获取contacts2.db数据库联系人数据的一些常用URI。另外Android对contacts.db数据库的表做了类的封装,表中的字段都有相应的静态常量,更多详情可查阅官方文档:http://developer.android.com/ref ... vider/Contacts.html

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表中数据。
0 0
原创粉丝点击