2016-11-17 3 views
0

私は今この課題に取り組んでおり、さまざまな可能性を模索し、「キューイング」の発生場所を絞り込んでいます。私が何をしようとしているのかをまず説明しましょう。onSensorChanged()のキューイングが矛盾しないようにする

何をしたいですか?
ウェアラブルサービス(Sony Smartwatch 3で動作)を搭載したAndroidアプリ(Google Pixelで実行中)を作成して、スマートウォッチからできるだけ早くセンサーデータを取得し、その結果をVerboseとしてログに記録します。現在のところ、TYPE_ROTATION_VECTORのデータは約150Hzです。このデータは、PrintWriterを使用してチャネル(出力ストリーム)を介して送信され、BufferReaderを使用して同じチャネル(入力ストリーム)上の電話機によって収集されます。私はChannelApiを使用しています。DataApiは配信を確実にしますが、私の目的はできるだけ早くセンサーデータをリアルタイムで提供することです。データ損失はそれほど重要ではありません。私は現在、別のアプリケーションでこれを使用するためにノートパソコンのADBを読んでいます。

問題点は何ですか?
プログラムのいくつかの段階でシステム時間を取得した後、データのキューイングはADB接続の障害でもなく、入力ストリームまたは出力ストリームもプリントライタでもないことがわかりました。 sensorEventが発生したので、機能onSensorChanged()は即座に呼び出されないようです。下記の時間はsensorListenerがSENSOR_DELAY_GAME(に設定し、各onSensorChanged()イベントのために、データとして送信もSENSOR_DELAY_FASTESTを占めている、説明するために、

  • を1行目:onSensorChanged()
  • 第二と呼ばれている時計にSystem.currentTimeMillis()行:sensorEvent

から(ミリ秒ナノから行く1000000で割った値)event.timestampこれは、いくつかのセンサ読取値の概要:

1479407287638; 687629; 
1479407287638; 687649; 
1479407287681; 687669; 
1479407287681; 687689; 
1479407287718; 687709; 
1479407287718; 687729; 
1479407287768; 687749; 
1479407287768; 687769; 
1479407287810; 687789; 
1479407287811; 687809; 

あなたが得る時間の間の違いを見てみると:

-  - 
0; 20 
49; 20 
0; 20 
37; 20 
0; 20 
50; 20 
0; 20 
42; 20 
1; 20 

あなたが見ることができるように、sensorTimestampは読みが20msごとがあることを示しています。ただし、onSensorChanged()は、同じ間隔で、または少なくとも一貫性で呼び出されません。指摘すると、たとえ高速であっても、チャネルとその入出力ライターは、より長い期間または時間であっても、バイト/メッセージの量に追いつくことができます。

私は何を試しましたか?

私はウェアラブルアプリを書いonSensorChangedからすべてのタスクを削除しようとしましたが、最初は他の場所で開始されたスレッド

if (data_transfer) {      // if interaction is initiated 
    new Thread(new convertAndSend(sensorName,timestamp,accuracy,values)).run(); 
} 

でそれらを実行onSensorChanged

public void onSensorChanged(SensorEvent event) { 
    final int accuracy = event.accuracy; 
    final long timestamp = event.timestamp; 
    final float[] values = event.values; 
    final String sensorName = event.sensor.getStringType(); 

    if (data_transfer) {      // if interaction is initiated 
     printWriter.println(message); 
    } 
} 

からすべてのタスクを削除しようとしました活動として、私はまた(バックグラウンドで実行されている)サービスに変換

public class SensorService extends Service implements SensorEventListener { 
... 
    public void onSensorChanged(SensorEvent event) { 
     client.sendSensorData(event.sensor.getType(), event.accuracy, event.timestamp/1000000, event.values); //client takes care of outputstream 
    } 
} 

最後に、を別のスレッド(thisthisに基づいて実装することを考えました。そのため、アクティビティスレッドまたはサービススレッドの影響を受けません。しかし、これも前に述べたのと同じ課題/挑戦を示しました。

public class SensorListenerThread implements Runnable { 

    private static final String TAG = "SensorService"; 
    private final static int SENS_ROTATION_VECTOR = Sensor.TYPE_ROTATION_VECTOR; 

    SensorManager mSensorManager; 

    @Override 
    public void run() { 
     Log.d("RunTag", Thread.currentThread().getName()); // To display thread 

     mSensorManager = ((SensorManager)getSystemService(SENSOR_SERVICE)); 

     Looper.prepare(); 
     Handler handler = new Handler(){ 
      // process incoming messages here?? 
     }; 
     Sensor rotationVectorSensor = mSensorManager.getDefaultSensor(SENS_ROTATION_VECTOR); 
     MySensorListener msl = new MySensorListener(); 
     mSensorManager.registerListener(msl, rotationVectorSensor, SensorManager.SENSOR_DELAY_FASTEST, handler); 

     Looper.loop(); 
    } 

    private class MySensorListener implements SensorEventListener { 
     public void onAccuracyChanged (Sensor sensor, int accuracy) {} 
     public void onSensorChanged(SensorEvent sensorEvent) { 
      Log.d("ListenerTag", Thread.currentThread().getName()); // To display thread 
     } 
    } 

} 

ヘルプ!
私の理解は、onSensorChangedイベントが呼び出されますが、センサーのタイムスタンプと同じ時刻に表示されないということです。速度とチャンネルの使用は非常にうまく動作しますが、この問題を回避する方法はありません。私は私の心の中に計画Bを持っています:私は私のラップトップで実行しているプログラムを計算/調整するためにセンサーのタイムスタンプを使用することができます。しかし、私は通信の遅れ(センサ - >ラップトップアプリケーションから調整するのが好きですが、これは毎回変更される変数である可能性があります)や、通信の不一致を調整しない方が望ましいです(値の印刷、各読みについて計算する必要があります)。

私はこの長い(申し訳ありません!)ストーリーが意味を持ち、誰かが私を助けたり正しい方向に向けることを願っています。

+0

もっと複雑なやりとりを処理するには、[ワーカースレッド](https://developer.android.com/guide/components/processes-and-threads.html)の使用をチェックするとよいでしょう。与えられたドキュメントで述べたように、UIスレッドから渡されたメッセージを処理するには、ワーカースレッドで[Handler](https://developer.android.com/reference/android/os/Handler.html)を使用することを検討してください。おそらく最も良い解決策は、[AsyncTaskクラス](https://developer.android.com/reference/android/os/AsyncTask.html)を拡張することです。これは、UIと対話する必要があるワーカースレッドタスクの実行を簡略化します。 – Teyam

+0

こんにちは@Teyam、私はonSensorchanged()メッセージを受け取るためだけにワーカースレッドを実装しました。もうUIスレッドに干渉しません。しかし、この場合にもメッセージは一定の時間間隔で受信されます。私は、センサーメッセージ(タイムスタンプ)とメッセージの受信(onSensorChanged)の間の時間が一貫しているような方法でコードを構築することが可能であることを期待していました。私は現在、センサーのタイムスタンプを見て、出現の対応する時間を計算する必要があります。 – Dave

答えて

0

このように、onSensorChanged()の一貫性のある呼び出しに頼るのは不可能かもしれません。したがって、私はonSensorChangedの時刻ではなくタイムスタンプを使用しています。私は同じことをするために他の人にアドバイスをします!

関連する問題