6

I've been developing an app on nougat that creates a directory in the external storage.

I used to do it like this:

final File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Chords/Processed Audio");
dir.mkdirs();

This code does not seem to work on API 26 (Android Oreo). The directory is not created.

How can I achieve the same thing, preferably that works on all android version from API 21 to API 26?

Daniele
  • 4,163
  • 7
  • 44
  • 95
  • 1
    Please explain, **in detail**, what "does not seem to work" means. Note that you should not use string concatenation to create file paths. Use `final File dir = new File(new File(Environment.getExternalStorageDirectory(), "Chords"), "Processed Audio");`. – CommonsWare Sep 29 '17 at 13:39
  • I'll try as you suggested. What I mean by "Does not work" is simply that the directory isn't created, while on Nougat it does – Daniele Sep 29 '17 at 13:43
  • some logcat would be useful. What about permissions? Have you granted permission to write external storage for your application? – pleft Sep 29 '17 at 13:51
  • ok It worked simply buy changing the `File` declaration as @CommonsWare suggested. Thanks. Please write the answer and I'll accept it. I think it will be useful for other people too. – Daniele Sep 29 '17 at 13:55

2 Answers2

7

I have no problems running your existing code on a Nexus 5X running Android 8.0. Using adb shell ls /storage/emulated/0, I see Chores/, and inside there I see Processed Audio/. This is for an app with WRITE_EXTERNAL_STORAGE permission, including runtime permissions.

That being said, ideally, do not use string concatenation to create File objects. Instead, use:

final File dir = new File(new File(Environment.getExternalStorageDirectory(), "Chords"), "Processed Audio");
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I also had all the permissions set, I've checked multiple times. Changing to your way of declaring instead of String concatenation worked for me though. Thanks again. – Daniele Sep 29 '17 at 14:01
  • Hi, I am using this plugin (https://github.com/JoschkaSchulz/cordova-plugin-image-resizer) in cordova app. I am facing same issue (https://github.com/JoschkaSchulz/cordova-plugin-image-resizer/issues/42). I see this code folder = new File(Environment.getExternalStorageDirectory() + "/" + folderName); and changed as you mentioned, but still its not working. Please let us know if you find any error in this. – NKurapati Jun 04 '18 at 10:25
  • @NKurapati: I suggest that you edit your GitHub issue and provide a reproducible test case along with a complete set of output (e.g., stack trace). – CommonsWare Jun 04 '18 at 10:33
  • @CommonsWare: As i am accessing through JavaScript, I am getting "Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference" message only. – NKurapati Jun 11 '18 at 08:52
  • @CommonsWare: I have updated github issue. Its failing to create directory. Please check and let us know if you found any error. thanks. – NKurapati Jun 18 '18 at 09:50
0

@Daniele, see https://stackoverflow.com/a/44455957/966789 and https://stackoverflow.com/a/33031091/966789 (Android added new permission model for Android 6.0 (Marshmallow). If your targetSdkVersion >= 23 and you are running on a Marshmallow (or later) device, you may need to enable runtime permissions. You should also read more about the runtime permissions changes. If you are using targetSdkVersion >= 24, you also must configure a FileProvider as show in this section. The example below uses com.codepath.fileprovider and should match the authorities XML tag specified)

Alexander Lubyagin
  • 1,346
  • 1
  • 16
  • 30