ContactsProvider建表的都在

packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsDatabaseHelper.java

首先该文件中有个Tables接口,其中的常量定义了数据库中大部分的表

    public interface Tables {public static final String CONTACTS = "contacts";  //联系人,由raw_contacts表聚合而成public static final String DELETED_CONTACTS = "deleted_contacts"; //标记要删除的联系人public static final String RAW_CONTACTS = "raw_contacts"; //联系人的原始数据,同一个联系人可能对应多个raw_contactspublic static final String STREAM_ITEMS = "stream_items"; //IM信息public static final String STREAM_ITEM_PHOTOS = "stream_item_photos"; //IM信息相关头像public static final String PHOTO_FILES = "photo_files"; //照片public static final String PACKAGES = "packages"; //包名public static final String MIMETYPES = "mimetypes"; //mime类型public static final String PHONE_LOOKUP = "phone_lookup"; //依据号码查联系人public static final String NAME_LOOKUP = "name_lookup"; //依据名字查联系人public static final String AGGREGATION_EXCEPTIONS = "agg_exceptions"; //合并联系人规则public static final String SETTINGS = "settings"; //设置public static final String DATA = "data"; //联系人最原始的数据,每一个row可以是号码、地址、名字等等public static final String GROUPS = "groups"; //联系人组public static final String PRESENCE = "presence"; //IM在线状态public static final String AGGREGATED_PRESENCE = "agg_presence"; //IM在线状态,聚合使用public static final String NICKNAME_LOOKUP = "nickname_lookup"; //昵称查找public static final String CALLS = "calls"; //通话记录public static final String STATUS_UPDATES = "status_updates";//聊天程序状态public static final String PROPERTIES = "properties"; //属性public static final String ACCOUNTS = "accounts"; //账户public static final String VISIBLE_CONTACTS = "visible_contacts"; //标记可见联系人public static final String DIRECTORIES = "directories";//通讯录public static final String DEFAULT_DIRECTORY = "default_directory";//默认通讯录public static final String SEARCH_INDEX = "search_index"; //搜索public static final String VOICEMAIL_STATUS = "voicemail_status";//语音邮箱public static final String PRE_AUTHORIZED_URIS = "pre_authorized_uris";//申请权限...public static final String DATA_USAGE_STAT = "data_usage_stat"; //data使用统计...public static final String DIALER_SEARCH = "dialer_search";//拨号盘搜索表public static final String CONFERENCE_CALLS = "conference_calls"; //会议组通话}  

PROPERTIES

属性表
        db.execSQL("CREATE TABLE " + Tables.PROPERTIES + " (" +PropertiesColumns.PROPERTY_KEY + " TEXT PRIMARY KEY, " + //keyPropertiesColumns.PROPERTY_VALUE + " TEXT " + //value");");

只有两个字段,key值有:

    public interface DbProperties {String DIRECTORY_SCAN_COMPLETE = "directoryScanComplete"; //Directory扫描完毕String AGGREGATION_ALGORITHM = "aggregation_v2";//联系人聚合算法String KNOWN_ACCOUNTS = "known_accounts"; //系统所有账号String ICU_VERSION = "icu_version"; //icu版本String LOCALE = "locale"; //所在区域String DATABASE_TIME_CREATED = "database_time_created"; //数据库创建时间String CALL_LOG_LAST_SYNCED = "call_log_last_synced"; //最后一次同步通话记录的时间}

ICU的解释见点击打开链接

ICU(International Component for Unicode) 是 IBM 与开源组织合作研究 , 基于 "IBM 公共许可证 " 的用于支持软件国际化的开源项目。 ICU 实现了对数字、日期、货币等提供国际化支持,提供了强大的 BIDI 算法,对阿拉伯语和希伯来语等 BiDi 语言提供了完善的支持。 ICU 分为 ICU4J 和 ICU4C,分别对应 Java 和 c/c++ 平台。 ICU4J 被 Sun 的 JDK1.1 采用并随 JDK 版本更新。最新的 ICU4J 库可以从 http://icu-project.org/ 网站上下载。

ACCOUNTS

账户表
        db.execSQL("CREATE TABLE " + Tables.ACCOUNTS + " (" + AccountsColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +AccountsColumns.ACCOUNT_NAME + " TEXT, " + //账户名称AccountsColumns.ACCOUNT_TYPE + " TEXT, " + //账户类型AccountsColumns.DATA_SET + " TEXT" + //所属数据集");");

账户类型在ContactsProvider2中针对手机定义了5个,一个本地账户(最常用的账户)和4个卡账户.

    public static final String ACCOUNT_TYPE_LOCAL_PHONE = "Local Phone Account";public static final String ACCOUNT_TYPE_SIM = "SIM Account";public static final String ACCOUNT_TYPE_USIM = "USIM Account";public static final String ACCOUNT_TYPE_UIM = "UIM Account";public static final String ACCOUNT_TYPE_CSIM = "CSIM Account";

data_set 是区分不同同步源的,因为同一个账户的数据是可以被多个数据源备份的。

CONTACTS

联系人表
        db.execSQL("CREATE TABLE " + Tables.CONTACTS + " (" +BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + //对应raw_contacts表中id,用于显示名字Contacts.PHOTO_ID + " INTEGER REFERENCES data(_id)," + //data表中photo相关row的idContacts.PHOTO_FILE_ID + " INTEGER REFERENCES photo_files(_id)," + //对应photo_files表中idContacts.CUSTOM_RINGTONE + " TEXT," + //来电铃声Contacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL  DEFAULT 0," + //标记该联系人来电是否直接转接到语音邮箱Contacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + //联系次数,如拨号会更新该值。Contacts.LAST_TIME_CONTACTED + " INTEGER," + //最后一次联系的时间,如电话、短信等Contacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + //是否为星标联系人Contacts.PINNED + " INTEGER NOT NULL DEFAULT " + PinnedPositions.UNPINNED + "," + //标记在联系人列表中是否订住,订住后滑动列表不会消失Contacts.HAS_PHONE_NUMBER + " INTEGER NOT NULL DEFAULT 0," + //是否有号码Contacts.LOOKUP_KEY + " TEXT," + //lookup_key, 方便在聚合的情况下找到联系人,因为聚合的时候有可能id无效ContactsColumns.LAST_STATUS_UPDATE_ID + " INTEGER REFERENCES data(_id)," + //最后更新的对应data表中的idContacts.CONTACT_LAST_UPDATED_TIMESTAMP + " INTEGER," + //最后更新时间Contacts.SEND_TO_VOICEMAIL_VT + " INTEGER NOT NULL DEFAULT 0," +    //add by MTK 类似SEND_TO_VOICEMAIL,视频通话相关Contacts.SEND_TO_VOICEMAIL_SIP + " INTEGER NOT NULL DEFAULT 0," +   //add by MTK 类似SEND_TO_VOICEMAIL,sip通话相关Contacts.INDICATE_PHONE_SIM + " INTEGER NOT NULL DEFAULT -1," + //add by MTK,是否为卡联系人Contacts.INDEX_IN_SIM + " INTEGER NOT NULL DEFAULT -1," +       //add by MTK 在sim卡中的索引Contacts.FILTER + " INTEGER NOT NULL DEFAULT 0," +              //add by MTK 用于标记该联系人是否可以显示桌面widgetContacts.IS_SDN_CONTACT + " INTEGER NOT NULL DEFAULT 0" +  // add by MTK 是否为sdn联系人");");

表中的每一个row都代表一个联系人,这一个联系人可能在多个账户下都有,对应多个RawContact。例如本地账户、微信和qq都对应一个手机号码,聚合后是一个Contact,有3个RawContact。

SDN (系统拨叫号码) 网络服务拨号。固化的用户不能编辑。见点击打开链接

DELETED_CONTACTS

删除联系人表

        db.execSQL("CREATE TABLE " + ContactsDatabaseHelper.Tables.DELETED_CONTACTS + " (" +ContactsContract.DeletedContacts.CONTACT_ID + " INTEGER PRIMARY KEY," + //删除的联系人idContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP + //删除时间" INTEGER NOT NULL default 0"+ ");");

删除联系人时候并不是直接删除,而是先标记删除的联系人

RAW_CONTACTS

源联系人表

  db.execSQL("CREATE TABLE " + Tables.RAW_CONTACTS + " (" +RawContacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +RawContactsColumns.ACCOUNT_ID + " INTEGER REFERENCES " + //账户id,对应于account表中的idTables.ACCOUNTS + "(" + AccountsColumns._ID + ")," +RawContacts.SOURCE_ID + " TEXT," + //源账户id,例如当前是手机账户id,但是源id是sim卡账户,表示该联系人是从sim卡导入的RawContacts.BACKUP_ID + " TEXT," + //备份源id,唯一的RawContacts.RAW_CONTACT_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + //是否为只读RawContacts.VERSION + " INTEGER NOT NULL DEFAULT 1," + //版本号,每次更新后都会有变化RawContacts.DIRTY + " INTEGER NOT NULL DEFAULT 0," + //VERSION有变化,表示要同步数据RawContacts.DELETED + " INTEGER NOT NULL DEFAULT 0," + //标记该联系人要删除,删除聚合联系人和同步server中的数据,最后再删除数据RawContacts.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + //对应Contacts表中的idRawContacts.AGGREGATION_MODE + " INTEGER NOT NULL DEFAULT " + //聚合模式,解释见后文RawContacts.AGGREGATION_MODE_DEFAULT + "," +RawContactsColumns.AGGREGATION_NEEDED + " INTEGER NOT NULL DEFAULT 1," + //标记是否要聚合RawContacts.CUSTOM_RINGTONE + " TEXT," + //铃声RawContacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + //标记该联系人来电后是否要直接转到语音邮箱RawContacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + //联系次数RawContacts.LAST_TIME_CONTACTED + " INTEGER," + //最后联系时间点RawContacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + //是否为星标联系人RawContacts.PINNED + " INTEGER NOT NULL DEFAULT "  + PinnedPositions.UNPINNED + //是否在列表中“订住”"," + RawContacts.DISPLAY_NAME_PRIMARY + " TEXT," + //名字,名在前,RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT," + //名字,姓在前RawContacts.DISPLAY_NAME_SOURCE + " INTEGER NOT NULL DEFAULT " + //名字源,解释见后文DisplayNameSources.UNDEFINED + "," +RawContacts.PHONETIC_NAME + " TEXT," + //名字对应的语音序列,如汉字对应的拼音RawContacts.PHONETIC_NAME_STYLE + " TEXT," + //语音序列类型,解释见后文RawContacts.SORT_KEY_PRIMARY + " TEXT COLLATE " + //排序字段ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," +RawContactsColumns.PHONEBOOK_LABEL_PRIMARY + " TEXT," + //名字首对应首字母,这个是为了归类名字到26个字母。RawContactsColumns.PHONEBOOK_BUCKET_PRIMARY + " INTEGER," + //名字对应首字母对应的序号,如字母D对应4,RawContacts.SORT_KEY_ALTERNATIVE + " TEXT COLLATE " + //姓在前名字排序字段ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," +RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE + " TEXT," +  //类似PHONEBOOK_LABEL_PRIMARYRawContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + " INTEGER," + //类似PHONEBOOK_BUCKET_PRIMARYRawContactsColumns.NAME_VERIFIED_OBSOLETE + " INTEGER NOT NULL DEFAULT 0," + //这个字段目前已不用RawContacts.SYNC1 + " TEXT, " + //同步要用的字段RawContacts.SYNC2 + " TEXT, " +RawContacts.SYNC3 + " TEXT, " +RawContacts.SYNC4 + " TEXT, " +RawContacts.TIMESTAMP + " INTEGER," +                               //add by MTK ,VERSION变化时间点RawContacts.SEND_TO_VOICEMAIL_VT + " INTEGER NOT NULL DEFAULT 0," + // add by MTK,后续同Contacts表中解释RawContacts.SEND_TO_VOICEMAIL_SIP + " INTEGER NOT NULL DEFAULT 0," + // add by MTKRawContacts.INDICATE_PHONE_SIM + " INTEGER NOT NULL DEFAULT -1," +  //add by MTKRawContacts.INDEX_IN_SIM + " INTEGER NOT NULL DEFAULT -1," +        //add by MTKRawContacts.IS_SDN_CONTACT + " INTEGER NOT NULL DEFAULT 0" +  // add by MTK");");

这个表中的每一个row对应于一个账户的数据,如果用户只使用一个本地手机账户的话,实际上就是一个RawContact对应一个Contact。

AGGREGATION_MODE

        public static final int AGGREGATION_MODE_DEFAULT = 0; //不覆盖之前设置的模式public static final int AGGREGATION_MODE_IMMEDIATE = 1; //插入或者更新时马上合并public static final int AGGREGATION_MODE_SUSPENDED = 2; //暂缓合并,例如批量插入时先不合并,插入完毕后再统一合并public static final int AGGREGATION_MODE_DISABLED = 3; //不合并

DISPLAY_NAME_SOURCE

    public interface DisplayNameSources {public static final int UNDEFINED = 0; public static final int EMAIL = 10; //电子邮件public static final int PHONE = 20; //电话public static final int ORGANIZATION = 30; //公司public static final int NICKNAME = 35; //昵称public static final int STRUCTURED_NAME = 40; //名字}

PHONETIC_NAME_STYLE

   public interface PhoneticNameStyle {public static final int UNDEFINED = 0;public static final int PINYIN = 3; //中文public static final int JAPANESE = 4; //日文public static final int KOREAN = 5; //朝鲜文}

STREAM_ITEMS

steam item表
        db.execSQL("CREATE TABLE " + Tables.STREAM_ITEMS + " (" +StreamItems._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +StreamItems.RAW_CONTACT_ID + " INTEGER NOT NULL, " + //对应的RawContact IdStreamItems.RES_PACKAGE + " TEXT, " +  //相关程序包名StreamItems.RES_ICON + " TEXT, " + //相关程序的图标StreamItems.RES_LABEL + " TEXT, " + //相关程序名,例如“Google Talk”StreamItems.TEXT + " TEXT, " + //信息字符串,例如朋友圈的内容StreamItems.TIMESTAMP + " INTEGER NOT NULL, " + //时间戳StreamItems.COMMENTS + " TEXT, " + //摘要信息,例如Text已被几人读过StreamItems.SYNC1 + " TEXT, " + //同步需要的字段StreamItems.SYNC2 + " TEXT, " +StreamItems.SYNC3 + " TEXT, " +StreamItems.SYNC4 + " TEXT, " +"FOREIGN KEY(" + StreamItems.RAW_CONTACT_ID + ") REFERENCES " +Tables.RAW_CONTACTS + "(" + RawContacts._ID + "));");

这个表是Deprecated,不会使用。从注释看是为聊天工具准备的,记录聊天工具最新的信息。

STREAM_ITEM_PHOTOS

steam photo表
        db.execSQL("CREATE TABLE " + Tables.STREAM_ITEM_PHOTOS + " (" +StreamItemPhotos._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +StreamItemPhotos.STREAM_ITEM_ID + " INTEGER NOT NULL, " + //对应的stream item idStreamItemPhotos.SORT_INDEX + " INTEGER, " +  //排序字段StreamItemPhotos.PHOTO_FILE_ID + " INTEGER NOT NULL, " + //头像文件idStreamItemPhotos.SYNC1 + " TEXT, " +StreamItemPhotos.SYNC2 + " TEXT, " +StreamItemPhotos.SYNC3 + " TEXT, " +StreamItemPhotos.SYNC4 + " TEXT, " +"FOREIGN KEY(" + StreamItemPhotos.STREAM_ITEM_ID + ") REFERENCES " +Tables.STREAM_ITEMS + "(" + StreamItems._ID + "));");

这个表是Deprecated,不会使用。记录stream item中的头像信息

PHOTO_FILES

头像表
        db.execSQL("CREATE TABLE " + Tables.PHOTO_FILES + " (" +PhotoFiles._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +PhotoFiles.HEIGHT + " INTEGER NOT NULL, " +  //高PhotoFiles.WIDTH + " INTEGER NOT NULL, " +  //宽PhotoFiles.FILESIZE + " INTEGER NOT NULL);"); //文件大小

PACKAGES

包名表
        db.execSQL("CREATE TABLE " + Tables.PACKAGES + " (" +PackagesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +PackagesColumns.PACKAGE + " TEXT NOT NULL" + //包名");");

id 和包名对照表,依据id获取包名

MIMETYPES

mime类型表
        db.execSQL("CREATE TABLE " + Tables.MIMETYPES + " (" +MimetypesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +MimetypesColumns.MIMETYPE + " TEXT NOT NULL" +");");

百度百科:MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。它是一个互联网标准,扩展了电子邮件标准.
这张表记录了data所有对象的类型,依据该类型可以区分每个row数据是什么。这些类型全部在ContactsContract中已CONTENT_ITEM_TYPE定义,例如Phone中的:

            /** MIME type used when storing this in data table. */public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone_v2";

标记该类型数据是电话号码
StructuredName中
            /** MIME type used when storing this in data table. */public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/name";

标记该类型数据是名字

DATA

数据表
 db.execSQL("CREATE TABLE " + Tables.DATA + " (" +Data._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +DataColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + //插入数据的程序包名idDataColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + //mime类型idData.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," +  //所属的RawContact IdData.HASH_ID + " TEXT," + //哈希值,用于恢复和备份数据Data.IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + //是否只读Data.IS_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + //标记为联系人的主要属性Data.IS_SUPER_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + //标记为联系人聚合后的主要属性,IS_SUPER_PRIMARY的前提是IS_PRIMARY为trueData.DATA_VERSION + " INTEGER NOT NULL DEFAULT 0," + //版本号Data.DATA1 + " TEXT," + //数据Data.DATA2 + " TEXT," +Data.DATA3 + " TEXT," +Data.DATA4 + " TEXT," +Data.DATA5 + " TEXT," +Data.DATA6 + " TEXT," +Data.DATA7 + " TEXT," +Data.DATA8 + " TEXT," +Data.DATA9 + " TEXT," +Data.DATA10 + " TEXT," +Data.DATA11 + " TEXT," +Data.DATA12 + " TEXT," +Data.DATA13 + " TEXT," +Data.DATA14 + " TEXT," +Data.DATA15 + " TEXT," +Data.SYNC1 + " TEXT, " + //同步需要的字段Data.SYNC2 + " TEXT, " +Data.SYNC3 + " TEXT, " +Data.SYNC4 + " TEXT, " +Data.CARRIER_PRESENCE + " INTEGER NOT NULL DEFAULT 0," + //目前只有一个可选值,标记是否可以视频通话Data.SIM_ASSOCIATION_ID + " INTEGER NOT NULL DEFAULT -1, " +    //add by MTK 卡联系人相关的sub_idData.IS_ADDITIONAL_NUMBER + " INTEGER NOT NULL DEFAULT 0 " +    //add by MTK 作用未知");");

DATA1~DATA15依据mime类型的不同有不同的意义,例如mime是名字:

private interface RawContactNameQuery {...public static final int DATA1 = 2;                              //全名public static final int GIVEN_NAME = 3;                         // data2 名public static final int FAMILY_NAME = 4;                        // data3 姓public static final int PREFIX = 5;                             // data4 前缀public static final int TITLE = 5;                              // data4 头衔public static final int MIDDLE_NAME = 6;                        // data5 中间名public static final int SUFFIX = 7;                             // data6 后缀public static final int PHONETIC_GIVEN_NAME = 8;                // data7 姓的语音字符序列public static final int PHONETIC_MIDDLE_NAME = 9;               // data8 中间名语音字符序列public static final int ORGANIZATION_PHONETIC_NAME = 9;         // data8 公司名语音字符序列public static final int PHONETIC_FAMILY_NAME = 10;              // data9 姓语音字符序列public static final int FULL_NAME_STYLE = 11;                   // data10 名字类型,解释如下public static final int ORGANIZATION_PHONETIC_NAME_STYLE = 11;  // data10public static final int PHONETIC_NAME_STYLE = 12;               // data11}

PHONETIC_NAME_STYLE之前已介绍,FULL_NAME_STYLE 如下定义:

   public interface FullNameStyle {public static final int UNDEFINED = 0;public static final int WESTERN = 1;/*** Used if the name is written in Hanzi/Kanji/Hanja and we could not determine* which specific language it belongs to: Chinese, Japanese or Korean.*/public static final int CJK = 2;public static final int CHINESE = 3;public static final int JAPANESE = 4;public static final int KOREAN = 5;}

PHONE_LOOKUP

号码查找表
        db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" +PhoneLookupColumns.DATA_ID+ " INTEGER REFERENCES data(_id) NOT NULL," + //对应data表中的idPhoneLookupColumns.RAW_CONTACT_ID+ " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + //对应raw_contacts表idPhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," + //号码PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" + //最小匹配号码");");

依据号码查找联系人数据,可见从这个表查找联系人id会少一个步骤。MIN_MATCH字段是号码的倒序,且长度不会超过一定长度(默认是7位,国内是11位)。这个是为了号码匹配,因为号码匹配是从字符串右边开始的,且达到一定位数就认为号码匹配成功,例如+8613812345678和13812345678 是匹配的。

NAME_LOOKUP

名字查找表
        db.execSQL("CREATE TABLE " + Tables.NAME_LOOKUP + " (" +NameLookupColumns.DATA_ID+ " INTEGER REFERENCES data(_id) NOT NULL," +NameLookupColumns.RAW_CONTACT_ID+ " INTEGER REFERENCES raw_contacts(_id) NOT NULL," +NameLookupColumns.NORMALIZED_NAME + " TEXT NOT NULL," +NameLookupColumns.NAME_TYPE + " INTEGER NOT NULL," +"PRIMARY KEY ("+ NameLookupColumns.DATA_ID + ", "+ NameLookupColumns.NORMALIZED_NAME + ", "+ NameLookupColumns.NAME_TYPE + ")" +");");

按名字查找联系人,其它字段同号码查找表类似,其中NAME_TYPE

        public static final int NAME_EXACT = 0;//名字public static final int NAME_VARIANT = 1; //名字变体,就是token的所有顺序public static final int NAME_COLLATION_KEY = 2; //为了排序public static final int NICKNAME = 3; //昵称public static final int EMAIL_BASED_NICKNAME = 4; //邮箱地址

名字插入的时候会生成这五种类型的数据到表中,前三中是基于名字的,后两种是从数据库表中查询生成的。这里注意代码中的NickName有两种情况,NICKNAME类型对应的是Nickname.CONTENT_ITEM_TYPE类型的data表中的数据,而packages/providers/ContactsProvider/src/com/android/providers/contacts/aggregation/util/CommonNicknameCache.java中的NickName对应的是常用英文名的缩写,如"Robert", "Bob" and "Rob"是一个意思,这部分的字符串替换是算在NAME_VARIANT类型中的

NICKNAME_LOOKUP

昵称表
        db.execSQL("CREATE TABLE " + Tables.NICKNAME_LOOKUP + " (" +NicknameLookupColumns.NAME + " TEXT," + //名字NicknameLookupColumns.CLUSTER + " TEXT" + //名字对应id");");

这个是被framework中的资源初始化的

    private void loadNicknameLookupTable(SQLiteDatabase db) {db.execSQL("DELETE FROM " + Tables.NICKNAME_LOOKUP);String[] strings = mContext.getResources().getStringArray(com.android.internal.R.array.common_nicknames);...}

该字符串定义在frameworks/base/core/res/res/values-en-rUS/donottranslate-names.xml中

 <string-array name="common_nicknames"><item>Abigail, Abbie</item><item>Abigail, Gail, Gayle</item><item>Abe, Abraham</item>...

可以看出每行数据定义了等价的名字,同一行的名字有相同的id

GROUPS

群组表
        db.execSQL("CREATE TABLE " + Tables.GROUPS + " (" +Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +GroupsColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + //对应package表中的idGroupsColumns.ACCOUNT_ID + " INTEGER REFERENCES " + //对应account表中的idTables.ACCOUNTS + "(" + AccountsColumns._ID + ")," +Groups.SOURCE_ID + " TEXT," + //源账户idGroups.VERSION + " INTEGER NOT NULL DEFAULT 1," + //版本号Groups.DIRTY + " INTEGER NOT NULL DEFAULT 0," + //是否要同步Groups.TITLE + " TEXT," + //群组名Groups.TITLE_RES + " INTEGER," + //群组名资源idGroups.NOTES + " TEXT," + //备注Groups.SYSTEM_ID + " TEXT," + //系统群组id,对同步有重要意义,从代码中看有系统id的GROUP_IS_READ_ONLY都会设置为1Groups.DELETED + " INTEGER NOT NULL DEFAULT 0," + //标记是否删除Groups.GROUP_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + //是否可见Groups.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1," + //当SYNC_EVERYTHING设置为false的时候,是否同步Groups.AUTO_ADD + " INTEGER NOT NULL DEFAULT 0," + //新建联系人后是否自动添加到该群组Groups.FAVORITES + " INTEGER NOT NULL DEFAULT 0," + //星标联系人是否自动添加到该群组Groups.GROUP_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + //是否只读Groups.SYNC1 + " TEXT, " + //同步字段Groups.SYNC2 + " TEXT, " +Groups.SYNC3 + " TEXT, " +Groups.SYNC4 + " TEXT " +");");

AGGREGATION_EXCEPTIONS

聚合规则表
        db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.AGGREGATION_EXCEPTIONS + " (" +AggregationExceptionColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +AggregationExceptions.TYPE + " INTEGER NOT NULL, " +AggregationExceptions.RAW_CONTACT_ID1+ " INTEGER REFERENCES raw_contacts(_id), " +AggregationExceptions.RAW_CONTACT_ID2+ " INTEGER REFERENCES raw_contacts(_id)" +");");

类型有三种:

        public static final int TYPE_AUTOMATIC = 0; //自动聚合public static final int TYPE_KEEP_TOGETHER = 1; //聚合public static final int TYPE_KEEP_SEPARATE = 2; //不聚合

另外两个字段是两个RawContact Id.

这个表可以添加联系人聚合的规则,联系人聚合时会参照这个规则。这个表的最大用处是手动合并联系人。

SETTINGS

设置表
        db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.SETTINGS + " (" +Settings.ACCOUNT_NAME + " STRING NOT NULL," + //账户名称Settings.ACCOUNT_TYPE + " STRING NOT NULL," + //账户类型Settings.DATA_SET + " STRING," + //标记同步源,一个数据库可备份到多处Settings.UNGROUPED_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + //不再群组内的联系人是否可见Settings.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1" + //是否启用同步,这个是最高等级的开关");");

VISIBLE_CONTACTS

可见联系人表

        db.execSQL("CREATE TABLE " + Tables.VISIBLE_CONTACTS + " (" +Contacts._ID + " INTEGER PRIMARY KEY" +");");

只有一个字段,可见联系人的id

DEFAULT_DIRECTORY

默认通讯录表
        db.execSQL("CREATE TABLE " + Tables.DEFAULT_DIRECTORY + " (" +Contacts._ID + " INTEGER PRIMARY KEY" +");");

无账户和无群组的联系人的id都会插入到这个表中

CALLS

见通话记录

VOICEMAIL_STATUS

语音邮箱状态表
        db.execSQL("CREATE TABLE " + Tables.VOICEMAIL_STATUS + " (" +VoicemailContract.Status._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +VoicemailContract.Status.SOURCE_PACKAGE + " TEXT UNIQUE NOT NULL," + //VoicemailContract.Status.PHONE_ACCOUNT_COMPONENT_NAME + " TEXT," + //phone进程的包名VoicemailContract.Status.PHONE_ACCOUNT_ID + " TEXT," +  //实际就是sim卡的subidVoicemailContract.Status.SETTINGS_URI + " TEXT," + //action view加上这个uri的intent可以拉起设置界面VoicemailContract.Status.VOICEMAIL_ACCESS_URI + " TEXT," + //获取语音邮件VoicemailContract.Status.CONFIGURATION_STATE + " INTEGER," + //设置状态,解释见下VoicemailContract.Status.DATA_CHANNEL_STATE + " INTEGER," +  //数据连接状态VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE + " INTEGER" + //通知连接状态");");

CONFIGURATION_STATE

        public static final int CONFIGURATION_STATE_OK = 0;public static final int CONFIGURATION_STATE_NOT_CONFIGURED = 1;public static final int CONFIGURATION_STATE_CAN_BE_CONFIGURED = 2;

DATA_CHANNEL_STATE

        public static final int DATA_CHANNEL_STATE_OK = 0;public static final int DATA_CHANNEL_STATE_NO_CONNECTION = 1;

NOTIFICATION_CHANNEL_STATE

        public static final int NOTIFICATION_CHANNEL_STATE_OK = 0;public static final int NOTIFICATION_CHANNEL_STATE_NO_CONNECTION = 1;

STATUS_UPDATES

状态表
        db.execSQL("CREATE TABLE " + Tables.STATUS_UPDATES + " (" +StatusUpdatesColumns.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," +StatusUpdates.STATUS + " TEXT," + //状态StatusUpdates.STATUS_TIMESTAMP + " INTEGER," + //时间戳StatusUpdates.STATUS_RES_PACKAGE + " TEXT, " + //提供资源的包名StatusUpdates.STATUS_LABEL + " INTEGER, " + //状态资源idStatusUpdates.STATUS_ICON + " INTEGER" + //状态图标id");");

这个转门指通讯工具(例如Google Talk)的状态,例如在线,隐身等。

DIRECTORIES

通讯录表
        db.execSQL("CREATE TABLE " + Tables.DIRECTORIES + "(" +Directory._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +Directory.PACKAGE_NAME + " TEXT NOT NULL," +Directory.DIRECTORY_AUTHORITY + " TEXT NOT NULL," + Directory.TYPE_RESOURCE_ID + " INTEGER," +DirectoryColumns.TYPE_RESOURCE_NAME + " TEXT," +Directory.ACCOUNT_TYPE + " TEXT," +Directory.ACCOUNT_NAME + " TEXT," +Directory.DISPLAY_NAME + " TEXT, " +Directory.EXPORT_SUPPORT + " INTEGER NOT NULL" + //后面详细解释" DEFAULT " + Directory.EXPORT_SUPPORT_NONE + "," +Directory.SHORTCUT_SUPPORT + " INTEGER NOT NULL" +" DEFAULT " + Directory.SHORTCUT_SUPPORT_NONE + "," +Directory.PHOTO_SUPPORT + " INTEGER NOT NULL" +" DEFAULT " + Directory.PHOTO_SUPPORT_NONE +");");

Directory表示一个集合,例如ContactsProvider默认会添加两个Directory,一个就是之前介绍的的DEFAULT,还有一个是LOCAL_INVISIBLE

        /*** _ID of the default directory, which represents locally stored contacts.*/public static final long DEFAULT = 0;/*** _ID of the directory that represents locally stored invisible contacts.*/public static final long LOCAL_INVISIBLE = 1;

除了这两个外,还可以在其他app中实现DirectoryProvider,ContactsProvider会扫描所有的apk,发现AndroidManifest中有

<meta-data android:name="android.content.ContactDirectory"  android:value="true"/>

都会认为该app是一个DirectoryProvider,ContactsProvider收到相应请求会转发到相应 AUTHORITY的DirectoryProvider去。

EXPORT_SUPPORT

        public static final int EXPORT_SUPPORT_NONE = 0; //不支持导出联系人public static final int EXPORT_SUPPORT_SAME_ACCOUNT_ONLY = 1; //只能导出到指定的账户public static final int EXPORT_SUPPORT_ANY_ACCOUNT = 2; //能导出到任何账户

SHORTCUT_SUPPORT

        public static final int SHORTCUT_SUPPORT_NONE = 0; //不支持快捷方式public static final int SHORTCUT_SUPPORT_DATA_ITEMS_ONLY = 1; //只支持单个data itempublic static final int SHORTCUT_SUPPORT_FULL = 2; //支持全部

PHOTO_SUPPORT

       public static final int PHOTO_SUPPORT_NONE = 0; //不支持头像public static final int PHOTO_SUPPORT_THUMBNAIL_ONLY = 1;  //小头像public static final int PHOTO_SUPPORT_FULL_SIZE_ONLY = 2; //大头像public static final int PHOTO_SUPPORT_FULL = 3; //全部支持

DirectoryProvider是针对三方app有自己的联系人数据,想通过Android标准的联系人查询供其它app使用,但是又不暴露自己的数据库实现,那么就按Android的标准实现一个DirectoryProvider。

SEARCH_INDEX

搜索表
            db.execSQL("CREATE VIRTUAL TABLE " + Tables.SEARCH_INDEX+ " USING FTS4 ("+ SearchIndexColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id) NOT NULL,"+ SearchIndexColumns.CONTENT + " TEXT, " //公司、备注等其它信息+ SearchIndexColumns.NAME + " TEXT, " //名字+ SearchIndexColumns.TOKENS + " TEXT" //号码+ ")");

FTS是Full-Text Search,见全文索引,这个大幅度提高了长文的搜索效率。

这里建立虚表是FTS的要求,更详细的见sqlite官方网站点击打开链接。注意使用FTS还会有另外5个表自动建立:
For each FTS virtual table in a database, three to five real (non-virtual) tables are created to store the underlying data. These real tables are called "shadow tables". The real tables are named "%_content", "%_segdir", "%_segments", "%_stat", and "%_docsize", where "%" is replaced by the name of the FTS virtual table.

DIALER_SEARCH

拨号盘搜索表,见MTK的T9搜索流程分析

CONFERENCE_CALLS

会议通话表,mtk添加的表
            db.execSQL("CREATE TABLE " + Tables.CONFERENCE_CALLS + " (" +ConferenceCalls._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +ConferenceCalls.GROUP_ID + " INTEGER REFERENCES groups(_id)," + //对应group idConferenceCalls.CONFERENCE_DATE + " INTEGER " + //日期");");

DATA_USAGE_STAT

data使用情况统计表
        db.execSQL("CREATE TABLE " + Tables.DATA_USAGE_STAT + "(" +DataUsageStatColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +DataUsageStatColumns.DATA_ID + " INTEGER NOT NULL, " + //对应data表的idDataUsageStatColumns.USAGE_TYPE_INT + " INTEGER NOT NULL DEFAULT 0, " + //类型,解释见下DataUsageStatColumns.TIMES_USED + " INTEGER NOT NULL DEFAULT 0, " + // 使用次数DataUsageStatColumns.LAST_TIME_USED + " INTERGER NOT NULL DEFAULT 0, " + //最后一次使用的时间"FOREIGN KEY(" + DataUsageStatColumns.DATA_ID + ") REFERENCES "+ Tables.DATA + "(" + Data._ID + ")" +");");

USAGE_TYPE_INT

        public static final String USAGE_TYPE_CALL = "call"; //通话public static final String USAGE_TYPE_LONG_TEXT = "long_text"; //长的文本通信,例如电子邮件public static final String USAGE_TYPE_SHORT_TEXT = "short_text"; //短的文本通信,例如短信

PRE_AUTHORIZED_URIS

权限表
        db.execSQL("CREATE TABLE " + Tables.PRE_AUTHORIZED_URIS + " ("+PreAuthorizedUris._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +PreAuthorizedUris.URI + " STRING NOT NULL, " +PreAuthorizedUris.EXPIRATION + " INTEGER NOT NULL DEFAULT 0);");

这个表用于app获取权限,与Context.grantUriPermission不同的是它不用在代码中指明要获取什么权限,授权后5分钟内可以查询数据,5分钟后权限过期。这个表的详细用法见ContactsContract中的Authorization类。

PRESENCE

        db.execSQL("ATTACH DATABASE ':memory:' AS " + DATABASE_PRESENCE + ";");db.execSQL("CREATE TABLE IF NOT EXISTS " + DATABASE_PRESENCE + "." + Tables.PRESENCE + " ("+StatusUpdates.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + //对应data表中的idStatusUpdates.PROTOCOL + " INTEGER NOT NULL," + //协议常量StatusUpdates.CUSTOM_PROTOCOL + " TEXT," + //订制协议名称StatusUpdates.IM_HANDLE + " TEXT," + //和协议相关StatusUpdates.IM_ACCOUNT + " TEXT," + //IM账号PresenceColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + //对应contacts idPresenceColumns.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + //对应raw_contacts idStatusUpdates.PRESENCE + " INTEGER," + //im的在线状态,解释见下StatusUpdates.CHAT_CAPABILITY + " INTEGER NOT NULL DEFAULT 0," + //通话能力,解释见下"UNIQUE(" + StatusUpdates.PROTOCOL + ", " + StatusUpdates.CUSTOM_PROTOCOL+ ", " + StatusUpdates.IM_HANDLE + ", " + StatusUpdates.IM_ACCOUNT + ")" + ");");

这个表和AGGREGATED_PRESENCE都是在内存数据库中,在设备中并没有对应文件,进程关闭后表就消失,进程开启后表创建。

IM即使通讯,例如Google Talk。这个表主要是记录IM的在线状态
PRESENCE
        int OFFLINE = 0; //不在线int INVISIBLE = 1; //隐身int AWAY = 2; //离开int IDLE = 3; //空闲int DO_NOT_DISTURB = 4; //勿扰int AVAILABLE = 5; //在线
CHAT_CAPABILITY
        public static final int CAPABILITY_HAS_VOICE = 1; //语音public static final int CAPABILITY_HAS_VIDEO = 2; //视频public static final int CAPABILITY_HAS_CAMERA = 4; //有前置摄像头

AGGREGATED_PRESENCE

        db.execSQL("CREATE TABLE IF NOT EXISTS "+ DATABASE_PRESENCE + "." + Tables.AGGREGATED_PRESENCE + " ("+AggregatedPresenceColumns.CONTACT_ID+ " INTEGER PRIMARY KEY REFERENCES contacts(_id)," +StatusUpdates.PRESENCE + " INTEGER," +StatusUpdates.CHAT_CAPABILITY + " INTEGER NOT NULL DEFAULT 0" +");");

字段同PRESENCE表。这个表的修改都在AbstractContactAggregator中,为了聚合联系人。

联系人存储ContactsProvider表分析相关推荐

  1. oracle表分析 示例

    drop table test; select count(*) from test; --创建测试表 create table test ( id number(9), nick varchar2( ...

  2. oracle表分析都分析什么,oracle表分析

    analyze table tablename compute statistics; analyze index indexname compute statistics; 对于使用CBO很有好处, ...

  3. MySQL存储引擎 lnnoDB逻辑架构 innodb存储引擎表空间(ibd文件)详解 回滚日志的物理空间

    文章目录 存储引擎 一 MySQL组织架构 二 查看存储引擎信息 三 修改存储引擎 3.1 配置文件修改存储引擎 3.2 临时修改存储引擎 3.3 建表时修改存储引擎 四 存储引擎实验 五 数据库升级 ...

  4. ORACLE的CBO及表分析

    最近接触到了表分析的几个案例,有一张表经过分析之后,在上面的sql语句的执行时间一下子从50分钟锐减到2分钟,不可思议. 第一部分 什么是表分析?简单的说,就是收集表和索引的信息,CBO根据这些信息决 ...

  5. 1、交换机ARP缓存表分析

    1.交换机ARP缓存表分析 一.用模拟器不是一个简单的拓扑:   拓扑简单描述:交换机不做任何配置,两台电脑使用arp -a命令查看混存表,均为空. 操作1:PC A 去ping  PC B: 10. ...

  6. MySQL存储写入速度慢分析

    问题背景描述:在MySQL中执行SQL语句,比如insert,贼慢,明明可能也就只是一行数据的插入,数据量很小,但是耗费的时间却很多,为什么? 一.存储结构分析 MySQL存储结构图: 解析: 1.读 ...

  7. 实验8-SPSS交叉表分析

    SPSS---交叉表分析 除了对单个变量的分析,在实际研究中,还需要对多个变量在不同取值情况下的数据分布情况,从而进一步分析变量之间的相互影响和关系,这就要用到交叉表分析. 交叉表是一种行列交叉的分类 ...

  8. mysql技术内幕innodb存储引擎——表索引算法和锁_(转)Mysql技术内幕InnoDB存储引擎-表索引算法和锁...

    表 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC% ...

  9. mysql 硬盘写入速度_MySQL存储写入速度慢分析

    原标题:MySQL存储写入速度慢分析 一.存储结构分析 MySQL存储结构图: 解析: 1.读操作:内存读-->cache缓存读-->磁盘物理读 读取到的数据会按上述顺序往回送. 2.写操 ...

  10. 权限控制相关数据表分析和创建

    权限控制相关数据表分析和创建 实体类分析:包含用户.角色.权限三大块 用户User,角色Role,权限Permission 为了方便进行动态的菜单管理,也就是不同权限用户进入到后台系统所看到的菜单是不 ...

最新文章

  1. 程序模拟电影院窗口卖票,多线程Demo
  2. js中的事件委托或是事件代理详解(转载)
  3. 一个登录框实现不同的登录验证
  4. 构造一个完美的分类系统
  5. 64位百度云 catia v6_逃狱兄弟百度云资源已更新,1080P高清资源分享64
  6. SharePoint v3:忘掉模拟用户Impersonate,SPSecurity.RunWithElevatedPrivileges来了
  7. python试卷河南理工大学万方科技学院_河南理工大学万方科技学院
  8. 信息学奥赛一本通 1226:装箱问题 | OpenJudge NOI 4.6 19:装箱问题
  9. Webpack3 从入门到放弃
  10. 西门子滚筒洗衣机教程_西门子洗衣机优缺点
  11. 企业实战——Ansible自动化运维基础知识
  12. 世界500强面试推理题求答案
  13. 程序员5大热门发展行业,就业迷茫的同学注意啦!
  14. 程序员怎么做可以安全通过试用期
  15. 5V转3V的降压芯片和LDO
  16. 机器视觉halcon——距离测量
  17. 【论文笔记】Heterogeneous Transfer Learning for HSIC Based on CNN
  18. 2019上半年阿里,腾讯,百度,美团,头条等技术面试题目,以及答案,专家出题人分析汇总...
  19. Android加速度传感器原理
  20. 信息收集(四)服务器信息收集

热门文章

  1. vivado 开发教程(三) 在SDK中创建应用工程
  2. vivado 开发教程(一) 创建新硬件工程
  3. 阿里云怎么启动mysql_阿里云启动mysql
  4. 微信小程序系列(3)如何用微信小程序写一个论坛?贴心代码详解(一)发帖
  5. 河南大学软件学院宿舍楼综合布线设计方案
  6. Opening My World——ESRI用户大会有感
  7. 用python写网络爬虫-英文翻译
  8. 如何在谷歌浏览器官网下载谷歌浏览器32位、64位或其他版本最新的离线安装包?
  9. tableau参数_Tableau-参数的设置方法
  10. win7下虚拟显示器完成记(virtual monitor)——VDI显卡透传场景