0

I've read several questions and the Android Guide on saving files but can't figure out where I'm going wrong.

I'm trying to save an image to a new folder in the pictures directory of the SD Card.

I have <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> in the manifest.

It is throwing an exception in this method

String storageStage =  Environment.getExternalStorageState();

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory (
            Environment.DIRECTORY_PICTURES),"/WordResolver");

    mediaStorageDir.mkdirs();

    if (! mediaStorageDir.exists()){ 
            if(! mediaStorageDir.mkdirs()) {

                Log.d("WordResolver", "Failed to create directory"); 
                return null;
            }
    }

    //Creating Media File Name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;

    if (type == MEDIA_TYPE_IMAGE) {
        mediaFile = new File (mediaStorageDir.getPath() + File.separator + "IMG_WR" +
                timeStamp + ".jpg");
    } else {
            return null;
        }

    return mediaFile;

}

The error it is throwing is a NullPointerException. The the reason it is a strange problem is because the program is trying to save in the internal storage rather than in the SD card as you can see here:

1

Where as I was under the impression that Environment.getExternalStoragePublicDirectory would save to the external storage?

Here's the stack trace:

                                                                            java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.aaron.wordresolver/com.example.aaron.wordresolver.cameraShot}: java.lang.NullPointerException: file
                                                                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                                                at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                at android.os.Looper.loop(Looper.java:148)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                             Caused by: java.lang.NullPointerException: file
                                                                                at android.net.Uri.fromFile(Uri.java:452)
                                                                                at com.example.aaron.wordresolver.cameraShot.getOutputMediaFileUri(cameraShot.java:55)
                                                                                at com.example.aaron.wordresolver.cameraShot.onCreate(cameraShot.java:45)
                                                                                at android.app.Activity.performCreate(Activity.java:6237)
                                                                                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                                                                                at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                                                                                at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                at android.os.Looper.loop(Looper.java:148) 
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                                at java.lang.reflect.Method.invoke(Native Method) 
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

I'm using an emulated device if that matters!

Cheers

COYG
  • 1,538
  • 1
  • 16
  • 31

1 Answers1

1

Where as I was under the impression that Environment.getExternalStoragePublicDirectory would save to the external storage?

It is. You can tell that by looking at the path. There are roughly zero devices in use today where external storage is an "SD card". An SD card is removable storage, and it is inaccessible via the filesystem on Android 4.4+.

With regards to your stack trace, you need to determine whether your problem is related to mediaStorageDir or type, as you will get the same symptoms in either case. Bear in mind that if your targetSdkVersion is 23 or higher, and you are running on Android 6.0 or higher, you need to request your external storage permission at runtime.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I didn't know you had to also request the permissions in 23 or higher, that sorted it. Good man! – COYG May 19 '16 at 14:47
  • @CommonsWare, Hey man, you said this "There are roughly zero devices in use today where external storage is an "SD card". An SD card is removable storage, and it is inaccessible via the filesystem on Android 4.4+.". I know this is a very old post but can you clarify what you meant with "_An SD card is removable storage, and it is inaccessible via the filesystem on Android 4.4+_"? – blue2609 Apr 26 '19 at 11:29
  • @zer0_reaper: External storage is on-board flash on almost every device. The `READ_EXTERNAL_STORAGE` and `WRITE_EXTERNAL_STORAGE` permissions affect this on-board flash, not removable storage. You do not have access to arbitrary filesystem locations on removable storage, only some limited ones tied to your app. Ideally, stop thinking about the filesystem entirely, and start using the Storage Access Framework, as eventually, you will not have access to most of *external* storage either, starting with Android Q. – CommonsWare Apr 26 '19 at 12:20
  • @CommonsWare Hi mate, thanks so much for the reply. Okay, so I do know that ***External Storage*** in Android Environment does not necessarily mean the External SD Card. It means the primary shared storage that can be mounted on a host computer, a space that can be accessed as a media storage and it's public (everyone can see it, not just the application itself). However, I have never heard of this **Storage Access Framework**, this is entirely new to me and when you said that we won't have access to external Storage starting from Android Q, what was that about? Thanks so much btw! – blue2609 Apr 26 '19 at 21:14
  • @zer0_reaper: "I have never heard of this Storage Access Framework" -- it has been around for five years: https://developer.android.com/guide/topics/providers/document-provider. "when you said that we won't have access to external Storage starting from Android Q, what was that about?" -- see https://commonsware.com/blog/2019/03/25/death-external-storage-what-now.html then https://commonsware.com/blog/2019/04/22/death-external-storage-more-story.html and then https://commonsware.com/blog/2019/04/25/death-external-storage-serenity-now.html – CommonsWare Apr 26 '19 at 21:17
  • @CommonsWare Ahh wow, right right okay I'll have a ready on your blog and yeah I literally just googled SAF a little bit. I'm asking a lot of questions because I'm kinda new to Android development mate (well it's been 8/9 months but I didn't get into it seriously until a couple months ago). Also, I posted this question on stackoverflow as well which is very relevant to the topic [Saving file to external SD Card](https://stackoverflow.com/questions/55863907/android-cannot-save-file-to-external-sd-card-even-though-i-have-the-correct-pat). Seriously though, thanks for answering, I'll have a read! – blue2609 Apr 26 '19 at 21:32