2012-11-10 78 views
2

我目前正在開發一款Android應用程序,它將在一段固定的時間內記錄傳感器數據幾個週期。例如,我打算記錄數據10秒鐘,然後停下來,讓手機休息10秒鐘,然後再次開始記錄,......以這種模式工作1小時。我的問題是,如何讓手機自動執行這個計劃?我目前正在使用下面的代碼(從Android: How to collect sensor values for a fixed period of time?),但它只適用於一個週期,我必須手動開始新的週期後,我確信上一個週期已經完成。如何讓傳感器定期工作?

public void onResume() { 
mSensorManager.registerListener(mListener, mSensorAcceleration, SensorManager.SENSOR_DELAY_GAME); 
mSensorManager.registerListener(mListener, mSensorMagnetic, SensorManager.SENSOR_DELAY_GAME); 
Handler h = new Handler(); 
h.postDelayed(new Runnable() { 

    @Override 
    public void run() { 
    // do stuff with sensor values 
     mSensorManager.unregisterListener(mListener);    
    } 
}, 10000); 

...

任何幫助將不勝感激!

回答

0

步驟#1:讓您的活動實施Runnable,而不是使用匿名內部類,移動您的run()方法以在活動上實施。

步驟#2:在您的run()方法中,使用postDelayed()將您自己(活動)安排在延遲後再次運行。此外,您現有的電話號碼postDelayed()將有效設置爲run()的定期呼叫。步驟#3:跟蹤您是否處於「傳感器開啓」或「傳感器關閉」模式,並且在run()中,根據需要註冊或取消註冊監聽器。

步驟#4:在onPause(),撥打removeCallbacks()在您的Handler停止定期撥打run()

您將會在this sample project中看到這種自我運行再運行邏輯的例子。這裏是活動:

package com.commonsware.android.post; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Toast; 

public class PostDelayedDemo extends Activity implements Runnable { 
    private static final int PERIOD=5000; 
    private View root=null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    root=findViewById(android.R.id.content); 
    } 

    @Override 
    public void onResume() { 
    super.onResume(); 

    run(); 
    } 

    @Override 
    public void onPause() { 
    root.removeCallbacks(this); 

    super.onPause(); 
    } 

    @Override 
    public void run() { 
    Toast.makeText(PostDelayedDemo.this, "Who-hoo!", Toast.LENGTH_SHORT) 
     .show(); 
    root.postDelayed(this, PERIOD); 
    } 
} 
+0

完美,非常感謝! – Bpache

2

我認爲有一個更好,更正確的方式來實現這一點。具體來說,我認爲讓Activity執行Runnable是錯誤的。它泄露了公共接口中的邏輯,應該保持私有(和隱藏)。即沒有人應該在活動之外調用run()。我建議如下改爲:

public class PostDelayedDemo extends Activity { 
    // Declaration of sensor-related fields. 

    private static final int PERIOD = 10000; 
    private Handler handler; 
    private final Runnable processSensors = 
     new Runnable() { 
     @Override 
     public void run() { 
      mSensorManager.registerListener(mListener, mSensorAcceleration, SensorManager.SENSOR_DELAY_GAME); 
      mSensorManager.registerListener(mListener, mSensorMagnetic, SensorManager.SENSOR_DELAY_GAME); 

      // Do work with the sensor values. 

      mSensorManager.unregisterListener(mListener); 

      // The Runnable is posted to run again here: 
      handler.postDelayed(this, PERIOD); 
     } 
     }; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    handler = new Handler(); 
    } 

    @Override 
    public void onResume() { 
    super.onResume(); 

    handler.post(processSensors); 
    } 

    @Override 
    public void onPause() { 
    handler.removeCallbacks(processSensors); 

    super.onPause(); 
    } 
} 
+0

謝謝你,你的解決方案更清潔。我們創建一個可運行的實例變量,而不是將整個活動作爲可運行對象。 – Bpache