本文來自http://blog.csdn.net/yihongyuelan 轉載請務必註明出處
本文代碼以MTK平台Android 4.4為分析對象,與Google原生AOSP有些許差異,請讀者知悉。
概述 之前有分析過Android 4.2的InCallScreen結構(傳送門),但後面Google發布了Android 4.4即Kitkat,遂決定以之前的文章為模板,重新整理並記錄。在4.4中當有來電或去電時,顯示給使用者的介面1,在4.4之前稱之為InCallScreen,但在4.4之後叫做InCallActivity。在4.4中我們調出的撥號盤介面,實際為DialtactsActivity並隸屬於Dialer應用。4.4 中介面分為3塊,CallCardFragment、CallButtonFragment、AnswerFragment,如下所示:
圖 1 InCallActivity介面(左:接通 右:來電)InCallActivity布局分析
在InCallActivity.java中,實現了對介面的初始化,在4.4中介面的布局是通過fragment來完成的,即incall_screen.xml,代碼如下:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/main"> <!-- MTK VideoCall fragment --> <FrameLayout android:id="@+id/vtCallFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:id="@+id/in_call_and_button_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:id="@+id/in_call_card_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"> <!-- CallCard fragment 用於顯示連絡人資訊 --> <fragment android:name="com.android.incallui.CallCardFragment" android:id="@+id/callCardFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentStart="true" /> <!-- 撥號盤 獨立出來易於複用 --> <fragment android:name="com.android.incallui.DialpadFragment" android:id="@+id/dialpadFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentStart="true" /> </RelativeLayout> <!-- 控制按鈕 也就是原來的InCallTouchUi --> <fragment android:name="com.android.incallui.CallButtonFragment" android:id="@+id/callButtonFragment" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <!-- 來電接聽/掛斷控制項 原始使用的系統的GlowpadView --> <fragment android:name="com.android.incallui.AnswerFragment" android:id="@+id/answerFragment" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:gravity="top" android:layout_gravity="bottom|center_horizontal" android:layout_marginBottom="@dimen/glowpadview_margin_bottom" android:visibility="gone" /> <!-- 會議電話管理介面 --> <fragment android:name="com.android.incallui.ConferenceManagerFragment" android:id="@+id/conferenceManagerFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentStart="true" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" /></FrameLayout>
從整個布局來看,4.4使用fragment代替了原來寫死的布局。一方面更能體現出模組化設計,另一方面對於不同螢幕尺寸的適配也更為容易。根據布局檔案,InCallActivity主要包括以下幾個部分:
- callCardFragment:用於顯示連絡人資訊及通話時間等;
- callButtonFragment:通話介面下方的控制按鈕,之前叫做InCallTouchUi;
- conferenceManagerFragment:會議電話的介面;
- vtCallFragment:視屏通話控制項;
- dialpadFragment:撥號盤顯示控制項。
- answerFragment:來電控制控制項,用於操作接聽/拒接/簡訊快捷回複。
總的來講4.4的布局改動不大,取而代之的是使用更加模組化的布局方式。下面主要展示常見的基礎布局,包括callCardFragement、callButtonFragment、answerFragment。
callCardFragment通話資訊展示callCardFragment控制項,實際上顯示的資訊主要為通話連絡人的相關資訊,整個布局顯示如2:
圖 2 callCardFragment介面
callButtonFragment通話控制介面在4.4中不再稱為InCallTouchUi,而是把下方的控制按鈕使用fragment封裝了起來,相應的布局可以在call_button_fragment.xml中查看。3:
圖 3 callButtonFragmentanswerFragment來電控制介面這裡所說的來電控制介面實際為4.4之前的MultiWaveView,。4:
圖 4 answerFragmentInCallActivity初始化流程
在InCallActivity的onCreate方法中,完成了各個組件(fragment)的初始化,主要在方法initializeInCall中,代碼如下:
private void initializeInCall() { if (mCallButtonFragment == null) { mCallButtonFragment = (CallButtonFragment) getFragmentManager() .findFragmentById(R.id.callButtonFragment); mCallButtonFragment.getView().setVisibility(View.INVISIBLE); } if (mCallCardFragment == null) { mCallCardFragment = (CallCardFragment) getFragmentManager() .findFragmentById(R.id.callCardFragment); } //... ...省略 }然後更新了狀態列以及近距離感應器的狀態,另外MTK對AOSP多了一些定製加入了一些自己的東西,比如SIMInfoWrapperr就是用於顯示儲存SIM卡資訊用的。相對於4.4之前的代碼來說,InCallActivity實際上取代了InCallScreen的功能,初始化流程詳細請查看代碼。這裡得提一下InCallUI中的presenter,它相當於是狀態機器,儲存各種狀態,而fragment用於承載顯示。InCallActivity初始化時序圖如下:
圖 5 InCallActivity初始化時序圖CallButtonFragment控制流程程
因為4.4代碼的變更,我們主要查看以下幾個控制項的控制和更新流程:
answerFragment滑動控制項
answerFragment就是原來的MultiWaveView,現在作為一個獨立的fragment存在。控制流程程時序圖如下:
圖 6 anserFragment顯示/控制時序圖
dialpadButton顯示/隱藏撥號盤
dialpadButton點擊效果與4.4之前差不多,只是與callCardFragment互斥。時序圖如下:
圖 7 接通後顯示撥號盤時序圖
audioButton開啟/關閉擴音器
audioButton用於開啟/關閉擴音器,同時在接入線控耳機或者藍芽耳機後,點擊會彈出選項,執行時序圖如下:
圖 8 開啟/關閉擴音器跟4.4以前的流程相比,現在的控制流程程是從InCallUI中的callButtonFragment傳遞到TeleService中的CallCommandService,並再往下傳遞。muteButton開啟/關閉麥克風靜音
麥克靜音的開啟/關閉與audioButton類似,執行時序如下:
圖 9 麥克風靜音開啟/關閉holdButton開啟/關閉呼叫保持
holdButton用於呼叫保持開啟/關閉,執行時序圖如下:
圖 10 呼叫保持開啟/關閉addButton添加一路通話
addButton在MTK 4.4的代碼中有所改動,顯示addButton的條件是:具有物理menu按鍵或屬於"tablet"。
圖 11 新增一路通話時序圖endButton掛斷當前通話
endButton點擊後執行時序圖如下:
圖 12 掛斷當前通話時序圖CallCardFragment通話資訊顯示
CallCardFragment的更新相對於4.4以前來說,更為獨立,代碼更為清晰(只不過被MTK這麼一改,哎……),整個介面更新時序圖如下:
圖13 CallCardFragment更新時序圖小結
Android 4.4 Phone在UI上並沒有大的改動,但是代碼的實現方法卻發生了很大的變化,通過分析可以基本理清UI介面的更新流程。
最後附上文中涉及時序圖的原圖下載連結,原圖無失真便於查看,點這裡。