首先說一下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. */ @Override public 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; @Override public 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() { @Override public 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.0 if (its[0] == 0.0) {// 貼近手機 System.out.println("手放上去了..."); if (localWakeLock.isHeld()) { return; } else localWakeLock.acquire();// 申請設備電源锁 } else {// 遠離手機 System.out.println("手拿開了..."); if (localWakeLock.isHeld()) { return; } else localWakeLock.setReferenceCounted(false); localWakeLock.release(); // 釋放設備電源锁 } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; } @Override public int onStartCommand(Intent intent, int flags, int startId) { //注冊監聽 mManager.registerListener(mListener, mSensor, SensorManager.SENSOR_DELAY_GAME); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { //取消監聽 mManager.unregisterListener(mListener); super.onDestroy(); } @Override public 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 { @Override public 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 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 真機測試)。
歡迎熱愛安卓開發的朋友們加入群共同進步。南京群 220818530,成都群 252743807,西安群252746034,武漢群121592153,杭州群253603803,廈門群253604146
From:CNBLOGS
全站熱搜
留言列表