原生Android4.0来电按钮消失的问题

google原生Android 4.0有个bug:来电时,如果用户进行一定操作,来电按钮会消失掉,以致用户无法接听电话.
在我们的项目中,对该问题的修复是通过修改以下几个文件来完成的:

packages/apps/Phone/src/com/android/phone/InCallScreen.java
packages/apps/Phone/src/com/android/phone/InCallTouchUi.java
packages/apps/Phone/src/com/android/phone/RespondViaSmsManager.java


InCallTouchUi.java文件的修改如下:

@@ -226,12 +226,19 @@ public class InCallTouchUi extends FrameLayout View.OnTouchListener smallerHitTargetTouchListener = new SmallerHitTarg mEndButton.setOnTouchListener(smallerHitTargetTouchListener); } + /** + * Updates the visibility and/or state of our UI elements, based on + * the current state of the phone. + */ + final void updateState(CallManager cm) { + updateState(cm,false); + } /** * Updates the visibility and/or state of our UI elements, based on * the current state of the phone. */ - void updateState(CallManager cm) { + void updateState(CallManager cm, boolean force) { if (mInCallScreen == null) { log("- updateState: mInCallScreen has been destroyed; bailing out..") return; @@ -270,7 +277,7 @@ public class InCallTouchUi extends FrameLayout // within the last 500 msec, *don't* show the incoming call // UI even if the phone is still in the RINGING state. long now = SystemClock.uptimeMillis(); - if (now < mLastIncomingCallActionTime + 500) { + if ((!force) && (now < mLastIncomingCallActionTime + 500)) { log("updateState: Too soon after last action; not drawing!"); showIncomingCallControls = false; }

InCallScreen.java文件的主要修改如下:

@@ -156,8 +156,9 @@ public class InCallScreen extends Activity private static final int EVENT_PAUSE_DIALOG_COMPLETE = 120; private static final int EVENT_HIDE_PROVIDER_OVERLAY = 121; // Time to rem private static final int REQUEST_UPDATE_SCREEN = 122; - private static final int PHONE_INCOMING_RING = 123; - private static final int PHONE_NEW_RINGING_CONNECTION = 124; + private static final int REQUEST_FORCE_UPDATE_SCREEN = 123; + private static final int PHONE_INCOMING_RING = 124; + private static final int PHONE_NEW_RINGING_CONNECTION = 125; // When InCallScreenMode is UNDEFINED set the default action // to ACTION_UNDEFINED so if we are resumed the activity will @@ -417,6 +418,9 @@ public class InCallScreen extends Activity updateScreen(); break; + case REQUEST_FORCE_UPDATE_SCREEN: + updateScreen(true); + break; case PHONE_INCOMING_RING: onIncomingRing(); break; @@ -2172,7 +2176,21 @@ public class InCallScreen extends Activity mWildPromptText.requestFocus(); } - + /** + * Updates the state of the in-call UI based on the current state of + * the Phone. This call has no effect if we're not currently the + * foreground activity. + * + * This method is only allowed to be called from the UI thread (since it + * manipulates our View hierarchy). If you need to update the screen from + * some other thread, or if you just want to "post a request" for the scree + * to be updated (rather than doing it synchronously), call + * requestUpdateScreen() instead. + */ + final private void updateScreen() + { + updateScreen(false); + } /** * Updates the state of the in-call UI based on the current state of * the Phone. This call has no effect if we're not currently the @@ -2184,7 +2202,7 @@ public class InCallScreen extends Activity * to be updated (rather than doing it synchronously), call * requestUpdateScreen() instead. */ - private void updateScreen() { + private void updateScreen(boolean force) { if (DBG) log("updateScreen()..."); final InCallScreenMode inCallScreenMode = mApp.inCallUiState.inCallScre if (VDBG) { @@ -2245,7 +2263,7 @@ public class InCallScreen extends Activity // Note we update the InCallTouchUi widget before the CallCard, // since the CallCard adjusts its size based on how much vertical // space the InCallTouchUi widget needs. - updateInCallTouchUi(); + updateInCallTouchUi(force); mCallCard.updateState(mCM); updateDialpadVisibility(); updateProviderOverlay(); @@ -3925,13 +3943,18 @@ public class InCallScreen extends Activity mRespondViaSmsManager = new RespondViaSmsManager(); mRespondViaSmsManager.setInCallScreenInstance(this); } - /** * Updates the state of the in-call touch UI. */ - private void updateInCallTouchUi() { + final private void updateInCallTouchUi() { + updateInCallTouchUi(false); + } + /** + * Updates the state of the in-call touch UI. + */ + private void updateInCallTouchUi(boolean force) { if (mInCallTouchUi != null) { - mInCallTouchUi.updateState(mCM); + mInCallTouchUi.updateState(mCM,force); } } @@ -3941,7 +3964,6 @@ public class InCallScreen extends Activity /* package */ InCallTouchUi getInCallTouchUi() { return mInCallTouchUi; } - /** * Posts a handler message telling the InCallScreen to refresh the * onscreen in-call UI. @@ -3958,7 +3980,23 @@ public class InCallScreen extends Activity mHandler.removeMessages(REQUEST_UPDATE_SCREEN); mHandler.sendEmptyMessage(REQUEST_UPDATE_SCREEN); } - + /** + * Posts a handler message telling the InCallScreen to force refresh the + * onscreen in-call UI. + * + * This is just a wrapper around updateScreen(true), for use by the + * rest of the phone app or from a thread other than the UI thread. + * + * updateScreen() is a no-op if the InCallScreen is not the foreground + * activity, so it's safe to call this whether or not the InCallScreen + * is currently visible. + */ + /* package */ void requestForceUpdateScreen() { + if (DBG) log("requestForceUpdateScreen()..."); + mHandler.removeMessages(REQUEST_UPDATE_SCREEN); + mHandler.removeMessages(REQUEST_FORCE_UPDATE_SCREEN); + mHandler.sendEmptyMessage(REQUEST_FORCE_UPDATE_SCREEN); + } /** * @return true if it's OK to display the in-call touch UI, given the * current state of the InCallScreen.


RespondViaSmsManager.java文件的修改如下:

@@ -281,7 +281,7 @@ public class RespondViaSmsManager { // update itself based on the current telephony state. // (Assuming the incoming call is still ringing, this will // cause the incoming call widget to reappear.) - mInCallScreen.requestUpdateScreen(); + mInCallScreen.requestForceUpdateScreen(); } }


结束!

你可能感兴趣的:(Android4.0)