原生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();          }      }


结束!

你可能感兴趣的:(thread,android,UI,Class,action,hierarchy)