Android联系人模块分析参考文档

javaboy_lgl 贡献于2013-02-27

作者 songhu  创建于2011-05-13 01:21:00   修改者fr  修改于2012-07-04 02:15:00字数8683

文档摘要:简介本文基于MTK6516代码进行分析联系人模块的功能及数据库操作的流程。联系人是手机功能中不可缺少的模块,主要记录用户的联系人数据,方便用户快捷的操作和使用,主要包括本机联系人和Sim卡联系人。本机联系人主要存储在手机内部存储空间,Android平台上是通过数据库(Provider)进行存储,并提供复杂的字段用于表示联系人数据,并提供用户快捷的操作,比如增加,删除,修改,查询等等。Sim卡联系人主要存储在Sim卡内部存储文件,包括adn、fdn、sdn。主要提供简单的字段用于表示联系人数据。并通过IccProvider提供的接口进行数据的增加、删除、修改、查询操作。
关键词:

 联系人功能分析 目录 1. 简介 3 2. 软件结构分析 3 2.1 Contacts模块 3 2.2 ContactsProvider模块 4 2.2.1 数据库创建 5 2.2.2 数据库操作 7 1. 简介 本文基于MTK6516代码进行分析联系人模块的功能及数据库操作的流程。 联系人是手机功能中不可缺少的模块,主要记录用户的联系人数据,方便用户快捷的操作和使用,主要包括本机联系人和Sim卡联系人。 本机联系人主要存储在手机内部存储空间,Android平台上是通过数据库(Provider)进行存储,并提供复杂的字段用于表示联系人数据,并提供用户快捷的操作,比如增加,删除,修改,查询等等。 Sim卡联系人主要存储在Sim卡内部存储文件,包括adn、fdn、sdn。主要提供简单的字段用于表示联系人数据。并通过IccProvider提供的接口进行数据的增加、删除、修改、查询操作。在IccProvider 中通过IIccPhoneBook的子类中实现的方法查询相关信息,IIccPhoneBook是一个AIDL服务类,通过IIccPhoneBook.Stub.asInterface(ServiceManager.getService("simphonebook")); 获得一个能操作sim卡数据的代理服务对象。 目前会根据Sim卡的实时状态,将Sim卡联系人整合到本地联系人数据库中,方便用户使用。 2.软件结构分析 联系人应用主要包括两个部分: 1. Contacts主要响应用户的请求和交互,数据显示。 2. ContactsProvider主要提供数据存储和数据结构 两者之间的主要交互流程如下图: 2.1 Contacts模块 Contacts主要提供联系人列表显示、增删改、查找、显示选项、导入导出,数据同步和SNS整合、分享联系人、桌面快捷方式和文件夹、快捷操作、其他应用获取数据。 导入导出主要有导出到SD卡,从SD卡导入,从SIM导入。SD卡导入导出主要是通过vCard的形式,存储到sd卡或者从sd卡读取指定的vCard文件并进行解析。Sim导入主要是通过IccProvider的query方法将Sim卡联系人读取出来,用户可以选择全部导入或者导入指定的Sim卡联系人。目前不支持导出到Sim卡。 全局搜索主要包括提供number和name(不至是display name,还包括邮箱名、公司名、公司职位等)搜索。主要方便用户查询,对于number方式的查询,如果联系人中无法找到,则会出现添加到联系人的选项。Name方式的查找,如果联系人中无法找到,则显示空。 Sim卡联系人整合:实时获得Sim卡的状态,对Sim上的联系人导入到本地数据库,或者将本地数据中Sim卡联系人删除。数据库Contacts表和raw_Contacts表表中有字段indicate_phone_or_sim_contact表示是否为Sim卡联系人,并区分出Sim1,Sim2上的联系人。 Google/Exchange服务整合:通过添加Google帐号,并开启同步,则会将Gmail中联系人同步到本地数据库,也可以将本地联系人同步到Gmail中。而且也支持Exchange服务帐号同步。 SNS整合:主要通过开放的API接口实现和RenRen、KaiXin的整合,用户可以同步联系人和新鲜事。 分享:用户主要通过蓝牙、Email等方式,将联系人以vCard的形式分享给别人。 桌面快捷方式和文件夹:在Launcher桌面创建快捷方式或者桌面文件件,用户可以快捷的进行操作。 其他应用获取数据:主要打电话、来电、短信、邮件等应用,获取联系人数据信息,进行各自的显示或操作。 2.2 ContactsProvider模块 ContactsProvider模块是联系人应用的数据基础,响应UI的请求,组织和管理数据。ContactsProvider模块中主要有ContactsProvider,CallLogProvider,SocialProvider三个provider,其中ContactsProvider处理联系人数据,操作raw_contacts, contacts, accounts, agg_exception, data, group, mimetypes, name_lookup, phone_lookup, settings, v1_settings数据表。CallLogProvider主要处理通话记录,操作calls 表。SocialProvider主要处理社交整合的数据,操作activitys和status_updates表。 2.2.1 数据库创建 数据库的创建主要通过ContactsDatabaseHelper和LegacyApiSupport来进行创建。当用户调用ContactsDatabaseHelper的OnCreate之后,先完成自己模块内定义的操作,然后执行LegacyApiSupport中的crateDatabase()。 SyncState创建的数据库,主要创建_sync_state和_sync_state_metadata表,主要用于同步时,状态的记录。 ContactsDatabaseHelper创建数据表及索引,主要创建contacts, raw_contacts, packages, mimetypes, data, phone_lookup, name_lookup, nickname_lookup, groups, agg_exceptions, settings, calls, activities, status_updates, properties, accounts。索引是针对某个表而建立的,只会影响数据表内数据。 ContactsDatabaseHelper创建视图,在本模块主要创建了Contacts,ContactEntities, Data和Groups相关的视图。主要有:view_data,view_data_restricted,view_raw_contacts,,view_raw_contacts_restricted, view_contacts, view_contacts_restricted, view_groups,contact_entities_view,contact_entities_view_restricted。 ContactsDatabaseHelper创建触发器,主要创建了以下几个触发器,具体作用可以参考代码:raw_contacts_deleted,raw_contacts_marked_deleted,data_updated,data_deleted, groups_update1。 ContactsDatabaseHelper加载NicknameLookup数据,首先删除Nickname_lookup表数据,并获取数组 common_nicknames中预定义的数据,然后全部插入到NicknameLookup表。 LegacyApiSupport模块创建数据库,主要完成了两个行为:创建视图和settings表。 LegacyApiSupport模块创建视图,主要有view_v1_people,view_v1_organizations,view_v1_contact_methods, view_v1_phones, view_v1_extensions,view_v1_groups,view_v1_group_membership,view_v1_photos。 LegacyApiSupport模块创建settings表,主要是创建v1_settings数据表。 综上可以得到以下表格,来进行对比。 ContactsDatabaseHelper LegacyApiSupport SyncState Table contacts raw_contacts packages mimetypes data phone_lookup name_lookup nickname_lookup groups agg_exceptions Settings calls activities status_updates, properties accounts v1_settings _sync_state _sync_state_metadata View view_data, view_data_restrict view_raw_contacts view_raw_contacts_restricted view_contacts view_contacts_restricted view_groups contact_entities_view contact_entities_view_restricted view_v1_people view_v1_organizations view_v1_contact_methods view_v1_phones view_v1_extensions view_v1_groups view_v1_group_membership view_v1_photos Trigger raw_contacts_deleted raw_contacts_marked_deleted data_updated data_deleted groups_update1 Other Insert Nickname_lookup data 2.2.2 数据库操作 数据库的操作对于用户来说,无非就是增加、修改、删除、查询,所以本节也主要针对以上几个方面进行讨论和分析。 数据库操作,主要分为两个模块ContactsProvider2和LegacyApiSupport进行处理。用户通过传递参数URL,先匹配ContactsProvider2中定义的URL,如果匹配成功则进行数据操作并返回。如果匹配不成功,则进入LegacyApiSupport中进行匹配,进行数据操作。 数据库涉及到读操作的行为,主要是数据查询,程序直接通过URL匹配查询,返回数据集。 数据库涉及到写操作的行为,主要包括增加、删除、修改,针对多个数据表的操作ContactsProvider采用事务机制,多个数据表的数据的操作全部完成后,统一进行提交。单表操作,则不会使用。 事务机制具体定义如下:{ mDb.beginTransactionWithListener(this) insertInTransaction()/updatnTransaction()/deleteInTransaction() mDb.setTransactionSuccessful() mDb.endTransaction() } 在beginTransactionWithListener中调用onBegin()方法,主要实现了事务处理的前期工作。endTransaction()中调用onCommit()方法,主要根据事务的成功状态,来进行数据提交。 而如何判断是否为多操作,ContactsProvider模块通过在SQLiteContentProvider文件的applyBatch()方法中进行标志变量的设置。 单表操作都是简单通过URL定位匹配,而完成数据库操作,实现上比较简单,就不多作分析。而多表操作,主要都是通过构建ContentProviderOperation数组,涉及到多个表的数据变化。最为常见的则是联系人的增删改,所以将联系人的增删改做主要的分析。联系人数据会涉及到raw_contacts表,contacts表,data表,name_lookup表,phone_lookup表,mimetypes表。 而raw_contacts表会使用contacts表的_id, contacts表会使用raw_contacts表的_id, data表会使用raw_contacts表和mimetypes表的_id, name_lookup表会使用data表和raw_contacts表的_id,phone_lookup表会使用data表和raw_contacts表的_id. 具体关系图如下: 下面将主要描述联系人的增加,删除,修改: l 联系人增加 用户在联系人新增界面,填入需要的联系人信息数据,比如名字,电话号码,电子邮件等信息,用户点击保存时会通过EntitySet.buildDiff()方法进行构造ContentProviderOperation数组,先构造带有RawContacts.CONTENT_URI的数据,然后根据用户输入的数据的mimetype类型,构造带有Data.CONTENT_URI的数据。最后会调用applyBatch()函数进行数据写入。 调用applyBatch()函数过程中,会读取ContentProviderOperation数组,而数组的每一条记录都会带有一个URI,通过匹配URI,找到对应的表进行插入操作。 操作成功后得到返回结果,并对关联数据mValuesBackReferences中的字段值进行更新。 获取mimetype,并根据mimetype类型数据,获得不同的DataRowHandler,进行data数据的写入。(data数据操作具体见Data表数据增加、修改、删除章节) l 联系人修改 用户在联系人编辑界面,更改需要修改的数据,比如名字,电话号码,电子邮件等信息,用户点击保存时会通过EntitySet.buildDiff()方法进行构造ContentProviderOperation数组,先构造带有RawContacts.CONTENT_URI的数据,然后根据用户输入的数据的mimetype类型,构造带有Data.CONTENT_URI的数据。最后会调用applyBatch()函数进行数据更新。 调用applyBatch()函数过程中,会读取ContentProviderOperation数组,而数组的每一条记录都会带有一个URI,通过匹配URI,找到对应的表进行更新操作。操作成功后得到返回结果。 获取mimetype,并根据mimetype类型数据,获得不同的DataRowHandler,进行data数据的更新。(data数据操作具体见Data表数据增加、修改、删除章节) l 联系人删除 用户在联系人列表选择联系人的删除,本地联系人url匹配只是删除contacts表中的数据, 标记raw_contacts表的字段deletde为1,而Data表的数据并没有发生变化。url匹配删除Sim卡联系人或者同步联系人时删除,会直接删除raw_contacts表的数据,并触发触发器raw_contacts_deleted,将data表,agg_exceptions表,contacts表的数据全部删除。 当用户进入到联系人编辑界面,删除某个数据。也就是只对联系人的data数据进行删除,而联系人数据未发生变化,这样会根据删除内容获得ContentProviderOperation数组。最后会调用applyBatch()函数进行数据更新。 调用applyBatch()函数过程中,会读取ContentProviderOperation数组,而数组的每一条记录都会带有一个URI,通过匹配URI,找到对应的表进行删除操作。操作成功后得到返回结果。 最后根据mimetype类型数据,获得不同的DataRowHandler,进行data数据的删除。(data数据操作具体见Data表数据增加、修改、删除章节) l Data表数据增加、修改、删除 前面关于联系人数据的增删改时,最后对data表的操作,都是通过mimetype获得对应类型的DataRowHandler,从而对数据库进行操作。 在ContactsProvider2初始化时,会创建HashMap来装载DataRowHandler,具体常见ContactsProvider2.java中的initDataRowHandlers()函数。但涉及到data数据操作时,会根据其mimetype,获得HashMap中指定的DataRowHanlder,进而执行指定DataRowHanlder中定义的insert,update,delete方法。 目前ContactsProvider主要提供的DataHandlder继承关系图: 1) EmailDataRowHandler 主要处理mimetype为email的data数据。 插入操作:先插入data表,然后获取邮箱地址@前的字符串,并插入到name_lookup表。 修改操作:先更新data表,然后删除name_lookup表中的指定数据,重新获取邮箱地址@前的字符串,并插入到name_lookup表 删除操作:先删除data表,然后删除name_lookup表数据 2) PhoneDataRowHandler 主要处理mimetype为phone的data数据。 插入操作:判断是否包含电话号码,包含的话先插入data表,然后更新phone_lookup表,不包含的话直接插入data表。 修改操作:判断是否包含电话号码,包含的话则更新data表,然后更新phone_lookup表,不包含的话直接更新data表。 删除操作:删除data表数据,更新phone_lookup表为空 3) OrganizeDataHandler 主要处理mimetype为organization的data数据。 插入操作:获取company和title字段值,先插入data表,然后将company和titile分别插入name_lookup表。 修改操作:更新data表,删除name_lookup表数据,重新获取company和title字段值,并将其插入到name_lookup表。 删除操作:删除data表数据,删除name_lookup表 4) NicknameDataRowHandler 主要处理mimetype为nickname的data数据。 插入操作:获取nickname字段值,先插入data表,如果nickname不为空,插入到name_lookup表。 修改操作:更新data表,删除name_lookup表数据,重新获取nickname字段值,并将其插入到name_lookup表。 删除操作:删除data表数据,删除name_lookup表 5) GroupMembershipRowHandler 主要处理mimetype为group_membership的data数据。 插入操作:插入data表,调用更新contacts和raw_contacts表中的contact_in_visible_group字段。 修改操作:更新data表,调用更新contacts和raw_contacts表中的contact_in_visible_group字段。 删除操作:删除data表数据,调用更新contacts和raw_contacts表中的contact_in_visible_group字段。 6) PhotoDataRowHandler 主要处理mimetype为photo的data数据。 插入操作:插入data表,调用更新contacts中的photo_id字段。 修改操作:更新data表,调用更新contacts中的photo_id字段。 删除操作:删除data表数据,调用更新contacts中的photo_id字段。 7) StructedNameRowHandler 主要处理mimetype为name的data数据。 插入操作:插入data表,通过函数insertNameLookupForStructuredName和insertNameLookupForPhoneticName插入name_lookup表两条记录。 修改操作:更新data表,删除name_lookup表数据,并通过调用函数insertNameLookupForStructuredName和insertNameLookupForPhoneticName重新插入name_lookup表两条记录。 删除操作:删除data表数据,删除name_lookup表数据。 8) StructedPostalRowHandler 主要处理mimetype为postal-address的data数据。 插入操作:插入data表。 修改操作:更新data表。 删除操作:删除data表数据。 9) CommonDataRowHandler EmailDataRowHandler、OrganizationDataRowHandler、PhoneDataRowHandler、NicknameDataRowHandler继承与CommonDataRowHandler。 CommonDataRowHandelr主要的数据操作,只是简单的对data表的增加、删除、修改。 10) CustomDataRowHandler CustomDataRowHandler继承与DataRowHandler,主要功能:当用户通过mimetype获取HashMap中加载的handler时,获取的handler为空时,则创建CustomDataRowHandler做为数据处理的handler。 CustomDataRowHandler主要的数据操作,也只是简单的对data表的增加、删除、修改

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享文档获得金币 ] 2 人已下载

下载文档