]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Android: Add support for sharing debug.txt (#12370)
authorrubenwardy <rw@rubenwardy.com>
Sun, 5 Jun 2022 16:42:09 +0000 (17:42 +0100)
committerGitHub <noreply@github.com>
Sun, 5 Jun 2022 16:42:09 +0000 (17:42 +0100)
android/app/src/main/AndroidManifest.xml
android/app/src/main/java/net/minetest/minetest/GameActivity.java
android/app/src/main/res/xml/filepaths.xml [new file with mode: 0644]
builtin/mainmenu/tab_about.lua
doc/menu_lua_api.txt
src/porting_android.cpp
src/porting_android.h
src/script/lua_api/l_mainmenu.cpp
src/script/lua_api/l_mainmenu.h

index 6ea677cb99ab859a0dd62e0e6f04f96067885aa7..11c868622b53599f5d5bf516ba0a69f0c5e15975 100644 (file)
                        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>
index eeb90ea7f7e59ebbe59e0a181e1ad578668c0799..f5e9fd6d08a303c653e9fd661f9d609ccc60e0e8 100644 (file)
@@ -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 (file)
index 0000000..2fff069
--- /dev/null
@@ -0,0 +1,3 @@
+<paths>
+       <external-files-path path="Minetest/" name="minetest" />
+</paths>
index ba258fd2d0486672aa95abd4d933287dc5d9de91..8e6155ea1885b920f3f84a69751a5bcdc6e05ce1 100644 (file)
@@ -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
index 68e7b4b9de018edb3bdff85149b3cd74211320ed..63e229135394403ff94ee71cbed1a3f54cc8ea2b 100644 (file)
@@ -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
 
index c71fe5ad88e1c733de7a9a7afceee4d7163139db..83b590b99d016d76d8f86074726466005f15968f 100644 (file)
@@ -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,
index 23981592265f50b5da30dff92c3febb4d1d7b97e..265825fbd8960f9e3fb88aa698bdbff2155c41dd 100644 (file)
@@ -60,6 +60,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
index f7b2393fb0b98cbc087236b139dc5bc9bf141b6e..4a847ed6ded83dba815c6abe6ecb1ac6950d824c 100644 (file)
@@ -876,6 +876,19 @@ int ModApiMainMenu::l_open_dir(lua_State *L)
        return 1;
 }
 
+/******************************************************************************/
+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)
 {
@@ -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);
 }
 
index 781185425196b7f9931f0c4d3f46a10d2de739e4..6ceff6dd7df203741327ac55f100f56a85324fdc 100644 (file)
@@ -152,6 +152,8 @@ class ModApiMainMenu: public ModApiBase
 
        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);