1

I need a app specific folder to store pdf files that my app is downloading from the internet. The app needs full access to the folder. I dont want to use system built-in picker provided via SAF.

So what is the correct way to create a folder in the "Root" folder of the device.

Andyson
  • 55
  • 1
  • 7

1 Answers1

2

You said in the comments the PDF files have to be public to the user (in the file explorer or in a PDF reader for example) so I updated my answer.

Before Android R from 2020 it was easy for an app to create files in the (public) external storage directory. "external" only means that the directory is not an internal app directory. It doesn't mean that the directory is part of an external SD card for example. Files in this directory (and child directories except the "Android" folder) are shown by the gallery app for example or by PDF readers.

In my Android API level 33 emulator the path to the (public) external storage directory is /storage/emulated/0. The directory also contains some default child directories named "Documents", "Download" or "Pictures" for example. Because the path is not guaranteed to always be the same you retrieve it using getExternalStorageDirectory or getExternalStoragePublicDirectory for one of the child directories.

So before Android R all you had to do is request permission WRITE_EXTERNAL_STORAGE and put your file into the directory returned by getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).

Unfortunately Android gets more strict every release and now WRITE_EXTERNAL_STORAGE has no effect any more and getExternalStoragePublicDirectory is also deprecated.

So to put your file into the (public) external Documents directory on Android R and later there seem to be multiple ways.

One way is to declare permission MANAGE_EXTERNAL_STORAGE in the manifest:

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

Then ask the user to enable it manually:

Uri u = Uri.parse("package:" + BuildConfig.APPLICATION_ID);
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, u);
startActivity(intent);

After this you can write to the folder returned by getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS) which points to /storage/emulated/0/Documents on my emulator.

There are two more ways described in this answer. One way is to use ACTION_CREATE_DOCUMENT and the other is to use MediaStore.

I also want to say that after placing your file in the (public) external storage directory it may take some time until it appears in PDF readers. You can send intent ACTION_MEDIA_SCANNER_SCAN_FILE so this happens faster. See this answer.

zomega
  • 1,538
  • 8
  • 26