3

I need to read a file stored in android root directory(/storage/emulated/0/MyFolder) while launching the app first time.

It was possible till API level 28 by using Environment.getExternalStorageDirectory(), But after I migrated to API level 29, Environment.getExternalStorageDirectory() deprecated and stopped working with below message.

This method was deprecated in API level 29. To improve user privacy, direct access to shared/external storage devices is deprecated. When an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible to apps. Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.

Also I tried Context().getExternalFilesDir(null) which was returning the following path only "/storage/emulated/0/Android/data/com.myapp.appid/files/", but I need to access a file in "/storage/emulated/0/" path.

So how to read the file in location "/storage/emulated/0/MyFolder" in legal way when running with target API level 29?

Natarajan
  • 3,241
  • 3
  • 17
  • 34
  • No, I tried `Context().getExternalFilesDir(null)`, but it returns application's private file path which is not an expected one. – Natarajan Dec 24 '19 at 08:25
  • `Context().getExternalFilesDir(null)` was returning the following path only "/storage/emulated/0/Android/data/com.myapp.appid/files/", but I need to access file in "/storage/emulated/0/" path. – Natarajan Dec 24 '19 at 08:27
  • I don't mind marking this question duplicate, But people who thinking this questions as duplicate please read my question description fully and flag duplicate. Because answers provided in following link is not resolved my issue. https://stackoverflow.com/questions/57116335/environment-getexternalstoragedirectory-deprecated-in-api-level-29-java – Natarajan Dec 24 '19 at 10:19
  • `need to read a file stored in android root directory(/storage/emulated/0/MyFolder)`. But who made that folder there? And when? And who wrote a file in it? And when? – blackapps Dec 24 '19 at 10:28
  • You can let the user pick that file with ACTION_OPEN_DOCUMENT. – blackapps Dec 24 '19 at 10:29
  • some files(those are related to app) will be added(in /storage/emulated/0/MyFolder) by device owner and when device owner installing the app, the app needs to check if that file is exist and read it, if exist. That's the concept. – Natarajan Dec 24 '19 at 10:37
  • is there any way to check at-least "if file is exist"? – Natarajan Dec 24 '19 at 10:38
  • I can implement to pick file with ACTION_OPEN_DOCUMENT option, but I don't want to show this picker if file is not exist. So I need to check if file is exist first. – Natarajan Dec 24 '19 at 10:40
  • How do you think the device owner will create folder MyFolder? And how wil the device owner put a file in it? – blackapps Dec 24 '19 at 10:45
  • Have you tried file.exists()? – blackapps Dec 24 '19 at 10:46
  • one way is to set targetSdkVersion to 28 while compileSdkVersion to 29 and use something like File folder = new File(Environment.getExternalStorageDirectory().getPath()+ subfolder); I have been using in android 10 . – Akash Chaudhary Apr 02 '20 at 14:56

1 Answers1

2

The only way is to ask the user to pick the file with Intent#ACTION_OPEN_DOCUMENT and then it is unlikely that the user will be able to pick that directory any way.

Google's stated intent for this change is to stop applications from making a proliferation of files/folders all over the place and give users control. The concept of files paths outside of your App's private directories no longer exists, you have to use MediaStore or SAF (Storage Access Framework) for non private stuff.

Going forward you will not be able to have your own App's public folder like this (unless on external SD card), you can only store stuff as Video, Image, Audio or Download (All other file types).

Note: that currently a number of Manufacturers on pre Android 10 provide a Document Provider that gives you access to the root of the Primary partition as well as the External SD card, but if you look at what is provided in the plain Android OS emulator images or Google's documentation you will not see a provided for the primary root partition as this would break Google's stated intent for this change.

See https://developer.android.com/training/data-storage/

and more specifically

https://developer.android.com/training/data-storage/shared/documents-files

You can ask the user to select a folder (which will be under the restricted public locations) and then you can programmatically access and check and files in this location. See https://developer.android.com/training/data-storage/shared/documents-files#grant-access-directory

You can ask the user once and then store the permission they have given you to access files/folders with https://developer.android.com/training/data-storage/shared/documents-files#persist-permissions

Note: There is a temporary workaround until Android 11 by enabling legacy mode.

Andrew
  • 8,198
  • 2
  • 15
  • 35
  • So there is no way to check if a file exist in "/storage/emulated/0/" path programmatically? – Natarajan Dec 24 '19 at 08:48
  • Google's stated intent for this change is to stop applications from making a proliferation of files/folders all over the place and give users control. The concept of files paths outside of your App's private directories no longer exists, you have to use MediaStore or SAF (Storage Access Framework) for non private stuff. There is a temporary workaround until Android 11 by enabling legacy mode. – Andrew Dec 24 '19 at 08:59
  • `You can ask the user to select a folder (which will be under the restricted public locations) `. No. No restriction at all. Complete access to primary partition. Complete access to micro SD card. And with SAF the concept of 'file' and folder paths stay but different. – blackapps Dec 24 '19 at 10:14
  • 1
    `Going forward you will not be able to have your own App's public folder`. Of course you can. And every app will using ACTION_OPEN_DOCUMENT_TREE. No user will refuse to select primary partition or sd card if an app he wants asks for it. – blackapps Dec 24 '19 at 10:33
  • While a lot of Pre Android 10 phone manufacturers provide a primary partition Document provider, You don't see this type of provider in the Emulator OS images or Google's documentation and I don't expect this practise to continue (Yes you will be able to use the root of an SD card if your phone supports SD cards) – Andrew Dec 26 '19 at 18:42
  • Then google's stated intent is an ass! plain and simple. – Andrew S Apr 30 '20 at 16:01