Android: Add content provider support to File::Delete
This commit is contained in:
parent
6e1e6d2311
commit
3805b84906
|
@ -1,6 +1,8 @@
|
||||||
package org.dolphinemu.dolphinemu.utils;
|
package org.dolphinemu.dolphinemu.utils;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.provider.DocumentsContract;
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.DolphinApplication;
|
import org.dolphinemu.dolphinemu.DolphinApplication;
|
||||||
|
|
||||||
|
@ -20,4 +22,18 @@ public class ContentHandler
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean delete(String uri)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ContentResolver resolver = DolphinApplication.getAppContext().getContentResolver();
|
||||||
|
return DocumentsContract.deleteDocument(resolver, Uri.parse(uri));
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e)
|
||||||
|
{
|
||||||
|
// Return true because we care about the file not being there, not the actual delete.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,3 +58,10 @@ int OpenAndroidContent(const std::string& uri, const std::string& mode)
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DeleteAndroidContent(const std::string& uri)
|
||||||
|
{
|
||||||
|
JNIEnv* env = IDCache::GetEnvForThread();
|
||||||
|
return env->CallStaticBooleanMethod(IDCache::GetContentHandlerClass(),
|
||||||
|
IDCache::GetContentHandlerDelete(), ToJString(env, uri));
|
||||||
|
}
|
||||||
|
|
|
@ -13,3 +13,4 @@ jstring ToJString(JNIEnv* env, const std::string& str);
|
||||||
std::vector<std::string> JStringArrayToVector(JNIEnv* env, jobjectArray array);
|
std::vector<std::string> JStringArrayToVector(JNIEnv* env, jobjectArray array);
|
||||||
|
|
||||||
int OpenAndroidContent(const std::string& uri, const std::string& mode);
|
int OpenAndroidContent(const std::string& uri, const std::string& mode);
|
||||||
|
bool DeleteAndroidContent(const std::string& uri);
|
||||||
|
|
|
@ -41,6 +41,7 @@ static jmethodID s_compress_cb_run;
|
||||||
|
|
||||||
static jclass s_content_handler_class;
|
static jclass s_content_handler_class;
|
||||||
static jmethodID s_content_handler_open_fd;
|
static jmethodID s_content_handler_open_fd;
|
||||||
|
static jmethodID s_content_handler_delete;
|
||||||
|
|
||||||
namespace IDCache
|
namespace IDCache
|
||||||
{
|
{
|
||||||
|
@ -187,6 +188,11 @@ jmethodID GetContentHandlerOpenFd()
|
||||||
return s_content_handler_open_fd;
|
return s_content_handler_open_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jmethodID GetContentHandlerDelete()
|
||||||
|
{
|
||||||
|
return s_content_handler_delete;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace IDCache
|
} // namespace IDCache
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -259,6 +265,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||||
s_content_handler_class = reinterpret_cast<jclass>(env->NewGlobalRef(content_handler_class));
|
s_content_handler_class = reinterpret_cast<jclass>(env->NewGlobalRef(content_handler_class));
|
||||||
s_content_handler_open_fd = env->GetStaticMethodID(s_content_handler_class, "openFd",
|
s_content_handler_open_fd = env->GetStaticMethodID(s_content_handler_class, "openFd",
|
||||||
"(Ljava/lang/String;Ljava/lang/String;)I");
|
"(Ljava/lang/String;Ljava/lang/String;)I");
|
||||||
|
s_content_handler_delete =
|
||||||
|
env->GetStaticMethodID(s_content_handler_class, "delete", "(Ljava/lang/String;)Z");
|
||||||
|
|
||||||
return JNI_VERSION;
|
return JNI_VERSION;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,5 +43,6 @@ jmethodID GetCompressCallbackRun();
|
||||||
|
|
||||||
jclass GetContentHandlerClass();
|
jclass GetContentHandlerClass();
|
||||||
jmethodID GetContentHandlerOpenFd();
|
jmethodID GetContentHandlerOpenFd();
|
||||||
|
jmethodID GetContentHandlerDelete();
|
||||||
|
|
||||||
} // namespace IDCache
|
} // namespace IDCache
|
||||||
|
|
|
@ -46,6 +46,11 @@
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
#include "Common/StringUtil.h"
|
||||||
|
#include "jni/AndroidCommon/AndroidCommon.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef S_ISDIR
|
#ifndef S_ISDIR
|
||||||
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
|
#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
|
||||||
#endif
|
#endif
|
||||||
|
@ -132,10 +137,19 @@ bool Delete(const std::string& filename)
|
||||||
{
|
{
|
||||||
INFO_LOG(COMMON, "Delete: file %s", filename.c_str());
|
INFO_LOG(COMMON, "Delete: file %s", filename.c_str());
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
if (StringBeginsWith(filename, "content://"))
|
||||||
|
{
|
||||||
|
const bool success = DeleteAndroidContent(filename);
|
||||||
|
if (!success)
|
||||||
|
WARN_LOG(COMMON, "Delete failed on %s", filename.c_str());
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const FileInfo file_info(filename);
|
const FileInfo file_info(filename);
|
||||||
|
|
||||||
// Return true because we care about the file no
|
// Return true because we care about the file not being there, not the actual delete.
|
||||||
// being there, not the actual delete.
|
|
||||||
if (!file_info.Exists())
|
if (!file_info.Exists())
|
||||||
{
|
{
|
||||||
WARN_LOG(COMMON, "Delete: %s does not exist", filename.c_str());
|
WARN_LOG(COMMON, "Delete: %s does not exist", filename.c_str());
|
||||||
|
|
Loading…
Reference in New Issue