没有p sensor时要求电话接通5s后灭屏
时间:10-02
整理:3721RD
点击:
[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_REAS
ON_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()) {
......
}
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_REAS
ON_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()) {
......
}