6

I'm really struggling with this for some reason and am hoping someone can help point me in the right direction.

I am targeting Android 11 / API 30 which is where the trouble seems to all stem from. Targeting lower might work for me - but it seems like Google is going to force me down this path eventually so I might as well just figure this out.

My apps typically write files out to the standard

getExternalFilesDir(null)

This gives me a path on the device which is

/storage/emulated/0/Android/data/com.domain.testapp/files

I also tried other types, like:

getExternalFilesDir(Environment.DIRECTORY_PICTURES)

results in

/storage/emulated/0/Android/data/com.domain.testapp/files/Documents

My app has no trouble actually writing files out to this location. In Android 11 I have to jump through some hoops with the local file explorer to see these files - but they do exist on the device.

I am now trying to give the user some ability to see the files and share the files and that's where I'm stumped!

This code below results in no files found

File filePath = this.getExternalFilesDir(null);
String filePathString = filePath.toString();

ArrayList<String> myData = new ArrayList<>();
File fileDir = new File(filePathString);

String[] files = fileDir.list();

if(files.length == 0){
    Log.w(APPID, "NO FILES IN FOLDER");
}

Yes - I know the File and .toString() is not needed - but I was logging them out each step because I thought I was crazy.

I know for a FACT that there are a dozen or so files in the folder this is pointing to in this app. This app created the files. Shouldn't it be able to see the files in the folder???

Manifest has the following permissions - which I dont think it needs all of:

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

No permissions show as denied to the app

I thought about using the external storage - but it seems like this is even harder in Android 11? Or is that really an easier path to take?

I did try playing with this, but it seems deprecated and soon to be gone?

File downloadFilePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

which is this folder on my device

/storage/emulated/0/Download

And I can definitely see the files in there with any file explorer.

Any thoughts on how to get access to the files this app created?

I'm probably missing something really obvious.

Any suggestions welcomed!!

Ed Kuhner
  • 369
  • 1
  • 2
  • 11
  • `In Android 11 I have to jump through some hoops with the local file explorer to see these files - ` You will not see your apps specific files with local file explorers on an Android 11 device. Why are you making such a confusing remark? – blackapps Apr 05 '21 at 07:01
  • `results in /storage/emulated/0/Android/data/com.domain.testapp/files/Documents ` No. Not Documents but Pictures. Please dont confuse us. – blackapps Apr 05 '21 at 07:02
  • For getExternalFilesDir you do not need any permission and for listing your files your code (although a mess) should do. – blackapps Apr 05 '21 at 07:06
  • `/storage/emulated/0/Download` Your app can write files there and list the files and subdirs in it with the same code you used before. Requesting legacy external storage makes no sense as that is only for Android 10 devices. – blackapps Apr 05 '21 at 07:08
  • Sorry you don't like my question? – Ed Kuhner Apr 06 '21 at 01:30
  • Google deprecated the ability to get the external public folder for Download - https://developer.android.com/reference/android/os/Environment#getExternalStoragePublicDirectory(java.lang.String) – Ed Kuhner Apr 06 '21 at 01:31
  • And my code doesnt list any files in the getExternalFilesDir - that's my entire problem - so my code may be a mess - but it doesn't work at all - and I agree it should! – Ed Kuhner Apr 06 '21 at 01:32
  • 1
    If your app could create files in the public Download folder then your app should be able to list them. It is unclear what you want more. The owner of the file is important in Android 11. For getExternalFilesDir only your app has access and if it created files there it can list them. You are not even telling if .list() returns null or an empty list. – blackapps Apr 06 '21 at 07:12
  • Good points - list() was returning empty. what is making me nervous now is that I'm using getExternalStoragePublicDirectory() and it's deprecated How else do you get the Documents or Photos folders? – Ed Kuhner Apr 07 '21 at 12:06
  • 1
    Its deprecated yes. But they work as before. So you can use them. – blackapps Apr 07 '21 at 12:29

6 Answers6

9

I Think I Have An Answer?

The more I read about this - it appears that Android 10 went one way, and then Android 11 back tracks it a little and re-enables some of the direct file path access.

Hopefully I'm right on this and won't have to come back and re-do things again down the road

So the answer is to use the requestLegacyExternalStorage in the Manifest - even though it's got all kinds of warnings

And then I created a folder in Documents with this

File filePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)+File.separator+"MyAppFolder");
filePath.mkdirs();

And Now I can write to this and read from it.

Anyway - this seems to work for me on Android 9, 10 and 11. So hopefully the trend forward continues.

Ed Kuhner
  • 369
  • 1
  • 2
  • 11
  • 2
    This doesn't solve the problem now-a-days. – Sakhawat Hossain Jun 14 '21 at 08:42
  • 1
    It does. android studio will tell you it's deprecated - but it works. you need this in the manifest as well: android:requestLegacyExternalStorage="true" – Ed Kuhner Jun 15 '21 at 11:42
  • This way you just bypass current requirement of Scoped storage. But you did not follow scoped storage best practice for that. – Umeshkumar D. Nov 11 '21 at 05:17
  • What is your targetSdkVersion inorder to access storage using Android 11? – Pakz Feb 10 '22 at 07:30
  • How did u fix this in Android 11 devices with compilesdkversion 30 or above ? – Erum Jan 17 '23 at 10:13
  • it will work if your **target** SDK version is Android 10 and the device version is Android 11. But if you try to target Android 11 or above, `android:requestLegacyExternalStorage` is ignored. that's why you got warnings and you would need to re-do it. – Adam Burley Jan 23 '23 at 16:51
2

Google Play Store requires that you use SCOPED STORAGE and not SHARED STORAGE, so you should avoid to use "requestLegacyStorage".

This mean you cannot access files on the sd card if the user doesn't directly choose them. To select a file from external storage you need the user interaction (:

There's another solution with Android >= 10 and it is the permission "MANAGE_EXTERNAL_STORAGE" which let you choose an application which can access the external storage. But the user must do all the actions so it isn't a really good solution :/

If your problem is about files you are taking with user interaction that are in the external storage, you can enable the access to the file uri by using a fileProvider (from example when you take a photo).

Have a nice day and a nice coding (:

Z3R0
  • 1,011
  • 10
  • 19
1

Add below line in your Android manifest file in application tag.

android:requestLegacyExternalStorage="true"
Dharmik Mavani
  • 107
  • 1
  • 8
  • 2
    This is incorrect for Android 11 - according to Google: Caution: After you update your app to target Android 11 (API level 30), the system ignores the requestLegacyExternalStorage attribute when your app is running on Android 11 devices, so your app must be ready to support scoped storage and to migrate app data for users on those devices. https://developer.android.com/training/data-storage/use-cases#opt-out-scoped-storage – Ed Kuhner Apr 06 '21 at 01:25
  • Turns out you are correct - but that wasn't the entire solution for me because I still could not read the contents of this folder properly. – Ed Kuhner Apr 06 '21 at 02:59
0

Do you have the following permission in your manifest? You say you have write and manage permission, but I think you actually require read permission to read external storage.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
IChung
  • 347
  • 1
  • 3
  • 8
0

For Android 11 and above Use this before requesting

Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                        Uri uri = Uri.fromParts("package", getPackageName(), null);
                        intent.setData(uri);
                        startActivity(intent);

To retrview and Store :

        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+"/FolderName/"+new_filename+"/");
        File[] allfiles = null;
        allfiles = file.listFiles();

        Log.i(TAG, String.valueOf(allfiles.length));
Gopal Reddy
  • 36
  • 1
  • 5
-1

please describe your question properly

if you want to pickup file from external storage then also apply in manifest requestlegegyexternalstorage=true

see in these snap - http://prntscr.com/114kqxp

or if you want to store the file in the device then you have to use file provider in android

for file provider example

please visit link - couldn't attach file send email android 11

axar
  • 539
  • 2
  • 17