11

Android Api 29 has big changes regarding files and folders. I have not found a way so far to create a folder in the internal storage that is public visible. Every folder I create can be seen by my app only.

I write an app that creates data files that shall be picked up by other apps, for instance the Total Commander to copy them to a destination. Everything worked fine until I activated Api 29. Some of my clients DO use pixel phones and they use Android 10.

How can I create a folder and files in Android 10 that are public?

This has been deprecated:

Environment.getExternalStorageDirectory();
Environment.getExternalStoragePublicDirectory(type);

and when I use

File root = context.getExternalFilesDir(null);

The created files can only be seen by my app. How can I achieve the behavior that was valid before Android 10?

Thanks in advance.

Grisgram
  • 3,105
  • 3
  • 25
  • 42
  • 1
    Use ACTION_OPEN_DOCUMENT_TREE or ACTION_OPEN_DOCUMENT. With them you can reach all external storage both internal and microSD card. Life is good. – blackapps Oct 11 '19 at 20:15
  • @blackapps with these two actions the user is presented with an open dialog ? Is there a way to access ( read / write ) withou an open dialog API 29 / 30 – MindRoasterMir Sep 08 '20 at 12:17
  • No, there is not. The user is invoked using these actions. – blackapps Sep 08 '20 at 12:21

2 Answers2

10

when I use File root = context.getExternalFilesDir(null); The created files can only be seen by my app

They can be seen by any app that uses the Storage Access Framework (e.g., ACTION_OPEN_DOCUMENT), if the user chooses the document that you place in that directory.

I write an app that creates data files that shall be picked up by other apps

Other apps have no access to external or removable storage on Android 10, except in the limited directories like getExternalFilesDir() or via non-filesystem means (ACTION_OPEN_DOCUMENT, MediaStore).

How can I create a folder and files in Android 10 that are public?

Use getExternalFilesDir() and related methods on Context. Or, use ACTION_CREATE_DOCUMENT or ACTION_OPEN_DOCUMENT_TREE and use the Storage Access Framework. In either case, the resulting documents can be used by other apps that also use the Storage Access Framework.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks. I created it now using the system UI with these actions. – Grisgram Nov 13 '19 at 18:34
  • @CommonsWare , how telgram / whatsapp etc apps are able to create folders in external storage ? – Ashish singh Aug 13 '20 at 15:20
  • 1
    @Ashishsingh: They are probably using `android:requestLegacyExternalStorage = "true"` – CommonsWare Aug 13 '20 at 15:22
  • 1
    @CommonsWare : Checked in Telegram source code ,they have TargetSDKVersion = 28 instead of android:requestLegacyExternalStorage = "true" – Ashish singh Aug 13 '20 at 16:48
  • @Ashishsingh: They will need to change very soon, as otherwise they will no longer be able to distribute updates on the Play Store. – CommonsWare Aug 13 '20 at 17:41
  • @CommonsWare I have API 30 - I am building an app to read pdf with "barteksc:android-pdf-viewer" and I am unable to oepn pdf using pdfViewer.formFile(), from download folder, because API 30 gives no access to external storage. Does it mean user have to always select the pdf file to open it ? Is it sane from google now ? – MindRoasterMir Sep 08 '20 at 12:25
  • @MindRoasterMir: "Does it mean user have to always select the pdf file to open it ?" -- well, ideally, you let the user choose where the PDF resides. It is the user's phone and the user's PDF, after all. "Does it mean user have to always select the pdf file to open it ?" -- for `Downloads/` specifically, I think the answer is yes. While we regained read access to parts of external storage, I think that specific directory still only shows us our own files, not files put there by other apps. – CommonsWare Sep 08 '20 at 12:31
  • @CommonsWare Thanks for the reply. I have also tried to create a folder where downloads is. Not possible with code only. If I create it with ACTION_CREATE_DOCUMENT can I then access it from the code ? without forcing the user to open with open dialog ? – MindRoasterMir Sep 08 '20 at 12:37
  • @CommonsWare and with the PDF File I want to make an app for only one pdf book and want to let user read the book after opening the app rather than forcing him to open a document, It works from assets but I want the app to remain small in size and download the book pdf at first use and then let the user use it afterwards. – MindRoasterMir Sep 08 '20 at 12:39
  • 1
    @MindRoasterMir: Well, `ACTION_CREATE_DOCUMENT` shows a "dialog". If you are asking if you can avoid a *second* dialog, then yes, that should work. Use `takePersistableUriPermissions()` on a `ContentResolver` with the `Uri` that you get from `ACTION_CREATE_DOCUMENT`. "download the book pdf at first use" -- um, download it yourself to `getFilesDir()`, and you don't have to worry about any of the rest of the problems. – CommonsWare Sep 08 '20 at 12:40
  • @CommonsWare seems to be interesting. here is my question, if you post me an answer with a little code example, I will accept it as an aasnwer thaks. I am going to try it . https://stackoverflow.com/questions/63787884/bartekscandroid-pdf-viewer3-0-0-beta-5-how-to-pdfview-fromfile-filenotfou – MindRoasterMir Sep 08 '20 at 12:45
  • @CommonsWare download it yourself to getFilesDir(), do you have an example? I was only successful to download pdf with DownloadManager and it lets me only to download in public directories i.e Downloads. – MindRoasterMir Sep 08 '20 at 13:01
  • @MindRoasterMir: Use OkHttp: https://stackoverflow.com/a/29012988/115145 – CommonsWare Sep 08 '20 at 14:15
  • @MindRoasterMir. I will give it a try. and the trick of persistantUripermission after first opening with open dialogue is working. Thanks – MindRoasterMir Sep 08 '20 at 14:16
  • @MindRoasterMir , Telegram source code is open source https://github.com/DrKLO/Telegram – Ashish singh Sep 09 '20 at 06:00
1

Starting from Android 10, you should use SAF, and let user choose the directory using ACTION_OPEN_DOCUMENT_TREE.

If you need a simple example. You can find it here

Alternatively, you could use requestLegacyExternalStorage = true in manifest when your app is not newly released. But, this is something that should not be used for future release, as this is a short-term solution provided by Google.

Note: In future releases of Android, user will not be able to pick the whole external file directory and Downloads directory, so unfortunately, keep in mind that we are not going to have access to these as well! For more information you can click here

Khamidjon Khamidov
  • 6,783
  • 6
  • 31
  • 62