2

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

该程序不断在 arraylist 上给我一个 NullPointerException ,我不知道为什么。任何帮助将不胜感激!

编辑:抱歉,如果缩进关闭或代码不清楚,这是一项学校作业,我的截止日期很严格,所以我必须急于使代码可用,然后才能担心可读性或效率。

编辑 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++) { 
4

2 回答 2

1

traces如果您的按钮开始或停止被单击,您只是在初始化变量。

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

于 2013-01-17T02:37:19.390 回答
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();
    }
}
于 2013-01-17T02:38:07.400 回答