Add support for love.filedropped in Android.

To send file to the filedropped callback, share the files to the game.
Note that for non-fused binary, if there's no game running, LOVE treat it as
*.love game to run.
This commit is contained in:
Miku AuahDark
2022-05-29 01:49:29 +08:00
parent 2879074177
commit 7b66e50cfc
3 changed files with 52 additions and 6 deletions
+25 -5
View File
@@ -126,9 +126,6 @@ bool openURL(const std::string &url)
static jmethodID openURL = env->GetMethodID(clazz, "openURLFromLOVE", "(Ljava/lang/String;)Z");
if (openURL == nullptr)
return false;
jstring jstringURL = env->NewStringUTF(url.c_str());
jboolean result = env->CallBooleanMethod(clazz, openURL, jstringURL);
@@ -725,9 +722,9 @@ const char *getCRequirePath()
{
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
jobject activity = (jobject) SDL_AndroidGetActivity();
jclass clazz = env->GetObjectClass(activity);
jclass clazz(env->GetObjectClass(activity));
jmethodID getCRequireMethod = env->GetMethodID(clazz, "getCRequirePath", "()Ljava/lang/String;");
static jmethodID getCRequireMethod = env->GetMethodID(clazz, "getCRequirePath", "()Ljava/lang/String;");
jstring cpath = (jstring) env->CallObjectMethod(activity, getCRequireMethod);
const char *utf = env->GetStringUTFChars(cpath, nullptr);
@@ -745,6 +742,29 @@ const char *getCRequirePath()
return path.c_str();
}
int getFDFromContentProtocol(const char *path)
{
int fd = -1;
if (strstr(path, "content://") == path)
{
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
jobject activity = (jobject) SDL_AndroidGetActivity();
jclass clazz = env->GetObjectClass(activity);
static jmethodID converter = env->GetMethodID(clazz, "convertToFileDescriptor", "(Ljava/lang/String;)I");
jstring uri = env->NewStringUTF(path);
fd = (int) env->CallIntMethod(activity, converter, uri);
env->DeleteLocalRef(uri);
env->DeleteLocalRef(clazz);
env->DeleteLocalRef(activity);
}
return fd;
}
int getFDFromLoveProtocol(const char *path)
{
constexpr const char PROTOCOL[] = "love2d://fd/";
+7
View File
@@ -96,6 +96,13 @@ bool checkFusedGame(void **physfsIO_Out);
const char *getCRequirePath();
/**
* Convert "content://" to file descriptor.
* @param path Path with content:// URI
* @return File descriptor if successful, -1 on failure.
*/
int getFDFromContentProtocol(const char *path);
/**
* Attempt to parse "(/)love2d://fd/<fd>" from path.
* @param path Potentially special path.
+20 -1
View File
@@ -22,6 +22,10 @@
#include "NativeFile.h"
#include "common/utf8.h"
#ifdef LOVE_ANDROID
#include "common/android.h"
#endif
// Assume POSIX or Visual Studio.
#include <sys/types.h>
#include <sys/stat.h>
@@ -84,7 +88,22 @@ bool NativeFile::open(Mode newmode)
if (file != nullptr)
return false;
#ifdef LOVE_WINDOWS
#if defined(LOVE_ANDROID)
// Try to handle content:// URI
int fd = love::android::getFDFromContentProtocol(filename.c_str());
if (fd != -1)
{
if (newmode != MODE_READ)
{
::close(fd);
throw love::Exception("%s is read-only.", filename.c_str());
}
file = fdopen(fd, "rb");
}
else
file = fopen(filename.c_str(), getModeString(newmode));
#elif defined(LOVE_WINDOWS)
// make sure non-ASCII filenames work.
std::wstring modestr = to_widestr(getModeString(newmode));
std::wstring wfilename = to_widestr(filename);