From de642e971d9316b9b7a4ea8b4c9a0474780dd3c1 Mon Sep 17 00:00:00 2001 From: Relintai Date: Tue, 7 Feb 2023 02:58:31 +0100 Subject: [PATCH] Ported: Implement file provider capabilities. The previously used file sharing api was restricted after Android N causing the engine to crash whenever used on devices running Android N or higher. - m4gr3d https://github.com/godotengine/godot/commit/b04c9a71f47a5dec7ed146122c39a775ad877d4c --- platform/android/export/export_plugin.cpp | 4 ++ platform/android/java/lib/AndroidManifest.xml | 10 +++++ .../res/xml/pandemonium_provider_paths.xml | 11 ++++++ .../pandemonium/PandemoniumIO.java | 39 +++++++++++++------ 4 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 platform/android/java/lib/res/xml/pandemonium_provider_paths.xml diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 8e4c562c4..65c431106 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -958,6 +958,10 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref &p encode_uint32(is_resizeable, &p_manifest.write[iofs + 16]); } + if (tname == "provider" && attrname == "authorities") { + string_table.write[attr_value] = get_package_name(package_name) + String(".fileprovider"); + } + if (tname == "supports-screens") { if (attrname == "smallScreens") { encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]); diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml index 98bcb3cd2..b8451db86 100644 --- a/platform/android/java/lib/AndroidManifest.xml +++ b/platform/android/java/lib/AndroidManifest.xml @@ -20,6 +20,16 @@ android:exported="false" /> + + + + diff --git a/platform/android/java/lib/res/xml/pandemonium_provider_paths.xml b/platform/android/java/lib/res/xml/pandemonium_provider_paths.xml new file mode 100644 index 000000000..424032cdf --- /dev/null +++ b/platform/android/java/lib/res/xml/pandemonium_provider_paths.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/PandemoniumIO.java b/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/PandemoniumIO.java index 8fb8356d1..55cfebb90 100644 --- a/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/PandemoniumIO.java +++ b/platform/android/java/lib/src/net/relintai/pandemonium/pandemonium/PandemoniumIO.java @@ -49,6 +49,9 @@ import android.view.Display; import android.view.DisplayCutout; import android.view.WindowInsets; +import androidx.core.content.FileProvider; + +import java.io.File; import java.util.List; import java.util.Locale; @@ -84,29 +87,43 @@ public class PandemoniumIO { // MISCELLANEOUS OS IO ///////////////////////// - public int openURI(String p_uri) { + public int openURI(String uriString) { try { - String path = p_uri; - String type = ""; - if (path.startsWith("/")) { - //absolute path to filesystem, prepend file:// - path = "file://" + path; - if (p_uri.endsWith(".png") || p_uri.endsWith(".jpg") || p_uri.endsWith(".gif") || p_uri.endsWith(".webp")) { - type = "image/*"; + Uri dataUri; + String dataType = ""; + boolean grantReadUriPermission = false; + + if (uriString.startsWith("/") || uriString.startsWith("file://")) { + String filePath = uriString; + // File uris needs to be provided via the FileProvider + grantReadUriPermission = true; + if (filePath.startsWith("file://")) { + filePath = filePath.replace("file://", ""); } + + File targetFile = new File(filePath); + dataUri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".fileprovider", targetFile); + dataType = activity.getContentResolver().getType(dataUri); + } else { + dataUri = Uri.parse(uriString); } Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); - if (!type.equals("")) { - intent.setDataAndType(Uri.parse(path), type); + if (TextUtils.isEmpty(dataType)) { + intent.setData(dataUri); } else { - intent.setData(Uri.parse(path)); + intent.setDataAndType(dataUri, dataType); + } + + if (grantReadUriPermission) { + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } activity.startActivity(intent); return 0; } catch (ActivityNotFoundException e) { + Log.e(TAG, "Unable to open uri " + uriString, e); return 1; } }