diff options
-rw-r--r-- | android/app/src/main/AndroidManifest.xml | 13 | ||||
-rw-r--r-- | android/app/src/main/java/net/minetest/minetest/GameActivity.java | 21 | ||||
-rw-r--r-- | android/app/src/main/res/xml/filepaths.xml | 3 | ||||
-rw-r--r-- | builtin/mainmenu/tab_about.lua | 9 | ||||
-rw-r--r-- | doc/menu_lua_api.txt | 2 | ||||
-rw-r--r-- | src/porting_android.cpp | 12 | ||||
-rw-r--r-- | src/porting_android.h | 7 | ||||
-rw-r--r-- | src/script/lua_api/l_mainmenu.cpp | 14 | ||||
-rw-r--r-- | src/script/lua_api/l_mainmenu.h | 2 |
9 files changed, 81 insertions, 2 deletions
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 6ea677cb9..11c868622 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -59,6 +59,17 @@ android:name=".UnzipService" android:enabled="true" android:exported="false" /> - </application> + + <provider + android:name="androidx.core.content.FileProvider" + android:authorities="net.minetest.minetest.fileprovider" + android:grantUriPermissions="true" + android:exported="false"> + <meta-data + android:name="android.support.FILE_PROVIDER_PATHS" + android:resource="@xml/filepaths" /> + </provider> + +</application> </manifest> diff --git a/android/app/src/main/java/net/minetest/minetest/GameActivity.java b/android/app/src/main/java/net/minetest/minetest/GameActivity.java index eeb90ea7f..f5e9fd6d0 100644 --- a/android/app/src/main/java/net/minetest/minetest/GameActivity.java +++ b/android/app/src/main/java/net/minetest/minetest/GameActivity.java @@ -26,6 +26,7 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.text.InputType; +import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.WindowManager; @@ -36,7 +37,9 @@ import android.widget.LinearLayout; import androidx.annotation.Keep; import androidx.appcompat.app.AlertDialog; +import androidx.core.content.FileProvider; +import java.io.File; import java.util.Objects; // Native code finds these methods by name (see porting_android.cpp). @@ -183,4 +186,22 @@ public class GameActivity extends NativeActivity { public String getCachePath() { return Utils.getCacheDirectory(this).getAbsolutePath(); } + + public void shareFile(String path) { + File file = new File(path); + if (!file.exists()) { + Log.e("GameActivity", "File " + file.getAbsolutePath() + " doesn't exist"); + return; + } + + Uri fileUri = FileProvider.getUriForFile(this, "net.minetest.minetest.fileprovider", file); + + Intent intent = new Intent(Intent.ACTION_SEND, fileUri); + intent.setDataAndType(fileUri, getContentResolver().getType(fileUri)); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.putExtra(Intent.EXTRA_STREAM, fileUri); + + Intent shareIntent = Intent.createChooser(intent, null); + startActivity(shareIntent); + } } diff --git a/android/app/src/main/res/xml/filepaths.xml b/android/app/src/main/res/xml/filepaths.xml new file mode 100644 index 000000000..2fff06908 --- /dev/null +++ b/android/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,3 @@ +<paths> + <external-files-path path="Minetest/" name="minetest" /> +</paths> diff --git a/builtin/mainmenu/tab_about.lua b/builtin/mainmenu/tab_about.lua index ba258fd2d..8e6155ea1 100644 --- a/builtin/mainmenu/tab_about.lua +++ b/builtin/mainmenu/tab_about.lua @@ -128,7 +128,9 @@ return { fgettext("Active renderer:") .. "\n" .. core.formspec_escape(core.get_screen_info().render_info) .. "]" - if PLATFORM ~= "Android" then + if PLATFORM == "Android" then + fs = fs .. "button[0,4;3.5,1;share_debug;" .. fgettext("Share debug log") .. "]" + else fs = fs .. "tooltip[userdata;" .. fgettext("Opens the directory that contains user-provided worlds, games, mods,\n" .. "and texture packs in a file manager / explorer.") .. "]" @@ -142,6 +144,11 @@ return { core.open_url("https://www.minetest.net") end + if fields.share_debug then + local path = core.get_user_path() .. DIR_DELIM .. "debug.txt" + core.share_file(path) + end + if fields.userdata then core.open_dir(core.get_user_path()) end diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt index 68e7b4b9d..63e229135 100644 --- a/doc/menu_lua_api.txt +++ b/doc/menu_lua_api.txt @@ -46,6 +46,8 @@ core.open_url(url) core.open_dir(path) ^ opens the path in the system file browser/explorer, returns false on failure. ^ Must be an existing directory. +core.share_file(path) +^ Android only. Shares file using the share popup core.get_version() (possible in async calls) ^ returns current core version diff --git a/src/porting_android.cpp b/src/porting_android.cpp index c71fe5ad8..83b590b99 100644 --- a/src/porting_android.cpp +++ b/src/porting_android.cpp @@ -213,6 +213,18 @@ void openURIAndroid(const std::string &url) jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl); } +void shareFileAndroid(const std::string &path) +{ + jmethodID url_open = jnienv->GetMethodID(nativeActivity, "shareFile", + "(Ljava/lang/String;)V"); + + FATAL_ERROR_IF(url_open == nullptr, + "porting::shareFileAndroid unable to find java openURI method"); + + jstring jurl = jnienv->NewStringUTF(path.c_str()); + jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl); +} + int getInputDialogState() { jmethodID dialogstate = jnienv->GetMethodID(nativeActivity, diff --git a/src/porting_android.h b/src/porting_android.h index 239815922..265825fbd 100644 --- a/src/porting_android.h +++ b/src/porting_android.h @@ -61,6 +61,13 @@ void showInputDialog(const std::string &acceptButton, void openURIAndroid(const std::string &url); /** + * Opens a share intent to the file at path + * + * @param path + */ +void shareFileAndroid(const std::string &path); + +/** * WORKAROUND for not working callbacks from java -> c++ * get current state of input dialog */ diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index f7b2393fb..4a847ed6d 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -877,6 +877,19 @@ int ModApiMainMenu::l_open_dir(lua_State *L) } /******************************************************************************/ +int ModApiMainMenu::l_share_file(lua_State *L) +{ +#ifdef __ANDROID__ + std::string path = luaL_checkstring(L, 1); + porting::shareFileAndroid(path); + lua_pushboolean(L, true); +#else + lua_pushboolean(L, false); +#endif + return 1; +} + +/******************************************************************************/ int ModApiMainMenu::l_do_async_callback(lua_State *L) { MainMenuScripting *script = getScriptApi<MainMenuScripting>(L); @@ -941,6 +954,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(get_max_supp_proto); API_FCT(open_url); API_FCT(open_dir); + API_FCT(share_file); API_FCT(do_async_callback); } diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index 781185425..6ceff6dd7 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -152,6 +152,8 @@ private: static int l_open_dir(lua_State *L); + static int l_share_file(lua_State *L); + // async static int l_do_async_callback(lua_State *L); |