I'm unable to create directory in android 10. It's working on devices till android Oreo.

I tried two ways for creating folders.

Using File.mkdir():

   File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
                    if (!f.isFile()) {
                        if (!(f.isDirectory())) {
                               success =  f.mkdir();
                        }

Here, the variable success is always false which means the directory isn't created.

Using Files.createDirectory():

   File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
                    if (!f.isFile()) {
                        if (!(f.isDirectory())) {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                try {
                                    Files.createDirectory(Paths.get(f.getAbsolutePath()));
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    Toast.makeText(getApplicationContext(), R.string.unable_to_download, Toast.LENGTH_LONG).show();
                                }
                            } else {
                                f.mkdir();
                            }
                        }

which causes this exception:

pzy64.pastebinpro W/System.err: java.nio.file.AccessDeniedException: /storage/emulated/0/Pastebin
pzy64.pastebinpro W/System.err:     at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:391)
pzy64.pastebinpro W/System.err:     at java.nio.file.Files.createDirectory(Files.java:674)

I've implemented the run-time permissions and

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

are all set.

Solution 1

As was first disclosed back in March 2019, you no longer have access by default to arbitrary locations on external storage or removable storage on Android 10+. This includes Environment.getExternalStorageDirectory() and other methods on Environment (e.g., getExternalStoragePublicDirectory().

For Android 10 and 11, you can add android:requestLegacyExternalStorage="true" to your <application> element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work.

Otherwise, your choices are:

  • Use methods on Context, such as getExternalFilesDir(), to get at directories on external storage into which your app can write. You do not need any permissions to use those directories on Android 4.4+. However, the data that you store there gets removed when your app is uninstalled.

  • Use the Storage Access Framework, such as ACTION_OPEN_DOCUMENT and ACTION_CREATE_DOCUMENT.

  • If your content is media, you can use MediaStore to place the media in standard media locations.

Solution 2

For Android 10, you can add

android:requestLegacyExternalStorage="true"

to your element in the manifest. This opts you into the legacy storage model, and your existing external storage code will work. This fix will not work on Android R and higher though, so this is only a short-term fix.

Solution 3

There are more restrictions in Android API 30

you can only write in your app-specific files

 File dir_ = new File(context.getFilesDir(), "YOUR_DIR");
 dir_.mkdirs();

or in the external storage of your app Android/data

File dir_ = new File(myContext.getExternalFilesDir("FolderName"),"YOUR_DIR");

UPDATE

this answer provided another solution https://stackoverflow.com/a/65744517/8195076

UPDATE

another way is to grant this permission in manifest

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

like this answer https://stackoverflow.com/a/66968986/8195076

Solution 4

Since Q beta 4 it's possible to opt-out of that feature by:

targeting api 28 (or lower) using requestLegacyExternalStorage manifest attribute:

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting Android Q. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

Solution 5

You can use public directory to save files in Android 11 like this:

dir = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getPath()
    + "/foldername");

if (!dir.exists()) {
     dir.mkdir();
     Toast.makeText(getApplicationContext(), "not exist", Toast.LENGTH_SHORT).show();
}

Solution 6

This works for me and I think it's functional on Android 10>

ContentResolver resolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/Folder Example");
String path = String.valueOf(resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues));
File folder = new File(path);
boolean isCreada = folder.exists();
if(!isCreada) {
    folder.mkdirs();
}

Solution 7

only use

android:requestLegacyExternalStorage="true"

in manifests