10

Androidプログラミングの基礎を学んでいます。

私は、加速度計、磁力計、および方向データを外部ファイルに記録しながら表示する単純なAndroidテストアプリケーションを持っています。メソッドinitLoggerを呼び出して、 [開始] ボタン (関連するセンサーの registerListener)のクリックでログ記録プロセスを開始します。

これに似ているものは...

public void initLogger(View view)
{
    boolean bFlag = false;

    Button btnStart = (Button)findViewById(R.id.btnStartLog);
    Button btnStop = (Button)findViewById(R.id.btnStopLog);

    btnStart.setEnabled(bFlag);
    btnStop.setEnabled(!bFlag);

    bEnableLogging = true;
    //Start reading the sensor values
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_UI);
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);

   //so on.... 

ロギング プロセスを停止する [停止] ボタンもあります (最後に、各センサーの unregisterListener を呼び出して登録を解除します)。

データ取得プロセスは、関連するセンサーからデータを取得し、それぞれの UI 要素に値を設定し、最終的にデータを外部の .csv ファイルに記録するonSensorChangedハンドラー内で発生します。

onSensorChanged イベントハンドラは次のようになります...

public void onSensorChanged(SensorEvent event) {


    // TODO Auto-generated method stub
    // accelerometer
    TextView tAX = (TextView) findViewById(R.id.txtViewAxValue);
    TextView tAY = (TextView) findViewById(R.id.txtViewAyValue);
    TextView tAZ = (TextView) findViewById(R.id.txtViewAzValue);

    // magnetic field
    TextView tMX = (TextView) findViewById(R.id.txtViewMx);
    TextView tMY = (TextView) findViewById(R.id.txtViewMy);
    TextView tMZ = (TextView) findViewById(R.id.txtViewMz);

    if (bEnableLogging) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

            accelerometerdata = event.values.clone();

            tAX.setText(Double.toString(accelerometerdata[0]));
            tAY.setText(Double.toString(accelerometerdata[1]));
            tAZ.setText(Double.toString(accelerometerdata[2]));


        }

        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {

            magneticmatrixdata = event.values.clone();

            tMX.setText(Double.toString(magneticmatrixdata[0]));
            tMY.setText(Double.toString(magneticmatrixdata[1]));
            tMZ.setText(Double.toString(magneticmatrixdata[2]));

        }

               // so on ....

構成されたすべてのセンサーからデータを受信しますが、データを受信する速度を制御することはできません。すなわち

SensorChanged イベントは、センサー データが変更されたときに発生することを知っています。ただし、このイベントを固定レートで発生させたいと考えています。例: 40ms ごと

質問:

  1. SensorChanged イベントが一定のレートで発生するようにするにはどうすればよいですか?
  2. この場合、Java のクラス TimerTask は役に立ちますか?

ここSOの専門家。助けてください:)

4

5 に答える 5

3

センサーの登録時に遅延を変更することで、間隔を変更できます。

int SENSOR_DELAY_FASTEST    get sensor data as fast as possible 
int SENSOR_DELAY_GAME       rate suitable for games 
int SENSOR_DELAY_NORMAL     rate (default) suitable for screen orientation changes
int SENSOR_DELAY_UI         rate suitable for the user interface

thisによると、最速の遅延は必要なものであり、それが十分に速く変更されない場合は、変更がなかったためです。getSensorData メソッドはありません。

SENSOR_DELAY_GAME (20,000 マイクロ秒の遅延)、SENSOR_DELAY_UI (60,000 マイクロ秒の遅延)、または SENSOR_DELAY_FASTEST (0 マイクロ秒の遅延) など、他のデータ遅延を指定できます。Android 3.0 (API レベル 11) 以降では、遅延を絶対値 (マイクロ秒単位) で指定することもできます。

指定する遅延は、推奨される遅延にすぎません。Android システムやその他のアプリケーションによって、この遅延が変更される場合があります。通常、システムは指定した遅延よりも小さい遅延を使用するため、ベスト プラクティスとして、可能な限り最大の遅延を指定する必要があります (つまり、アプリケーションのニーズを満たす最も遅いサンプリング レートを選択する必要があります)。より大きな遅延を使用すると、プロセッサの負荷が低くなるため、消費電力が少なくなります。

于 2012-09-03T11:40:07.937 に答える
2

SensorChanged イベントが発生しなかった場合は変更がないことがわかっているため、古い値をそのまま使用できます。特定の間隔で LOG データを要求したので、onSensorChanged メソッドで出力を行わず、新しいデータを加速度計データ変数に複製するだけです。さらに、40ms ごとに加速度計データの値をログに記録します。このようにして、データが変更されていなくても、40ms ごとに実際の値を記録しています....

注: Ridcullys Answer によると、特定の時間間隔でセンサー データを「配信」することも可能のようです。しかし、Android のセンサー データではいつものように、これらの「配信」に遅延があるため、私のソリューションでは、より正確に 40 ミリ秒間隔になります。一方で、ログを記録した瞬間にセンサー データが変更された場合、新しいデータを 1 間隔だけ遅らせる可能性があります。そして、私は推測します(この点についてはわかりません)-「リアルタイムでできるだけ速く取得する」などのsthではなく、ロギングに関するものであるため、これは要件ではありません-Timer-SolutionはCPU負荷を減らします。

于 2012-09-05T07:04:29.543 に答える
1

registerListenerSensorManagerを使用してリスナーを登録する場合、JavaDocs に記載されているように、固定定数の代わりにマイクロ秒単位で間隔を渡すことができます。SENSOR_DELAY_...

rate センサー イベントが配信される速度。これはシステムへのヒントにすぎません。イベントは、指定された速度より速くまたは遅く受信される場合があります。通常、イベントはより速く受信されます。値は、SENSOR_DELAY_NORMAL、SENSOR_DELAY_UI、SENSOR_DELAY_GAME、または SENSOR_DELAY_FASTEST のいずれか、またはマイクロ秒単位のイベント間の目的の遅延である必要があります。

したがって、例のリクエストに一致するように40000を渡すだけです。また、前述のように、これは単なるヒントであるため、マイクロ秒単位の正確な間隔で値を取得することに依存しません。

于 2012-09-03T12:37:09.643 に答える
0

どうすればセンサーで非常に長い遅延が発生するかを理解しようとしてきましたが、これまでのところ成功しています。developer.android のドキュメントには、遅延時間をマイクロ秒単位で指定できることが記載されています。以下は、私が試した多数の数値です。

// Initialize in onCreate
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE)
mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);

// Register the listener, and play around with delay
mSensorManager.registerListener(this, mLight, 200000000);

ただし、以下の LogCat ダンプ - onSensorChanged() - は 1 秒間に 4 回も呼び出されることに注意してください。

01-14 06:58:07.088: D/IOE Sensors(20933): onSensorChanged が呼び出され、イベントは: android.hardware.SensorEvent@42849f70 01-14 06:58:07.268: D/IOE Sensors(20933): onSensorChanged 、イベントは: android.hardware.SensorEvent@42849f70 01-14 06:58:07.448: D/IOE Sensors(20933): onSensorChanged が呼び出され、イベントは: android.hardware.SensorEvent@42849f70 01-14 06:58: 07.628: D/IOE Sensors(20933): onSensorChanged が呼び出され、イベントは: android.hardware.SensorEvent@42849f70 01-14 06:58:07.808: D/IOE Sensors(20933): onSensorChanged が呼び出され、イベントは: android. hardware.SensorEvent@42849f70 01-14 06:58:07.989: D/IOE Sensors(20933): onSensorChanged が呼び出され、イベントは: android.hardware.SensorEvent@42849f70 01-14 06:58:08.169: D/IOE Sensors( 20933): onSensorChanged が呼び出されました。イベントは次のとおりです: android.hardware.SensorEvent@42849f70

于 2014-01-14T14:17:56.393 に答える