我需要在原生 C/C++ 代码中的 Android 应用程序中按文件名打开文件。本机代码是我不想修改的第 3 方库,但它们通常需要文件名作为读取/写入文件的参数。使用 Google 的“范围存储”API 并在 Android 10 或更高版本中禁用对文件的本机访问,这是一个真正的问题。
一个众所周知的解决方案是获取文件描述符并使用“proc/self/fd/FD_NUMER”技巧,例如:
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!
将此传递给本机 C/C++ 代码有效,但前提是文件位于手机主存储中。如果用户试图打开插入电话插槽的外部 SD 卡上的文件,则它不起作用 - 以这种方式打开的文件没有读取权限。我只能获取文件描述符 int 编号并使用 fdopen(fd)。但这将需要修改 3rd 方库(开源或许可)的源代码,并且每当这些库的原始源更新时,这是一个非常令人头疼的问题。
有没有更好的解决这个问题的办法?不,我不想听到添加的解决方案
android:requestLegacyExternalStorage="true"
到 AndroidManifest.xml 应用程序部分 - 谷歌威胁要在 2020 年的下一版本 Android 中禁用它,因此需要一个永久的解决方案。另一个简单但愚蠢的解决方案是将用户尝试打开的整个(可能是巨大的)文件复制到私有应用程序目录中。愚蠢而无用...