簡易實現臉部貼近自動關屏

今天分享給你們一個簡易的Demo,實現的效果是:當手機屏幕貼近臉部時,屏幕自動熄滅。固然,因爲是簡單的思路,因此這裏所謂的「熄滅」並不是真的關閉屏幕,而是簡單地使用一張黑色背景的圖片遮蓋住全部顯示的內容,看上去像是關閉了屏幕而已。
整個實現思路較爲簡單,首先啓動監聽器,監聽距離變化,一旦距離到達必定的接近值的時候,就關掉屏幕;反之則打開屏幕。這裏的學問僅在於一個距離傳感器返回給咱們的距離值,這個距離值會在相應的監聽器回調裏面獲取。
很少說了,直接上代碼:
須要添加的權限:android

<uses-permission Android:name="android.permission.DEVICE_POWER"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
複製代碼

Java主邏輯:app

import android.app.Activity;  
import android.content.Context;  
import android.hardware.Sensor;  
import android.hardware.SensorEvent;  
import android.hardware.SensorEventListener;  
import android.hardware.SensorManager;  
import android.os.Bundle;  
import android.os.PowerManager;  
import android.util.Log;  
import android.view.Menu;  
import android.view.View;  
  
public class SensorTest extends Activity implements SensorEventListener{  
    public static final String TAG = "SensorTest";  
      
    //調用距離傳感器,控制屏幕  
    private SensorManager mManager;//傳感器管理對象  
    //屏幕開關  
    private PowerManager localPowerManager = null;//電源管理對象  
    private PowerManager.WakeLock localWakeLock = null;//電源鎖  
      
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.sensor);  
          
        mManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);  
        //獲取系統服務POWER_SERVICE,返回一個PowerManager對象  
        localPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);  
        //獲取PowerManager.WakeLock對象,後面的參數|表示同時傳入兩個值,最後的是LogCat裏用的Tag   
        localWakeLock = this.localPowerManager.newWakeLock(32, "MyPower");//第一個參數爲電源鎖級別,第二個是日誌tag  
    }  
      
    public void onResume(){  
        super.onResume();  
        mManager.registerListener(this, mManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),// 距離感應器  
                SensorManager.SENSOR_DELAY_NORMAL);//註冊傳感器,第一個參數爲距離監聽器,第二個是傳感器類型,第三個是延遲類型  
    }  
      
    public void onStop(){  
        super.onStop();  
        Log.d(TAG,"on stop");  
    }  
      
    public void onDestroy(){  
        super.onDestroy();  
        Log.d(TAG,"on destroy");  
        if(mManager != null){  
            localWakeLock.release();//釋放電源鎖,若是不釋放finish這個acitivity後仍然會有自動鎖屏的效果,不信能夠試一試  
            mManager.unregisterListener(this);//註銷傳感器監聽  
        }  
    }  
  
    @Override  
    public void onAccuracyChanged(Sensor sensor, int accuracy) {  
        // TODO Auto-generated method stub  
          
    }  
  
    @Override  
    public void onSensorChanged(SensorEvent event) {  
        // TODO Auto-generated method stub  
        float[] its = event.values;  
        //Log.d(TAG,"its array:"+its+"sensor type :"+event.sensor.getType()+" proximity type:"+Sensor.TYPE_PROXIMITY);  
        if (its != null && event.sensor.getType() == Sensor.TYPE_PROXIMITY) {  
  
            System.out.println("its[0]:" + its[0]);  
  
            //通過測試,當手貼近距離感應器的時候its[0]返回值爲0.0,當手離開時返回1.0  
            if (its[0] == 0.0) {// 貼近手機  
  
                System.out.println("hands up");  
                Log.d(TAG,"hands up in calling activity");  
                if (localWakeLock.isHeld()) {  
                    return;  
                } else{  
  
                    localWakeLock.acquire();// 申請設備電源鎖  
                }  
            } else {// 遠離手機  
  
                System.out.println("hands moved");  
                Log.d(TAG,"hands moved in calling activity");  
                if (localWakeLock.isHeld()) {  
                    return;  
                } else{  
                    localWakeLock.setReferenceCounted(false);  
                    localWakeLock.release(); // 釋放設備電源鎖  
                }  
            }  
        }  
    }  
  
}  
複製代碼

這裏特別注意:
一、在退出的時候務必釋放,不然有可能在其餘正常使用的狀況下仍然會黑屏;
二、注意非空檢查,在某些未配備距離傳感器的機型上,會報空。ide