2

I am getting a FileNotFoundException on the line where I declare and initalize the FileOutputStream. I'm not really sure why this is happening particularly since I make a new File before I create the FileOutputStream. I did not post the entire function, but basically it unregisters the gyroscope and accelerometer sensors and writes their output to a .csv file. Any help would be greatly appreciated because I have no idea what is wrong.

protected void stopRecording() throws IOException{
    sm.unregisterListener(this);

    
    File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    //file name is the current date and time
    cal = Calendar.getInstance(TimeZone.getDefault());
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_hh:mm:ss");
    
    String output = sdf.format(cal.getTime()).toString();
    File file = new File(path, output+ "_A" + ".csv");
    FileOutputStream fos = new FileOutputStream(file);
    out = new BufferedWriter(new OutputStreamWriter(fos));
    
    for( int i = 0; i < a.size(); i++){
        try {
            out.write(a.get(i));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }


03-22 11:43:40.845 18684-18684/? W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Pictures/2016-03-22_11:43:40_A.csv: open failed: EACCES (Permission denied)
03-22 11:43:40.859 18684-18684/? W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:452)
03-22 11:43:40.859 18684-18684/? W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
03-22 11:43:40.859 18684-18684/? W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
03-22 11:43:40.859 18684-18684/? W/System.err:     at com.example.alex.parkinsonsdiseaseapp.TestEnvironmentActivity.stopRecording(TestEnvironmentActivity.java:172)
03-22 11:43:40.859 18684-18684/? W/System.err:     at com.example.alex.parkinsonsdiseaseapp.TestEnvironmentActivity$3.onClick(TestEnvironmentActivity.java:120)
03-22 11:43:40.859 18684-18684/? W/System.err:     at android.view.View.performClick(View.java:5226)
03-22 11:43:40.859 18684-18684/? W/System.err:     at android.view.View$PerformClick.run(View.java:21266)
03-22 11:43:40.859 18684-18684/? W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
03-22 11:43:40.859 18684-18684/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
03-22 11:43:40.859 18684-18684/? W/System.err:     at android.os.Looper.loop(Looper.java:168)
03-22 11:43:40.859 18684-18684/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5845)
03-22 11:43:40.859 18684-18684/? W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
03-22 11:43:40.859 18684-18684/? W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
03-22 11:43:40.859 18684-18684/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
03-22 11:43:40.859 18684-18684/? W/System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
03-22 11:43:40.859 18684-18684/? W/System.err:     at libcore.io.Posix.open(Native Method)
03-22 11:43:40.859 18684-18684/? W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
03-22 11:43:40.860 18684-18684/? W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:438)
03-22 11:43:40.860 18684-18684/? W/System.err:  ... 13 more
user207421
  • 305,947
  • 44
  • 307
  • 483
Alex Cauthen
  • 497
  • 5
  • 12
  • 32

3 Answers3

-1

I think this is worth a try (its good practice anyway). Felt too long for a comment, hence an answer.

After you call the constructor on file to create a new File object, check if it is readable, writeable [Ref: API]. If not, you would want to ensure that it is, before attempting to open a FileOutputStream on it [Ref: API].

Also, I have seen instance where you need to make a call to file.createNewFile() to ensure a file is created. So, add that before the fos declaration? Shouldn't make a world of difference; but worth a try, I think.

EDIT:

Make this change.

File path = Environment.getExternalStorageDirectory();

and ensure you have

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

in your manifest. I wish the Android logcat was more particular about this stuff.

Debosmit Ray
  • 5,228
  • 2
  • 27
  • 43
  • I added it in, but no luck. – Alex Cauthen Mar 22 '16 at 01:16
  • @AlexCauthen Nothing even if you call `setWritable(..)`?! – Debosmit Ray Mar 22 '16 at 01:17
  • @AlexCauthen I'm sure you have the file write permissions set in the manifest? – Debosmit Ray Mar 22 '16 at 01:18
  • I'm not familiar with setWriteable. I will look it up. As far as permissions go I did not think you needed it to create internal files, but I do have the externals files permission. – Alex Cauthen Mar 22 '16 at 01:23
  • Check the edit I made. Worst case, change the `File path` to what I mentioned, and go over all the changes I suggested. And everything should be good. – Debosmit Ray Mar 22 '16 at 01:24
  • If it means anything, this exact code is working for my friends who are also working on the project haha... I will have no way of testing if your edit worked though because I don't have an SD card. – Alex Cauthen Mar 22 '16 at 01:37
  • @AlexCauthen I have done this stuff successfully, on devices that have no mountable SD card slot. So, that is not the issue here. Don't be confused about the word 'external' [REFERENCE](http://stackoverflow.com/questions/6049114/environment-getexternalstoragedirectory-does-not-return-the-path-to-the-removabl) – Debosmit Ray Mar 22 '16 at 01:41
  • @AlexCauthen Alternatively, use internal storage to test functionality [ref](http://developer.android.com/guide/topics/data/data-storage.html#filesInternal) – Debosmit Ray Mar 22 '16 at 01:44
  • This is all a complete waste of time. It just replicates the checks that already happen inside the operating system, and replicates them via multiple system calls instead of one. – user207421 Jul 01 '20 at 03:20
-1

You need to ensure that you are putting your FileOutputStream and BufferedWriter lines in the try block. Also, use different delimiters for the time other than ":".

protected void stopRecording() throws IOException{
    sm.unregisterListener(this);


    File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    //file name is the current date and time
    cal = Calendar.getInstance(TimeZone.getDefault());
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_hh.mm.ss");

    String output = sdf.format(cal.getTime()).toString();
    File file = new File(path, output+ "_A" + ".csv");

    for( int i = 0; i < a.size(); i++){
        try {
            FileOutputStream fos = new FileOutputStream(file);
            out = new BufferedWriter(new OutputStreamWriter(fos));
            out.write(a.get(i));
        } catch (IOException e1) {
            e1.printStackTrace();
            FileOutputStream fos = new FileOutputStream(file);
            out = new BufferedWriter(new OutputStreamWriter(fos));
        }
    }
  • 1
    This catches an exception, but doesn't solve the underlying problem – Debosmit Ray Mar 22 '16 at 01:17
  • I tried it out, and it works for me. The compiler gave me an error saying that it needed to catch the FileNotFoundException, which the IOException does. Once I did this and changed the time delimiter, it ran fine. The only other thing I can think of is what the value of path is. – Mike Keathley Mar 22 '16 at 01:21
  • 1
    That is not the issue. In certain specification combinations on Android, certain things weirdly stop working. Catching exception are very important, but if the functionality is integral to the app, you need to find some other way to get the job done, or pin-point what exactly the issue is. Just because the catch block wasn't hit on your device, doesn't ensure that it wont be hit in someone else's. – Debosmit Ray Mar 22 '16 at 01:23
-1

I guess because you can not creat csv file directly just using File class. You can change File file = new File(path, output+ "_A" + ".csv"); to File file = new File(path, output+ "_A" + ".txt"); Also the output format is illegal at some point.

Adam Lyu
  • 431
  • 1
  • 5
  • 17
  • The `File` class doesn't care about csv any more than any other kind of file, or name, and the change you have proposed is ultimately merely cosmetic. Your final sentence is not helpful in the least. – user207421 Jul 01 '20 at 03:22