Skip to content

Commit

Permalink
Implement file provider capabilities
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
m4gr3d committed Feb 1, 2023
1 parent aed400c commit b04c9a7
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 11 deletions.
4 changes: 4 additions & 0 deletions platform/android/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,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]);
Expand Down
10 changes: 10 additions & 0 deletions platform/android/java/lib/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
11 changes: 11 additions & 0 deletions platform/android/java/lib/res/xml/godot_provider_paths.xml
Original file line number Diff line number Diff line change
@@ -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>
38 changes: 27 additions & 11 deletions platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
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;

Expand Down Expand Up @@ -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;
}
}
Expand Down

0 comments on commit b04c9a7

Please sign in to comment.