今天分享給你們一個簡易的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