Ich muss Dateien nach Dateinamen in Android-Apps im nativen C/C++-Code öffnen. Beim nativen Code handelt es sich um Bibliotheken von Drittanbietern, die ich lieber nicht ändern würde, aber sie erfordern oft einen Dateinamen als Argument zum Lesen/Schreiben von Dateien. Mit der „Scoped Storage“-API von Google und der Deaktivierung des nativen Zugriffs auf Dateien in Android 10 oder höher ist das ein echtes Problem.
Eine bekannte Lösung besteht darin, einen Dateideskriptor zu erhalten und „proc /self/fd/FD_NUMER"-Trick, etwa:
ParcelFileDescriptor mParcelFileDescriptor = null;
Code: Select all
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!
Die Übergabe an nativen C/C++-Code funktioniert, aber
nur, wenn sich die Datei im Hauptspeicher des Telefons befindet. Wenn der Benutzer versucht, eine Datei zu öffnen, die sich auf einer externen SD-Karte befindet, die in den Telefonsteckplatz eingelegt ist, funktioniert dies nicht – es gibt keine Leseberechtigung für die auf diese Weise geöffnete Datei. Ich kann nur die int-Nummer des Dateideskriptors abrufen und fdopen(fd) verwenden. Dies erfordert jedoch eine Änderung des Quellcodes von Bibliotheken Dritter (Open Source oder lizenziert) und verursacht große Kopfschmerzen, wenn die Originalquelle dieser Bibliotheken aktualisiert wird.
Gibt es eine bessere Lösung? zu diesem Problem? Und nein, ich möchte die Lösung mit dem Hinzufügen von
nicht hören
Code: Select all
android:requestLegacyExternalStorage="true"
zum Anwendungsabschnitt „AndroidManifest.xml“ – Google droht, dies in der nächsten Android-Version im Jahr 2020 zu deaktivieren, daher ist eine dauerhafte Lösung erforderlich. Eine andere einfache, aber dumme Lösung besteht darin, die gesamte (vielleicht riesige) Datei, die der Benutzer zu öffnen versucht, in ein privates App-Verzeichnis zu kopieren. Dumm und nutzlos...