没有p sensor时要求电话接通5s灭屏

    xiaoxiao2021-03-25  59

    [Android Version]

    Android V4.0/V4.1/V4.2/4.4

    [DESCRIPTION]

    没有p sensor时要求电话接通5s灭屏

    [SOLUTION]

     注:

       红色标识修改的code.

    Android V4.4之前的版本:

     

    1.PhoneGlobals.java

    a.添加如下方法: Runnable timeOutTask = new Runnable(){    public void run(){      //mPowerManager.goToSleep(SystemClock.uptimeMillis());

        try{           mPowerManagerService.goToSleep(SystemClock.uptimeMillis

             (),PowerManager.GO_TO_SLEEP_REASON_PROXIMITY);

            }catch(RemoteException e){

     

           }

     

        } };

    /************************************************ param: time:  milliseconds *************************************************/ void setScreenTimeout(long time) {

     if (VDBG) Log.d(LOG_TAG, "setScreenTimeout(" + time + ")...");    // stick with default timeout if we are using the proximity sensor  //  if (proximitySensorModeEnabled()) {    //   return;    // }   mHandler.removeCallbacks(timeOutTask);   mHandler.postDelayed(timeOutTask, time);  }

    /*该方法可根据需要添加到incallscreen.java中的onpause()方法实体的最后*/  void cancelScreenTimeout() {

     if (VDBG) Log.d(LOG_TAG, "cancelScreenTimeout()");  mHandler.removeCallbacks(runningtask);    }

    b.修改如下方法:   /* package */

    void updateWakeState() {         PhoneConstants.State state = mCM.getState();         ......         ......         if (DBG) Log.d(LOG_TAG, "updateWakeState: callscreen " + isShowingCallScreen                        + ", dialer " + isDialerOpened                        + ", speaker " + isSpeakerInUse + "...");

        // (1) Set the screen timeout.     //     // Note that the "screen timeout" value we determine here is     // meaningless if the screen is forced on (see (2) below.)     //     if (!isShowingCallScreen || isSpeakerInUse) {      // Use the system-wide default timeout.      setScreenTimeout(5000);     } else {      // We're on the in-call screen, and *not* using the speakerphone.            if (isDialerOpened) {       // The DTMF dialpad is up.  This case is special because       // the in-call UI has its own "touch lock" mechanism to       // disable the dialpad after a very short amount of idle       // time (to avoid false touches from the user's face while       // in-call.)       //       // In this case the *physical* screen just uses the       // system-wide default timeout.       setScreenTimeout(5000);          } else {       // We're on the in-call screen, and not using the DTMF dialpad.       // There's actually no touchable UI onscreen at all in       // this state.  Also, the user is (most likely) not       // looking at the screen at all, since they're probably       // holding the phone up to their face.  Here we use a       // special screen timeout value specific to the in-call       // screen, purely to save battery life.                     setScreenTimeout(5000);         }     }

            // Decide whether to force the screen on or not.         //         // Force the screen to be on if the phone is ringing or dialing,         // or if we're displaying the "Call ended" UI for a connection in         // the "disconnected" state.         // However, if the phone is disconnected while the user is in the         // middle of selecting a quick response message, we should not force         // the screen to be on.         //         boolean isRinging = (state == PhoneConstants.State.RINGING);       ......       ...... }

    c.修改如下方法:  private class PhoneGlobalsBroadcastReceiver extends BroadcastReceiver {   @Override   public void onReceive(Context context, Intent intent) {             ......             String action = intent.getAction();             ......             ......             } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {                 if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_HEADSET_PLUG");                 if (VDBG) Log.d(LOG_TAG, "    state: " + intent.getIntExtra("state", 0));                 if (VDBG) Log.d(LOG_TAG, "    name: " + intent.getStringExtra("name"));                 mIsHeadsetPlugged = (intent.getIntExtra("state", 0) == 1);                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_WIRED_HEADSET_PLUG, 0));                 pokeUserActivity();             } else if ((action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) &&            ......            ...... }

    2.callNotifier.java a.添加成员变量. public class CallNotifier extends Handler implements CallerInfoAsyncQuery.OnQueryCompleteListener {         ......         ......     private Vibrator mVibrator;     private Call.State mPreviousCallState = Call.State.IDLE;     private Call.State mLastCallState = Call.State.IDLE;

    b.修改如下方法: private void onPhoneStateChanged(AsyncResult r) {    PhoneConstants.State state = mCM.getState();    if (VDBG) log("onPhoneStateChanged: state = " + state);

       ......    ......   mApplication.notificationMgr.statusBarHelper                 .enableNotificationAlerts(state == PhoneConstants.State.IDLE);

            Phone fgPhone = mCM.getFgPhone();   Call.State ringCallState =mCM.getRingingPhone().getRingingCall().getState();   Call.State fgCallState = mCM.getActiveFgCallState();   if((ringCallState == Call.State.IDLE && mLastCallState.isRinging())||    (fgCallState == Call.State.ACTIVE && mLastCallState.isDialing())){      PhoneGlobals.getInstance().setScreenTimeout(5000);    }   mLastCallState = ringCallState.isRinging()?ringCallState:fgCallState;   if (fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {             if ((fgPhone.getForegroundCall().getState() == Call.State.ACTIVE)                     && ((mPreviousCdmaCallState == Call.State.DIALING)                     ||  (mPreviousCdmaCallState == Call.State.ALERTING))) {                 if (mIsCdmaRedialCall) {                     int toneToPlay = InCallTonePlayer.TONE_REDIAL;                     new InCallTonePlayer(toneToPlay).start();                 }                 // Stop any signal info tone when call moves to ACTIVE state                 stopSignalInfoTone();             }             mPreviousCdmaCallState = fgPhone.getForegroundCall().getState();         }    ......    ...... }

    Android V4.4及之后版本:

    1.PhoneGlobals.java a.添加如下变量和方法:  ...... private boolean mTtyEnabled;     // Current TTY operating mode selected by user     private int mPreferredTtyMode = Phone.TTY_MODE_OFF;

        private Call.State mLastCallState = Call.State.IDLE;

     

       Runnable timeOutTask = new Runnable(){      public void run(){  

        try{      //mPowerManager.goToSleep(SystemClock.uptimeMillis());       mPowerManagerService.goToSleep(SystemClock.uptimeMillis(),PowerManager.GO_TO_SLEEP_REASON_PROXIMITY);

            } catch(RemoteException e){

     

            }      }    };    

        /**      * Set the restore mute state flag. Used when we are setting the mute state      * OUTSIDE of user interaction {@link PhoneUtils#startNewCall(Phone)}      */     /*package*/void setRestoreMuteOnInCallResume (boolean mode) {         PhoneLog.d(LOG_TAG, "setRestoreMuteOnInCallResume, mode = " + mode);         mShouldRestoreMuteOnInCallResume = mode;     } ...... b.添加如下方法: ......   //开始定时器,定时灭屏  /************************************************  param:  time:  milliseconds  *************************************************/  void setScreenTimeout(long time) {    if (VDBG) Log.d(LOG_TAG, "setScreenTimeout(" + time + ")...");      // stick with default timeout if we are using the proximity sensor   //  if (proximitySensorModeEnabled()) {     //return;   //}    mHandler.removeCallbacks(timeOutTask);    mHandler.postDelayed(timeOutTask, time);   }

     //取消灭屏的定时器,不让灭屏   void cancelScreenTimeout() {         if (VDBG) Log.d(LOG_TAG, "cancelScreenTimeout()");    mHandler.removeCallbacks(runningtask);     }  

        public PhoneGlobals(Context context) {         super(context);         sMe = this;     } ......

    Note:

           以上两方法要在亮屏或灭屏的地方调用,同一进程(默认进程是phone进程)的话,可直接调用,不同的进程,则要通过跨进程的方式才能调用。 c.修改如下方法:   /* package */ void updateWakeState() {         PhoneConstants.State state = mCM.getState();      Call.State ringCallState = mCM.getRingingPhone().getRingingCall().getState();   Call.State fgCallState = mCM.getActiveFgCallState();   Log.d(LOG_TAG, "updateWakeState,ringCallState ="+ringCallState);   Log.d(LOG_TAG, "updateWakeState,fgCallState ="+ringCallState);      Log.d(LOG_TAG, "updateWakeState,before of mLastCallState ="+mLastCallState);

      if((ringCallState == Call.State.IDLE && mLastCallState.isRinging())||     (fgCallState == Call.State.ACTIVE && mLastCallState.isDialing())){     PhoneGlobals.getInstance().setScreenTimeout(5000);

      }   mLastCallState = ringCallState.isRinging()?ringCallState:fgCallState;   Log.d(LOG_TAG, "updateWakeState,after of mLastCallState ="+mLastCallState);  

            // True if the speakerphone is in use.  (If so, we *always* use         // the default timeout.  Since the user is obviously not holding         // the phone up to his/her face, we don't need to worry about         // false touches, and thus don't need to turn the screen off so         // aggressively.)         // Note that we need to make a fresh call to this method any         // time the speaker state changes.  (That happens in         // PhoneUtils.turnOnSpeaker().)         boolean isSpeakerInUse = (state == PhoneConstants.State.OFFHOOK) && PhoneUtils.isSpeakerOn(this); ...... } d.添加如下变量: powermanager.java ......  /**      * Go to sleep reason code: Going to sleep due to a screen timeout.      * @hide      */     public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2;

        /**      * Go to sleep reason code: Going to sleep due to proximity sensor.      * @hide      */     public static final int GO_TO_SLEEP_REASON_PROXIMITY = 3;  

        final Context mContext; ......

    e.修改如下方法:

    Notifier.java private void sendGoToSleepBroadcast(int reason) {         if (DEBUG) {             Slog.d(TAG, "Sending go to sleep broadcast.");         }

            int why = WindowManagerPolicy.OFF_BECAUSE_OF_USER;         switch (reason) {             case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:                 why = WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN;                 break;             case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:                 why = WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;                 break;                          case PowerManager.GO_TO_SLEEP_REASON_PROXIMITY:                 why = WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR;                 break;                    }

            EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);         ......         }          f.修改如下方法:

    PowerManagerService.java

    private boolean goToSleepNoUpdateLocked(long eventTime, int reason) {         if (mSbPlugState) {             if (DEBUG_SPEW) {                 Slog.d(TAG, "smart book mode: bypass goToSleep request");             }             return false;         }

            if (DEBUG) {         ......         switch (reason) {             case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN:                 Slog.i(TAG, "Going to sleep due to device administration policy...");                 break;             case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT:                 Slog.i(TAG, "Going to sleep due to screen timeout...");                 break;                         case PowerManager.GO_TO_SLEEP_REASON_PROXIMITY:                 Slog.i(TAG, "Going to sleep due to proximity sensor...");                 break;                         default:                 Slog.i(TAG, "Going to sleep by user request...");                 reason = PowerManager.GO_TO_SLEEP_REASON_USER;                 break;         }

            // MTK: Force enable proximity when talking screen off timeout         if (reason == PowerManager.GO_TO_SLEEP_REASON_TIMEOUT) {             if (shouldUseProximitySensorLocked()) {             ......   }  

    转载请注明原文地址: https://ju.6miu.com/read-40377.html

    最新回复(0)