Android - MANAGE_EXTERNAL_STORAGE

Hi folks,

I need my Android apps to be able to read/write to/from external storage; rather than a private area where the user is unable to access / share them.

It seems that modern Android prevents this, without use of both MANAGE_EXTERNAL_STORAGE and ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION …

Has anybody out there patched Juce to add this - seemingly essential :slight_smile: - capability?

Best to all,

Pete

NB: I’ve found it essential to add this:
android:requestLegacyExternalStorage=“true”

… and make sure you target 29 or earlier.

Otherwise, even if the user-side permissions are set, your app cannot write to the storage device.

Worked without this on Android SDK 30 with emulator.

Failed until I made this change, on Samsung Galaxy device running Android 10.

Pete

Android 11 gets rid of that flag, you need to use the SAF (Storage Access Framework) for public file stuff, this would either be NDK or Java API.

SAF is essentially a file service using URI and streams.

https://www.techotopia.com/index.php/An_Android_Storage_Access_Framework_Example
https://www.zoftino.com/how-to-create-browse-files-option-in-android

There are many parts tot his, the links are just some simple examples.

Hi @TeotiGraphix,

Yeah - the problem is with applications / engines that use extensive FILE* based file system access, using SAF would require an onerous rewrite! :slight_smile:

Not really sure what else can be done at this point…

Pete

Well you either rewrite the file access or eventually you will not be able to update the app.

I was in the same situation, old school dev using old school methods and it came back to bite me. :wink:

Either way SAF is pretty powerful once it’s plumbed into the application.

Well, indeed!

It does seem crazy to me that I can write for every other platform without having to worry about stuff like this; but, anyhow…

Either way, this is something that the Juce team need to embrace, I think.

Best wishes,

Pete

1 Like

Well I have been doing Android since 2010, so… I have no comment other than yeah.

Either way, this is something that the Juce team need to embrace, I think.

There are file system abstractions that could solve this, I think JUCE doesn’t prioritize Android, for obvious reasons, but it is like a half dead limb being dragged behind a horse. :slight_smile:

This is why they want the legacy gone, devs were cheating for years. :slight_smile: SAF Came in KitKat which was about 2015-2016 or so.

When Android started it was like the new horizon, walled garden debates, all that. Now for some reason Google realized years later (since the start) that full access to a file system would get exploited, imagine that.

Sure. But surely the sandboxing provided by the OS would prevent any issues? Certainly the case with iOS, where there are zero problems with using standard C / C++ file system APIs.

Anyhow, it is what it is :slight_smile: - no point in my moaning about it I guess :wink:

Pete

That was my point, Android had to appeal to “all others” at that time, iOS was proprietary, so they started straight out with a file access sandbox. Android needed to get established and IMHO is why this mess even exists and was not taken care of at the start (sandboxed file system).

Sometimes it’s just plain depressing talking as an Android dev. :wink: So many mistakes along the way, but again it’s what happens when you have to serve “all the rest”, they cut corners. (purely opinion of course)

Oh, I agree! I’ve done Android consultancy on and off for years - but have managed to avoid it (through choice!) recently. The system and tools have kept changing, and it is generally hard work.

iOS and macOS are much more stable in terms of platform and toolchains, so I’ve found them much more pleasurable to work with.

1 Like

Hello, tell me, how can I update the application to a newer version in this case?

@OliviaParcker I think you have to hope the Juce team will change the implementation of the File class (and related classes?) to work with SAF on Android.

Either that, or write your own adaptor layer for Android, that sits around SAF.

Best wishes, Pete

Yes, for now you have to create a native extension(bridge code) in either Java or NDK C++.

yes, I hope Juce will change the quality of the class.
Thank you
Olivia Parker, developer of “work time

1 Like

This thread has helped me solve my file access problems on Android, thank you all. I’ve given the exact details of how I implemented these changes in one of my later posts in the following thread:

Hopefully this will be helpful for anybody having this issue in future who, like me, didn’t initially know where the various parameters should be added.

2 Likes

Bumping this…

It seems that of August 2021, Android apps need be built with the target SDK version 30 to allow them to upload to Google Play. That also means the ‘requestLegacyStorage’ trick in the manifest does not work anymore. It thus seems that using the Storage Access Framework is the way to go to allow JUCE apps to read and write to shared folders and to allow export or import of files in your app.

If so, is this something we should request as feature to the JUCE team to prevent everybody to have to write their custom code? If there would be a simple way to use the JUCE URL to be able to read or write a file using SAF would be awesome…

I was preparing to release the app and now ran into this show-stopper…
From earlier tweaking I know it’s dangerous to play around with Projucer/AndroidStudio/Java/NDK/C++.
Suddenly everything blows up or gets overwritten when you save or reload the wrong thing :face_with_spiral_eyes:
For now the Android exporter is pretty useless - except you want to deal with apk’s and maybe cash money :laughing:

Please JUCE team, give us a perspective on this.

We’ve now improved support for working with content:// URLs, such as those returned from native file choosers, through the AndroidDocument API:

Internally, AndroidDocument uses the DocumentsContract API on Android. As a result, it should be possible to read and write to shared locations, as long as the user has granted access to those locations via the native file picker. Unfortunately, DocumentsContract doesn’t support as many operations as File, so changing the implementation of File directly would have resulted in several unsupported or partially-working functions. We decided instead to add a new class which only supports operations that work on all platforms.

1 Like