2

Android用の歩数カウンターを書こうとしています。現在、1 つのアクティビティに 4 つのボタンが含まれています。arraylist に保存されている加速度計データの記録を開始するためのボタンです。arraylist は型 Trace を取ります。これは、1 つのセンサー変更のデータを保持するために作成したクラスです。停止ボタンと、テキスト ファイルからデータを読み書きするためのボタンもあります。

このプログラムは、arraylist で NullPointerException を出し続けますが、その理由がわかりません。どんな助けでも大歓迎です!

編集: インデントがずれていたり、コードが不明確だったりして申し訳ありません。これは学校の課題であり、締め切りが厳しいので、読みやすさや効率性を心配する前に、急いでコードを使用できるようにする必要があります。

編集 2: 例外は発生しなくなりましたが、まだ適切に読み書きできません。ファイル1に正常に書き込むことができましたが、どういうわけか機能しなくなりました。

package com.myApp.playpool;

    //imports

public class MainActivityBAK extends Activity implements SensorEventListener{

    //global fields (traces is instantiated here as new arraylist)

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

        acceleration=(TextView)findViewById(R.id.acceleration);
        startButton = (Button) findViewById(R.id.startButton);
        stopButton = (Button) findViewById(R.id.stopButton);
        readButton = (Button) findViewById(R.id.readButton);
        writeButton = (Button) findViewById(R.id.writeButton);

        sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sm.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);

        dataFilePath = getString(R.string.data_file_path);
        acceleration.setText("Current file: " + dataFilePath);

        lastCheck = System.currentTimeMillis();

        defineButtons();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    @Override
    public void onSensorChanged(SensorEvent event1) {

        if (running && ((System.currentTimeMillis() - lastCheck) > 1000)) { 
            acceleration.setText("X: "+event1.values[0]+"\nY: "+event1.values[1]+"\nZ: "+event1.values[2]);
            traces.add(new Trace(System.currentTimeMillis(), event1.values[0], event1.values[1], event1.values[2]));
            lastCheck = System.currentTimeMillis();
        }

    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    public void defineButtons() { //defines onClick methods for the buttons

        startButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                traces = new ArrayList<Trace>();
                running = true;
            }
        });

        stopButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                traces = new ArrayList<Trace>();
                running = false;
            }
        });

        readButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                try {
                    scan = new Scanner(new File(dataFilePath));
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                while (scan.hasNext()) {
                    String str = scan.nextLine();
                    String [] strings = str.split(";");
                    double time = Double.parseDouble(strings[0]);
                    float x = Float.parseFloat(strings[0]), y = Float.parseFloat(strings[1]), z = Float.parseFloat(strings [2]);
                    traces.add(new Trace(time, x, y, z));
                }

                Toast.makeText(getBaseContext(),
                        ("Done reading to SD file: '" + dataFilePath + "'"),
                        Toast.LENGTH_SHORT).show();
                scan.close();
            }
        });

        writeButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                try {
                    File file = new File(dataFilePath);
                    print = new PrintWriter(file);
                    file.createNewFile();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                for (int i = 0; i < traces.size(); i++) {
                    double time = traces.get(i).time;
                    float x = traces.get(i).x, y = traces.get(i).y, z = traces.get(i).z;
                    print.println(time + ";" + x + ";" + y + ";" + z + ";");
                }
                print.close();
                Toast.makeText(getBaseContext(),
                        ("Done writing to SD file: '" + dataFilePath + "'"),
                        Toast.LENGTH_SHORT).show();
            }
        });

    }

}

write メソッドの for ループでクラッシュしているようです。

for (int i = 0; i < traces.size(); i++) { 
4

2 に答える 2

1

tracesボタンの開始または停止がクリックされた場合にのみ、変数を初期化しています。

その前に「書き込み」ボタンをクリックすると、参照はまだ null です。

于 2013-01-17T02:37:19.390 に答える
1

完全なソース コードまたはスタック トレースなしでは判断が難しいですが、tracesが初期化されていないように見えonSensorChanged()ます。が「// グローバル フィールド」のreadButton.setOnClickListener場合は、次のように、宣言されている場所で初期化する必要があります。traces

protected ArrayList<Trace> traces = new ArrayList<Trace>();

2番目の質問の編集

File.createNewFile()ファイルが既に存在する場合、このメソッドを使用しても機能しないと思います。次のサンプルのように、別のアプローチを試してみてください。

Writer writer = null;
try {
    OutputStream out = mContext.openFileOutput(dataFileName, Context.MODE_PRIVATE);
    writer = new OutputStreamWriter(out);

    for (int i = 0; i < traces.size(); i++) {
        double time = traces.get(i).time;
        float x = traces.get(i).x, y = traces.get(i).y, z = traces.get(i).z;
        writer.write(time + ";" + x + ";" + y + ";" + z + ";");
    }
}
finally {
    if (writer != null) {
        writer.close();
    }
}
于 2013-01-17T02:38:07.400 に答える