I need to open files by file name in Android apps within native C/C++ code. The native code are 3rd party libraries that I would prefer not to modify, but they often require file name as an argument to read/write files. With the Google's "scoped storage" API and disabling native access to files in Android 10 or later, it's a real problem.
One well known solution is to get a file descriptor and use "proc/self/fd/FD_NUMER" trick, like:
ParcelFileDescriptor mParcelFileDescriptor = null;
String getFileNameThatICanUseInNativeCode(Context context, DocumentFile doc) {
try {
Uri uri = doc.getUri();
mParcelFileDescriptor =
context.getContentResolver().openFileDescriptor(uri, "r");
if (mParcelFileDescriptor != null) {
int fd = mParcelFileDescriptor.getFd();
return "/proc/self/fd/" + fd;
}
}
catch (FileNotFoundException fne) {
return "";
}
}
// Don't forget to close mParcelFileDescriptor when done!
Passing this to native C/C++ code works, but only if the file is in phone main storage. If the user tries to open a file that is on external SD card inserted into the phone slot, it does not work - there is no read permission for the file opened this way. I can only grab the file descriptor int number and use fdopen(fd). But this will require modifying the source code of 3rd party libraries (open source or licensed), and a big headache, whenever the original source of these libraries is updated.
Is there any better solution to that problem? And no, I don't want to hear the solution with adding
android:requestLegacyExternalStorage="true"
to AndroidManifest.xml application section - Google threatens to disable that in the next version of Android in 2020, so a permanent solution is needed. Another easy but dumb solution is copying the entire (maybe huge) file that the user tries to open into private app directory. Dumb and useless...
Update May 19, 2020: just discovered: the READ_EXTERNAL_STORAGE permission lets you read files, but not list directory contents, when running on Android 11 and targeting API 30 (or higher in the future). I submitted it as a bug and just got "This is working as intended" reply (https://issuetracker.google.com/issues/156660903). If anyone cares, please comment there, and also at their "survey": https://google.qualtrics.com/jfe/form/SV_9HOzzyeCIEw0ij3?Source=scoped-storage I have no idea how to proceed developing apps on Android with all these limitations.
Тo anyone contemplating switching their app to SAF, I post my app's monthly average ratings chart from Google Play developer console. In January 2020 I released the first version of my app using SAF instead of regular file access, see attached image. As more and more users update, the ratings go down, a lot of comments that I destroyed a good app. The app even now has well over 1 million active installs.
Update May 17 2020: Google has finally conceded and is permitting READ_EXTERNAL_STORAGE permission in Android 11 and beyond. After spending months in converting my apps to Storage Access Framework (SAF), I now take a week or two to convert it back, at least the reading files part, to regular file access... Thank you, Google! Thank you sarcastically, for the lost time and effort, and thank you sincerely, for at least partially understanding our point!
This is not the end of the "scoped storage" nightmare. Google is "improving" it again in Android 11 (see https://developer.android.com/preview/privacy/storage) - all we did so far to make it work may soon be thrown out to garbage.
Please consider commenting on and supporting my request to not limit Scoped Storage access to Download directory in Android 11, and/or improve the system "Files" interface: https://issuetracker.google.com/issues/151759806
I'm seriously considering giving up further development for the Android platform... It seems to me that arrogant, controlling "parents" took over Android system evolution, who think the rest of us are little children, and they need to install safety gates all around at our houses, seriously limiting our freedom of movement. So sad.
Greg
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With