天天看點

Android--保持加速度傳感器在螢幕關閉後運作(收集)

  由于寫論文需要,需要用手機加速度采集資料,關于android加速度傳感器的介紹網上一抓一大把,但大多都是大同小異,跟官網文檔差不多。自己寫了個取加速度傳感器的APK,發現資料有點不對勁,原理螢幕一關後,系統就自動把各種傳感器給停掉了,網上找了很久,發現一些可用的資源。

1、檢視手機是否支援鎖屏後繼續運作傳感器

  有些手機可以支援背景取傳感器資料,有些手機不行,這與硬體廠商具體實作有關,像GPS這些傳感器都是很耗電的,廠商也是出于電源管理的考慮,這裡是一個不完全清單,總結哪些軟體支援螢幕關閉後依然運作傳感器。這裡更有一款APK(Accelerometer Frequency)專門檢視你的手機是否支援。

  如果你的手機不支援,那還是不要折騰了,換了裝置試試。

2、實作方法

  我主要參考了

  1)http://blog.kozaxinan.com/2012/08/using-accelerometer-when-screen-off_16.html

  2)http://stackoverflow.com/questions/9982433/android-accelerometer-not-working-when-screen-is-turned-off

  星期天我按他們的方法實作了一下,主要思想就是申請鎖屏後CPU不休眠:

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);  PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
wl.acquire();
..
wl.release();      

  我把service寫成activity的一個内部類,而我把申請電源管理的指令放在了service的Oncreate()方法裡,之前一直納悶,明明我的手機檢測支援的,鎖屏後還是沒有取資料,而且連接配接USB時,鎖屏後繼續取加速度傳感器資料,而拔掉USB後就停了,到處找原因,後來才發現service的OnCreate()方法沒執行,坑了我。

  醜又醜點,我把電源管理申請放在了Activity的onCreate()方法中,結果可行了,把代碼放上來。 

Android--保持加速度傳感器在螢幕關閉後運作(收集)
1 public class AccleratePersist extends Activity {
  2     private static final String TAG = "AccleratePersist";
  3     private static final int DELAY = SensorManager.SENSOR_DELAY_NORMAL;
  4     private static boolean STOP = true;// 開始暫停按鈕
  5 
  6     private SensorManager mSensorManager;
  7     private WakeLock mWakeLock;
  8     private TextView accView;// 顯示加速度值
  9     private StringBuilder builder = new StringBuilder();
 10     private long lastTimestamp = 0;
 11 
 12     private PersistService mySerivece;
 13 
 14     @Override
 15     protected void onCreate(Bundle savedInstanceState) {
 16         super.onCreate(savedInstanceState);
 17         setContentView(R.layout.activity_main);
 18         accView = (TextView) this.findViewById(R.id.accValue);
 19         final Button stopButton = (Button) this.findViewById(R.id.stopButton);// 停止測量按鈕
 20         final Button clearButton = (Button) this.findViewById(R.id.clear); // 清除資料
 21 
 22         View.OnClickListener onClickListener = new View.OnClickListener() {
 23 
 24             @Override
 25             public void onClick(View view) {
 26                 if (view == stopButton) {
 27                     STOP = !STOP;
 28                     setMeasure();
 29                 } else if (view == clearButton) {
 30                     builder = new StringBuilder();
 31                     accView.setText("");
 32                 }
 33             }
 34 
 35             @SuppressLint("Wakelock")
 36             private void setMeasure() {
 37                 if (STOP) {// 停止鍵按下後,取消監聽,是否電源
 38                     stopButton.setText("繼續");
 39                     mSensorManager.unregisterListener(mySerivece);
 40                     mWakeLock.release();
 41                 } else {
 42                     stopButton.setText("停止");
 43                     mWakeLock.acquire();// 螢幕熄後,CPU繼續運作
 44                     mSensorManager
 45                             .registerListener(
 46                                     mySerivece,
 47                                     mSensorManager
 48                                             .getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
 49                                     DELAY);
 50                 }
 51             }
 52 
 53         };
 54         clearButton.setOnClickListener(onClickListener);
 55         stopButton.setOnClickListener(onClickListener);
 56         mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
 57         mySerivece = new PersistService();
 58         PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
 59         mWakeLock = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);// CPU儲存運作
 60         IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);// 螢幕熄掉後依然運作
 61         filter.addAction(Intent.ACTION_SCREEN_OFF);
 62         registerReceiver(mySerivece.mReceiver, filter);
 63     }
 64 
 65     class PersistService extends Service implements SensorEventListener {
 66 
 67         private float[] accValue = new float[3];
 68 
 69         public BroadcastReceiver mReceiver = new BroadcastReceiver() {
 70             @Override
 71             public void onReceive(Context context, Intent intent) {
 72 
 73                 if (!STOP
 74                         && !intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
 75                     return;
 76                 }
 77                 if (mSensorManager != null) {//取消監聽後重寫監聽,以保持背景運作
 78                     mSensorManager.unregisterListener(PersistService.this);
 79                     mSensorManager
 80                             .registerListener(
 81                                     PersistService.this,
 82                                     mSensorManager
 83                                             .getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
 84                                     SensorManager.SENSOR_DELAY_NORMAL);
 85                 }
 86 
 87             }
 88 
 89         };
 90 
 91         public void onAccuracyChanged(Sensor sensor, int accuracy) {
 92             Log.i(TAG, "PersistService.onAccuracyChanged().");
 93         }
 94 
 95         public void onSensorChanged(SensorEvent sensorEvent) {
 96             if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
 97                 Log.i(TAG, "PersistService.TYPE_ACCELEROMETER.");
 98                 accValue = sensorEvent.values;
 99                 for (int i = 0; i < 3; i++) {
100                     builder.append((int) accValue[i]);
101                     builder.append(",");
102                 }
103                 builder.append((sensorEvent.timestamp - lastTimestamp) / 1000000);// 采樣時間差
104                 builder.append("\n");
105                 accView.setText(builder.toString());
106                 lastTimestamp = sensorEvent.timestamp;
107             }
108 
109         }        
110         @Override
111         public IBinder onBind(Intent intent) {
112             // TODO Auto-generated method stub
113             return null;
114         }        
115 
116     }
117 }      
Android--保持加速度傳感器在螢幕關閉後運作(收集)

   記得加一個權限:  <uses-permission android:name="android.permission.WAKE_LOCK" />

  有問題歡迎交流。

 轉載請注明出處:http://www.cnblogs.com/fengfenggirl