如何在android中读取和写入有关加速度计的数据?

时间:2013-01-17 02:28:36

标签: java android

我正在尝试为android编写一个步数计数器。它目前包含一个活动中的四个按钮: 一个按钮,用于开始记录存储在arraylist中的加速计数据。 arraylist采用Trace类型,这是我创建的类,用于保存一个传感器更改的数据。我还有一个停止按钮,以及从文本文件中读取或写入数据的按钮。

这个程序一直给我一个关于arraylist的NullPointerException,我无法弄清楚原因。任何帮助将不胜感激!

编辑:对不起,如果缩进或代码不清楚,这是一个学校作业,我在严格的截止日期,所以我必须急于使代码可用,然后才能担心可读性或效率。< / p>

编辑2:我不再有任何例外,但我仍然无法正确读/写。我能够成功写入文件,然后以某种方式停止运行。

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++) { 

2 个答案:

答案 0 :(得分:1)

如果点击按钮开始或停止,则只是初始化traces变量。

如果在此之前单击“写入”按钮,则引用仍为空。

答案 1 :(得分:1)

看起来好像traces尚未在onSensorChanged()readButton.setOnClickListener中初始化,尽管没有完整的源代码或堆栈跟踪很难说清楚。如果traces是“//全局字段”,那么您应该将其初始化为声明的位置,例如:

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

编辑第二个问题

我的猜测是,如果文件已经存在,使用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();
    }
}