Android contacts 的详解
一、包結構分析
相關聯的的projects1、Contacts相關
聯系人分為了Contacts和ContactsCommon,與sim卡聯系人相關的是在Telephony中,數據庫是在ContactsProvider,apk要push到/system/priv-app/Contacts下
2、Contacts的包結構
3、ContactsCommon的包結構
二、功能分析
主要介紹一下和聯系人相關的幾個主要的功能,其他簡單的就略過了,具體問題還是需要在code中看。
1、數據庫分析
系統聯系人數據庫存放在如下位置data\data\com.android.providers.contacts\data bases\,正常的聯系人都保存在contacts2.db中,個人信息保存在profile.db,但是兩個數據庫的基本結構都是一樣的
表結構
其中有比較重要的三個表:account、mimetype、data、raw_contacts、contacts,其他的表結構用的較少,遇到問題再去ContactsProvider中查看code。
幾張表直接的主要關聯關系
Account是和賬號有關
data表中存放的是聯系人具體信息,每行存儲一位聯系人的某一類信息(如電話,姓名,郵箱、社交賬號、地址等)
其中數據存放在dataX(x為數字)中,根據這行的mimetype_id來對應是什么類的信息數據,mimetype表中存放的是幾種數據類型和_id,如圖所示
對應到code中,可以通過下面的一些類去源碼中具體看mimetype和dataX是對應關系
例如:
其他的類可以參考下面這段定義
[java]?view plaincopy
下面是數據庫中的視圖(一些聯合查詢的封裝),其中重要的幾個已經標出。
以上都是一些常用到的數據表和視圖,詳細的數據表結構以及各個字段的數據類型和意義還需要在code中詳細查看。
ContactsProvider中最主要的兩個類:
com.android.providers.contacts.ContactsDatabaseHelper
com.android.providers.contacts.ContactsProvider2
ContactsDatabaseHelper繼承自SqliteOpenHelper,是對數據庫的創建和更新的操作,該類中有詳細的每個表的字段和數據類型的定義,以及數據庫根據version更新和對聯系人部分數據CURD操作封裝的聲明,提供給ContactsProvider2調用
ContactsProvider2繼承自AbstractContactsProvider,是apps和數據庫之間數據傳遞的協議,通過Uri來進行訪問,定義了apps需要使用到的CURD方法
2、聯系人中的數據操作流程
數據查詢
以主界面的DefaultContactBrowseListFragment為例,繼承關系如圖
如下圖所示:
繼承自ContactEntryListFragment的List界面的數據加載流程如下:
在Fragment中通過LoaderManager來對CursorLoader的創建和管理, Fragment中持有一個ContactEntryListAdapter對象,CursorLoader的參數配置等都放在ContactEntryListAdapter中處理, CursorLoader數據加載完成之后回調到Fragment中來,然后通過ContactEntryListAdapter來控制數據的刷新,以及UI的控制
DefaultContactBrowseListFragment對應的adapter為DefaultContactListAdapter,對應的cursorloader為ProfileAndContactsLoader。
其他操作
對于聯系人的創建、更新、刪除一般情況下都封裝在ContactSaveService類中,如圖
ContactSaveService類繼承自IntentService,是一個用于異步操作聯系人數據的service,在完成數據操作之后,通過請求操作的時候傳遞來intent(intent中包含需要回調的Activity和action)回調到Activity中來通知UIThread進行UI update
以create contact為例:
ContactEditorFragment.save()方法中
ContactSaveService中createSaveContactIntent(),傳遞了回調需要的參數
ContactSaveService中saveContact()中
能夠回調到Activity是因為,Contact中有關聯系人操作的Activity的基類ContactsActivity 實現了ContactSaveService.Listener,然后在onCreate中ContactSaveService.registerListener(this),然后通過上面的代碼邏輯最終會調用到
3、主界面
主界面為PeopleActivity界面,分為兩個tab,分別為DefaultContactBrowseListFragment和ContactTileListFragment,通過viewpager進行切換
其中DefaultContactBrowseListFragment為聯系人列表頁面,主要用來處理聯系人列表的加載展示和聯系人搜索,數據加載流程上面已經說明了,列表itemview為ContactListItemView
ContactTileListFragment為收藏聯系人及常用聯系人,該類直接繼承自Fragment,但是和之前說的流程基本一致,方式略微不同,數據分為收藏聯系人和最近常聯系的聯系人,通過ContactTileLoaderFactory來提供加載不同數據的cursorloader
在UI顯示上,通過adapter來控制顯示stared和frequent聯系人,stared為3個一行,frequent一行一個
主界面最上層右下角有一個create聯系人的按鈕,點擊直接進入create contact界面
最上面是toolbar,有search按鈕,和menu鍵
主界面還監聽了provider數據變化
4、Detail界面
AndroidL的code中,detail包中沒有了之前的聯系人詳情,只留下了一些輔助工具類,轉而使用QuickContactActivity來代替ContactDetailActivity,而且UI上也有較大改動,界面是可滑動的,最外層是自定義view:com.android.contacts.widget.MultiShrinkScroller,如果最近和該聯系人聯系過,那么在聯系人號碼下面緊接著就會列出最近聯系情況,包括通話和短信,然后才是其他信息,每一類數據多條時默認顯示一條,點擊查看全部的時候會展開。 z
從聯系人列表進入的時候是全屏狀態,從其他途徑(目前已知的有從短信、桌面快捷方式)進入的時候是非全屏狀態,是通過MultiShrinkScroller控制(runEntranceAnimation)
數據加載和上面的加載流程類似。
5、Edit界面
編輯界面在ContactEditorActivity->ContactEditorFragment中,界面中數據加載流程都和上面類似,比較復雜的是編輯界面的UI,是一個自定義的RawContactEditorView,下圖是數據傳遞和綁定的流程圖
Fragment中持有自定義view對象RawContactEditorView和數據對象RawContactDeltaList,從數據庫中查詢出數據Contact之后,將數據封裝到RawContactDeltaList中,然后通過bindeditors、editor.setState方法將RawContactDeltaList數據傳遞給自定義view,然后RawContactEditorView就會將數據拆分,然后傳遞各個子view,同時也將RawContactDeltaList傳遞過去,然后數據更新就會在子view中完成,當Fragment中需要進行保存聯系人的時候,就可以直接使用RawContactDeltaList;保存聯系人的操作和上面的數據交互流程類似。
6、Pick界面
Pick界面為ContactSelectionActivity,會根據不同的action加載不同的Fragment,包括ContactPickerFragment
PhoneNumberPickerFragment
EmailAddressPickerFragment
PostalAddressPickerFragment
JoinContactListFragment
比較常用的是前3個Fragment
ContactSelectionActivity一般都是通過startActivityForResult的方式啟動的,所以在它finish之前需要返回一個結果回去。
數據加載流程略過。
7、導入導出功能
這個功能是從主界面上的menu鍵觸發
從SIM卡導入
會調用到Telephony的com.android.phone.SimContacts extends ADNList,ADNList中負責數據加載流程,SimContacts負責UI邏輯處理,都很簡單。
?
從存儲空間導入
導入vcard文件,是在ImportVCardActivity中,首先會通過VCardScanThread獲取到存儲空間中的.vcf文件,然后提示用戶來選擇要導入的vcf文件,通過VCardCacheThread進行緩存數據,封裝導入數據需要的數據類型,具體的導入過程是通過bind VCardService進行,service中通過ExecutorService (初始化的為一個單線程的線程池)來執行ImportProcessor(implements Runable)線程,ImportProcessor中執行具體解析導入,ImportProcessor在初始化的時候會傳一個NotificationImportExportListener來進行導入完成之后的接口回調。
導出到存儲空間卡
導出聯系人到vcf文件,存儲到存儲空間中,導出過程和導入過程類似,也是使用VCardService進行。
8、sim卡聯系人
Android L上沒有專門針對SIM聯系人的編輯,顯示等處理,只有上面的導入操作,據說5.1支持雙卡,還不清楚對于sim聯系人有什么影響
9、dialer中用到聯系人
Dialer中有一個tab是全部聯系人的展示和搜索,都是用的ContactsCommon中的東西,所以數據加載流程基本類似,不多復述。
10、其他
1、拷貝到剪貼板
[java]?view plaincopy2、Android L上用到的水波紋效果的類:ViewAnimationUtils
3、修改statusbar顏色(Android L上的,其他version未驗證)
[java]?view plaincopy
總體來看,和我們之前在mtk4.4.4上做的區別很大,移植工作量比較大。
總結
以上是生活随笔為你收集整理的Android contacts 的详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html博客音乐播放器代码大全,HTML
- 下一篇: xvidcore交叉编译