Android4.2中Phone的P-sensor的應用的分析。
阿新 • • 發佈:2019-02-10
先說現象,現象就是來電話,接通電話,把手機螢幕靠近臉部,遮擋住P-sensor,螢幕變黑了,不遮擋住P-sensor,螢幕就點亮了。接著我們來看看程式碼流程。
先來說說靠近P-sensor,不滅屏的正常的現象:
- 插入耳機
- 開啟揚聲器
- 開啟藍芽耳機
- 連結藍芽鍵盤
步驟一: 在PhoneGlobals.java檔案中onCreate()方法中:
。。。 。。。
[java] view plaincopyprint?-
// lock used to keep the processor awake, when we don't care for the display.
- mPartialWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
- | PowerManager.ON_AFTER_RELEASE, LOG_TAG);
- // Wake lock used to control proximity sensor behavior.
- if (mPowerManager.isWakeLockLevelSupported(
-
PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
- mProximityWakeLock = mPowerManager.newWakeLock(
- PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);
- }
注意這個private PowerManager.WakeLock mProximityWakeLock;這個初始化變數,
這個mProximityWakeLock就是所說的P-Sensor鎖,它是用來喚醒螢幕和使螢幕睡眠的鎖。
步驟二:在PhoneGlobals.java檔案中的onCreate()方法中:
[java] view plaincopyprint?- // create mAccelerometerListener only if we are using the proximity sensor
- if (proximitySensorModeEnabled()) {
- mAccelerometerListener = new AccelerometerListener(this, this);
- }
步驟三:在更新Phone的狀態的時候確定這個加速度的P-sensor感應器起作用;
[java] view plaincopyprint?- <span style="font-size:18px;">/**
- * Notifies the phone app when the phone state changes.
- *
- * This method will updates various states inside Phone app (e.g. proximity sensor mode,
- * accelerometer listener state, update-lock state, etc.)
- */
- /* package */void updatePhoneState(PhoneConstants.State state) {
- if (state != mLastPhoneState) {
- mLastPhoneState = state;
- if (state == PhoneConstants.State.IDLE)
- PhoneGlobals.getInstance().pokeUserActivity();
- updateProximitySensorMode(state);
- // Try to acquire or release UpdateLock.
- //
- // Watch out: we don't release the lock here when the screen is still in foreground.
- // At that time InCallScreen will release it on onPause().
- if (state != PhoneConstants.State.IDLE) {
- // UpdateLock is a recursive lock, while we may get "acquire" request twice and
- // "release" request once for a single call (RINGING + OFFHOOK and IDLE).
- // We need to manually ensure the lock is just acquired once for each (and this
- // will prevent other possible buggy situations too).
- if (!mUpdateLock.isHeld()) {
- mUpdateLock.acquire();
- }
- } else {
- if (!isShowingCallScreen()) {
- if (!mUpdateLock.isHeld()) {
- mUpdateLock.release();
- }
- } else {
- // For this case InCallScreen will take care of the release() call.
- }
- }
- if (mAccelerometerListener != null) {
- // use accelerometer to augment proximity sensor when in call
- mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
- </span><span style="color:#ff0000;"><strong><span style="font-size:24px;"> </span><span style="font-size:18px;">mAccelerometerListener.enable(state == PhoneConstants.State.OFFHOOK);</span></strong></span><span style="font-size:18px;">
- }
- // clear our beginning call flag
- mBeginningCall = false;
- // While we are in call, the in-call screen should dismiss the keyguard.
- // This allows the user to press Home to go directly home without going through
- // an insecure lock screen.
- // But we do not want to do this if there is no active call so we do not
- // bypass the keyguard if the call is not answered or declined.
- if (mInCallScreen != null) {
- if (VDBG) Log.d(LOG_TAG, "updatePhoneState: state = " + state);
- if (!PhoneUtils.isDMLocked())
- mInCallScreen.updateKeyguardPolicy(state == PhoneConstants.State.OFFHOOK);
- }
- }
- }</span>
步驟四:用AccelerometerListener.java類中的監聽事件來處理一些這個覆蓋的改變,一共有2個狀態,一個是
horizontal,一個是vertical的狀態。在上述步驟三紅色的呼叫部分註冊這個監聽事件:
[java] view plaincopyprint?- publicvoid enable(boolean enable) {
- if (DEBUG) Log.d(TAG, "enable(" + enable + ")");
- synchronized (this) {
- if (enable) {
- mOrientation = ORIENTATION_UNKNOWN;
- mPendingOrientation = ORIENTATION_UNKNOWN;
- mSensorManager.registerListener(mSensorListener, mSensor,
- SensorManager.SENSOR_DELAY_NORMAL);
- } else {
- mSensorManager.unregisterListener(mSensorListener);
- mHandler.removeMessages(ORIENTATION_CHANGED);
- }
- }
- }
步驟五:監聽事件的相應的過程如下: [java] view plaincopyprint?
- SensorEventListener mSensorListener = new SensorEventListener() {
- publicvoid onSensorChanged(SensorEvent event) {
- onSensorEvent(event.values[0], event.values[1], event.values[2]);
- }
- publicvoid onAccuracyChanged(Sensor sensor, int accuracy) {
- // ignore
- }
- };
[java] view plaincopyprint?
- privatevoid onSensorEvent(double x, double y, double z) {
- if