首先說一下android平台下的11種感應器: 1. ACCELEROMETER 加速,描述加速度的。 2.GRAVITY 重力,這個在大家都知道。 3.GYROSCOPE 陀螺儀,對於物體跌落檢測更強大些,開發遊戲少了它會有點遺憾的,API Level 9新增的類型。 4. LIGHT 光線感應器,很多Android手機的螢幕亮度是根據這個感應器的數組自動調節的。 5. LINEAR_ACCELERATION 線性加速器,API Level 9新增的。 6. MAGNETIC_FIELD 磁極感應器。 7. ORIENTATION 方向感應器。 8. PRESSURE 壓力感應器。 9. PROXIMITY 距離感應器,對於通話後關閉螢幕背光很有用。 10. ROTATION_VECTOR 旋轉向量,Android 2.3新增的,如果我們過去處理映像會發現這個還是很有用的,不過這裡還是對遊戲開發起到輔助。 11. TEMPERATURE 溫度感應器,可以擷取手機的內部溫度,不過和周邊的有些差距,畢竟手機內部一般溫度比較高。要善於應用這些資源,今天要說的就是距離感應器。其這個鎖頻的原理也很簡單,就是當有物體靠近距離感應器的時候,會觸發事件,然後在事件裡面申請裝置電源鎖,讓螢幕處於黑屏出台,然後當物體離開距離感應器,釋放裝置電源鎖,就ok了。下面看看代碼MainActivity.java 這個類很簡單,就是啟動一個Service。
public class MainActivity extends Activity {/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);Intent intent = new Intent(MainActivity.this, MyService.class);startService(intent);}}
然後就是MyService.java 主要內容
public class MyService extends Service {private SensorManager mManager;private Sensor mSensor = null;private SensorEventListener mListener = null;private PowerManager localPowerManager = null;private PowerManager.WakeLock localWakeLock = null;@Overridepublic void onCreate() {//擷取系統服務POWER_SERVICE,返回一個PowerManager對象localPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);//擷取PowerManager.WakeLock對象,後面的參數|表示同時傳入兩個值,最後的是LogCat裡用的Tag localWakeLock = this.localPowerManager.newWakeLock(32, "MyPower");//擷取系統服務SENSOR_SERVICE,返回一個SensorManager對象mManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);//擷取距離感應器對象mSensor = mManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);//註冊感應器事件mListener = new SensorEventListener() {@Overridepublic void onSensorChanged(SensorEvent event) {float[] its = event.values;if (its != null&& event.sensor.getType() == Sensor.TYPE_PROXIMITY) {System.out.println("its[0]:" + its[0]);//經過測試,當手貼近距離感應器的時候its[0]傳回值為0.0,當手離開時返回1.0if (its[0] == 0.0) {// 貼近手機System.out.println("手放上去了...");if (localWakeLock.isHeld()) {return;} elselocalWakeLock.acquire();// 申請裝置電源鎖} else {// 遠離手機System.out.println("手拿開了...");if (localWakeLock.isHeld()) {return;} elselocalWakeLock.setReferenceCounted(false);localWakeLock.release(); // 釋放裝置電源鎖} }}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}};}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//註冊監聽mManager.registerListener(mListener, mSensor,SensorManager.SENSOR_DELAY_GAME);return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {//取消監聽mManager.unregisterListener(mListener);super.onDestroy();}@Overridepublic IBinder onBind(Intent intent) {return null;}}
AndroidManifest.xml 中需要添加許可權<uses-permissionandroid:name=
"android.permission.DEVICE_POWER"/><uses-permission android:name=
"android.permission.WAKE_LOCK"/>
由於時間原因,我這裡只是實現了功能,還有很多要最佳化的地方,有需要的話自己可以加上。 最佳化1:當按下的時候,螢幕會鎖住,但是感應器事件依然會觸發,也就是說,當你擋住距離感應器,然後再放開,螢幕依然會亮。 解決方案:當系統鎖屏或黑屏會廣播兩個訊息分別是:ACTION_SCREEN_OFF和ACTION_SCREEN_ON,所以我們可以自己寫個BroadcastReceiver來接受這個廣播,並且做相應的處理。具體處理方法大家可以在黑屏的時候停止service,然後在螢幕亮後再啟動service。或者更簡單的定義個boolean變數,黑屏為false,亮的時候為true,然後判斷在true的情況下才申請裝置電源鎖,應該都可以。大概代碼如下
public class MyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (action.equals("android.intent.action.SCREEN_OFF")) {} else if (action.equals("android.intent.action.SCREEN_ON")) {}}}
最佳化2:實現可以手動關閉和啟動service。在MainActivity中可以添加個checkBox,以便開啟和停止服務。這個應該很簡單就不詳細說明了。
最佳化3:開機自啟動。這個就不說了,網上大把大把的資料。
最後再講解下PowerManager這個類。PowerManager這個類主要是用來控制電源狀態的. 通過使用該類提供的api可以控制電池的待機時間,一般情況下不要使用。如果確實需要使用,那麼儘可能的使用最低層級的WakeLocks鎖。並且確保使用完後釋放它。你可以通過context.getSystemService(Context.POWER_SERVICE)的方式獲得PowerManager的執行個體。在PowerManager中,最主要的newWakeLock方法,SDK源碼如下
/*** Get a wake lock at the level of the flags parameter. Call* {@link WakeLock#acquire() acquire()} on the object to acquire the* wake lock, and {@link WakeLock#release release()} when you are done.** {@samplecode*PowerManager pm = (PowerManager)mContext.getSystemService(* Context.POWER_SERVICE);*PowerManager.WakeLock wl = pm.newWakeLock(* PowerManager.SCREEN_DIM_WAKE_LOCK* | PowerManager.ON_AFTER_RELEASE,* TAG);*wl.acquire();* // ...*wl.release();* }** @param flags Combination of flag values defining the requested behavior of the WakeLock.* @param tag Your class name (or other tag) for debugging purposes.** @see WakeLock#acquire()* @see WakeLock#release()*/public WakeLock newWakeLock(int flags, String tag){return new WakeLock(flags, tag);}
這個方法將建立WakeLock對象,通過調用此對象的方法你就可以方便的去控制電源的狀態。方法如下:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");wl.acquire();螢幕將停留在設定的狀態,一般為亮、暗狀態wl.release();釋放掉正在啟動並執行cpu或關閉螢幕。
flags參數說明: * cpu screen keyboard
* PARTIAL_WAKE_LOCK on off off
* SCREEN_DIM_WAKE_LOCK on dim off
* SCREEN_BRIGHT_WAKE_LOCK on bright off
* FULL_WAKE_LOCK on bright bright
如果你持有PARTIAL_WAKE_LOCK鎖,不論任何定時器甚至是按下電源開關,cpu都將繼續運行,無法進入休眠狀態。除非你釋放掉它。其他鎖的話,雖然cpu也在運行,但是當使用者按下電源開關時,裝置將立刻進入休眠狀態。
就說到這裡了,這個也沒什麼,下面會附上源碼。(此程式只在 htc G7 真機測試)。 http://files.cnblogs.com/feifei1010/Keylock.rar歡迎熱愛安卓開發的朋友們加入群共同進步。南京群 220818530,成都群 252743807,西安群252746034,武漢群121592153,杭州群253603803,廈門群253604146