简体   繁体   中英

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? 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. I would like the data to be in CSV format.

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.
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.
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 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. You shouldn't try to use out if you just failed to initialize it. The try block should ensclose all the lines using out , and not just the line initializing it.

walkData could also be null. 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
                }
             }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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