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>
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;
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).
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);
+ }
}
--- /dev/null
+<paths>
+ <external-files-path path="Minetest/" name="minetest" />
+</paths>
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.") .. "]"
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
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
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,
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
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)
{
API_FCT(get_max_supp_proto);
API_FCT(open_url);
API_FCT(open_dir);
+ API_FCT(share_file);
API_FCT(do_async_callback);
}
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);