1

ステップがいつ発生するかを把握しようとしています。そこで、これを行うために countSteps というメソッドを作成しました。問題は、while ループで新しいデータを取得し続け、onSensor に戻るとは思わないため、スタックしてしまうことです。indexoutofboundsexception: invalid index 2,size 2 というエラーも表示されます。

だから私の最初の質問は、while ループなしで私が持っているメソッドを実装する他の方法はありますか? 2 つ目は、indexoutofboundsexception を修正する方法です。public class MainActivity extends Activity implement SensorEventListener {

    private SensorManager mSensorManager;
    private Sensor mRotationVector;
    private Sensor mAccelerometer;
    private TextView mTextView4;
    private TextView mTextView5;
    private TextView mTextView6;
    private TextView mTextView7;
    private TextView mTextView8;
    float a, b, c, d, x, y, z, xyz;
    float[] retVals = new float[3];
    float avg = 10;
    float factor = (float) 1.15;
    ArrayList<Float> accelData = new ArrayList<Float>();
    public int peakCounter = 0;
    public int underAvgCounter = 0;

    public void countSteps() {
        int n = 0;
        float controlPoint = accelData.get(0);
        while (accelData.iterator().hasNext()) {
            if (accelData.get(n) != accelData.get(n + 1)) {
                if (accelData.get(n) > accelData.get(n + 1)) {
                    if (accelData.get(n) < controlPoint) {
                        n++;
                    } else {
                        if (accelData.get(n) < avg * factor) {
                            underAvgCounter++;
                        }
                        peakCounter++;
                        n++;
                    }
                } else {
                    controlPoint = accelData.get(n + 1);
                    n++;
                }
            } else {
                n++;
            }
            peakCounter -= underAvgCounter;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView4 = (TextView) findViewById(R.id.textView4);
        mTextView5 = (TextView) findViewById(R.id.textView5);
        mTextView6 = (TextView) findViewById(R.id.textView6);
        mTextView7 = (TextView) findViewById(R.id.textView7);
        mTextView8 = (TextView) findViewById(R.id.textView8);
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager
                .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        accelData.add((float) 0);
    }

    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this, mAccelerometer,
                SensorManager.SENSOR_DELAY_GAME);
    }

    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSensorChanged(SensorEvent event) {
            x = event.values[0];
            y = event.values[1];
            z = event.values[2];
            xyz = (float) Math.sqrt((x * x) + (y * y) + (z * z));
            accelData.add(xyz);
            mTextView7.setText("magnitude accel " + xyz);
            countSteps();
            mTextView8.setText("steps " + peakCounter);

    }
}
4

3 に答える 3

2
 while (accelData.iterator().hasNext()) {

コレクションに少なくとも 1 つの要素がある場合は、常に true です。

  1. accelData.iterator()毎回新しいイテレータを作成し、
  2. accelData.iterator().hasNext()コレクション内の最初の要素を毎回チェックします
  3. n++ は end に到達するまで実行され、
  4. accelData.get(n + 1)スローIndexOutOfBoundsException

forできることの 1 つは、ループを使用することです。

 for (int n = 0; n < accelData.size() - 1; n++) {  // size-1 is used since you're accessing n+1 index
     if (accelData.get(n) != accelData.get(n + 1)) {
         if (accelData.get(n) > accelData.get(n + 1)) {
                if (accelData.get(n) >= controlPoint) {
                    if (accelData.get(n) < avg * factor) {
                        underAvgCounter++;
                    }
                    peakCounter++;                        
                }
        } else {
            controlPoint = accelData.get(n + 1);
        }
    } 
}
peakCounter -= underAvgCounter;
于 2013-08-09T14:47:57.753 に答える
1
Iterator it = accelData.iterator();
while(it.hasNext()) {
  float elem = it.next();
  ...
}
于 2013-08-09T14:43:22.203 に答える
0

IndexOutOfBounds では、次のコード コード スニペットが問題になります。

accelData.get(n) および accelData.get(n + 1)

iterator().hasNext() のチェックを行っていますが、n+1 要素の存在は保証されません。

無限ループは、 iterator().next() を使用して次の要素に移動したことがないためだと思います。理解を深めるために、単純なイテレータ コードを参照してください。

また、for、do while、while、および Java の高度な for ループなどのループ手法を使用できますが、問題はありません。重要なのは、効率的で読みやすいかどうかだけです。

于 2013-08-09T15:00:22.753 に答える