2

私は現在、センサーデータを一定時間数サイクル記録するアプリをAndroidで開発しています。たとえば、データを 10 秒間記録してから停止し、電話を 10 秒間休ませてから、記録を再開する予定です。このパターンで 1 時間作業します。私の質問は、電話がこの計画を自動的に実行できるようにする方法ですか? 現在、以下のコードを使用しています ( Android から: 一定期間センサー値を収集する方法は? ) が、1 サイクルしか機能しないため、前のサイクルが完了したことを確認してから、新しいサイクルを手動で開始する必要があります。

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);

...

どんな助けでも大歓迎です!!

4

2 に答える 2

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();
  }
}
于 2012-11-10T22:24:25.923 に答える
0

ステップ #1:Runnable匿名の内部クラスを使用するのではなく、アクティビティを実装run()して、メソッドをアクティビティに実装するように移動します。

ステップ #2:run()メソッドで、 を使用して遅延後に再度実行するように自分自身 (アクティビティ) をスケジュールしますpostDelayed()。これに加えて、 への既存の呼び出しによりpostDelayed()、 への定期的な呼び出しが効果的に設定されrun()ます。

ステップ 3: 「センサー オン」モードか「センサー オフ」モードかを追跡し、run()必要に応じてリスナーを登録または登録解除します。

ステップ #4:onPause()で、 に電話して、への定期的な呼び出しを停止しremoveCallbacks()ます。Handlerrun()

このサンプル プロジェクトでは、この種の自分で実行を再スケジュールするロジックの例を示します。アクティビティは次のとおりです。

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);
  }
}
于 2012-11-10T13:32:05.813 に答える