summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
authorFredia Huya-Kouadio <fhuya@meta.com>2023-01-26 14:03:04 -0800
committerFredia Huya-Kouadio <fhuya@meta.com>2023-02-01 01:03:50 -0800
commitbdbeb0772f3e9edf6c110c8e0797a3fdfb364559 (patch)
tree74afffdb047b8cedc81b817566eaa6d9900ba17c /platform/android
parentf7397a5ac6bffc0df24cae61b8aabfa4a3b65347 (diff)
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.
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/export/export_plugin.cpp4
-rw-r--r--platform/android/java/lib/AndroidManifest.xml10
-rw-r--r--platform/android/java/lib/res/xml/godot_provider_paths.xml11
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java38
4 files changed, 52 insertions, 11 deletions
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 9ebb8aa102..0902be9595 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -1027,6 +1027,10 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &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 1f77e2fc34..f03a1dd47a 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -20,6 +20,16 @@
android:exported="false"
/>
+ <provider
+ android:name="androidx.core.content.FileProvider"
+ android:authorities="${applicationId}.fileprovider"
+ android:exported="false"
+ android:grantUriPermissions="true">
+ <meta-data
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/godot_provider_paths" />
+ </provider>
+
</application>
</manifest>
diff --git a/platform/android/java/lib/res/xml/godot_provider_paths.xml b/platform/android/java/lib/res/xml/godot_provider_paths.xml
new file mode 100644
index 0000000000..1255f576bf
--- /dev/null
+++ b/platform/android/java/lib/res/xml/godot_provider_paths.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<paths xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <external-path
+ name="public"
+ path="." />
+
+ <external-files-path
+ name="app"
+ path="." />
+</paths>
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index 41d06a6458..edcd9c4d1f 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.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,42 @@ public class GodotIO {
// 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;
}
}