简体   繁体   English

写入文件时出现空指针异常 - Android Studio

[英]Null Pointer Exception when writing to a File - Android Studio

My app crashes every time I go to send the data gathered by the sensor.每次我去发送传感器收集的数据时,我的应用程序都会崩溃。 The error I am given is as follows:我给出的错误如下:

06-20 14:50:00.784  22983-22983/com.example.adam.proj2 E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
        at com.example.adam.proj2.SensorActivity.onClick(SensorActivity.java:124)
        at android.view.View.performClick(View.java:3549)
        at android.view.View$PerformClick.run(View.java:14393)
        at android.os.Handler.handleCallback(Handler.java:605)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:4944)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
        at dalvik.system.NativeStart.main(Native Method)

Here is the code for gathering the sensor data:以下是收集传感器数据的代码:

 public void onSensorChanged(SensorEvent event) {
    float x = event.values[0];
    ArrayList<Float> enrolAcc = new ArrayList<>();
    ArrayList<Float> authAcc = new ArrayList<>();
    TextView textEnrol = (TextView) findViewById(R.id.textView);
    if (choice == 1) {
        mPreviousAcc = mCurrentAcc;
        mCurrentAcc = (float) Math.sqrt((double) (x * x));
        float delta = mCurrentAcc - mPreviousAcc;
        mDiffAcc = mDiffAcc * 0.9f + delta;
        if (enrolAcc.size() < 100) {
            enrolAcc.add(x);

        } else {
            enrolAcc.remove(0);
            enrolAcc.add(x);
        }
        walkData = enrolAcc.toString();
        textEnrol.setText(walkData);
    }

Here is the code for writing to the file (this happens onClick of a button):这是写入文件的代码(这发生在单击按钮时):

 public void onClick(View v) {
    switch (v.getId()) {
        case R.id.enrolBtn:
            choice = 1;
            Toast.makeText(this, "Enrolment Mode Selected", Toast.LENGTH_SHORT).show();
            break;
        case R.id.authBtn:
            choice = 2;
            Toast.makeText(this, "Authentication Service Starting", Toast.LENGTH_SHORT).show();
            break;
        case R.id.sendBtn:
            choice = 3;
            String baseDir = android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
            String fileName = "Walk Data.csv";
            String filePath = baseDir + File.separator + fileName;
            File f = new File(filePath);
            FileOutputStream out = null;
            try {
                out = new FileOutputStream(f);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            try {
                out.write(walkData.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            android.net.Uri u1 = Uri.fromFile(f);
            Intent sendIntent = new Intent(Intent.ACTION_SEND);
            sendIntent.putExtra(Intent.EXTRA_STREAM, u1);
            sendIntent.setType("text/html");
            startActivity(sendIntent);
            break;
    }
}

From what I can see the exception is generated by the out.write method?从我可以看出异常是由 out.write 方法生成的? The array list holding the sensor values is stored in the walkData string so that the string can be then written in the csv file stored on the external device storage.保存传感器值的数组列表存储在 walkData 字符串中,以便可以将该字符串写入存储在外部设备存储器上的 csv 文件中。 I would like the data to be in CSV format.我希望数据为 CSV 格式。

I am stumped and cannot figure out how to prevent this, any help would be much appreciated.我很难过,无法弄清楚如何防止这种情况发生,任何帮助将不胜感激。

You get the error because you are trying to write to a READ ONLY file.您收到错误是因为您正在尝试写入READ ONLY文件。
The line out = new FileOutputStream(f) throws an exception: java.io.FileNotFoundException: /storage/sdcard/Walk Data.csv: open failed: EROFS (Read-only file system) , but you actually ignore it, so out = NULL and then you get the other exception.out = new FileOutputStream(f)抛出异常: java.io.FileNotFoundException: /storage/sdcard/Walk Data.csv: open failed: EROFS (Read-only file system) ,但您实际上忽略了它,所以out = NULL然后你会得到另一个异常。
Move your file to a place where you can write to it -将文件移动到可以写入的位置 -

    String fileName = "Walk Data.csv";
    String baseDir = getFilesDir() + "/" + fileName;
    File f = new File(baseDir);

Look at the code:看代码:

        try {
            out = new FileOutputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            out.write(walkData.getBytes());

The exception is thrown at the last line.在最后一行抛出异常。 So, what could possibly be wrong at that line?那么,那条线上可能有什么问题呢?

out could be null. out可能为空。 out will be null if the file is not found, since you catch that exception and pretend nothing wrong happened at the line before, leaving out as null.如果未找到文件, out将为空,因为您捕获了该异常并假装之前该行没有发生任何错误,而将out保留为空。 You shouldn't try to use out if you just failed to initialize it.你不应该尝试使用out ,如果你只是无法初始化它。 The try block should ensclose all the lines using out , and not just the line initializing it. try 块应该包含所有使用out的行,而不仅仅是初始化它的行。

walkData could also be null. walkData也可以为空。 But since we don't know where it comes from, we can't say.但由于我们不知道它来自哪里,我们不能说。 Use your debugger to know which is null.使用您的调试器知道哪个是空的。 And whatever the answer is, fix your exception handling code.不管答案是什么,修复你的异常处理代码。 It should look like它应该看起来像

        FileOutputStream out = null;
        try {
            out = new FileOutputStream(f);
            out.write(walkData.getBytes());

            android.net.Uri u1 = Uri.fromFile(f);
            Intent sendIntent = new Intent(Intent.ACTION_SEND);
            sendIntent.putExtra(Intent.EXTRA_STREAM, u1);
            sendIntent.setType("text/html");
            startActivity(sendIntent);
        } catch (IOException e) {
            // TODO signal the error to the user. Printing a stack trace is not enough
        }
        finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // TODO signal the error to the user. Printing a stack trace is not enough
                }
             }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM