android: init user path
This commit is contained in:
parent
28b2ee9cd7
commit
9848610ea2
10 changed files with 153 additions and 5 deletions
|
@ -1,10 +1,13 @@
|
||||||
cmake_minimum_required(VERSION 3.8)
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
|
||||||
add_library(citra-android SHARED
|
add_library(citra-android SHARED
|
||||||
dummy.cpp
|
native_interface.cpp
|
||||||
|
native_interface.h
|
||||||
|
ui/main/main_activity.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
# find Android's log library
|
# find Android's log library
|
||||||
find_library(log-lib log)
|
find_library(log-lib log)
|
||||||
|
|
||||||
target_link_libraries(citra-android ${log-lib} core common inih)
|
target_link_libraries(citra-android ${log-lib} core common inih)
|
||||||
|
target_include_directories(citra-android PRIVATE "../../../../../" "./")
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
int dummy(int a, int b) {
|
|
||||||
return a + b;
|
|
||||||
}
|
|
22
src/android/app/src/main/cpp/native_interface.cpp
Normal file
22
src/android/app/src/main/cpp/native_interface.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2019 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "native_interface.h"
|
||||||
|
|
||||||
|
namespace CitraJNI {
|
||||||
|
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||||
|
return JNI_VERSION_1_6;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetJString(JNIEnv* env, jstring jstr) {
|
||||||
|
std::string result = "";
|
||||||
|
if (!jstr)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
const char* s = env->GetStringUTFChars(jstr, nullptr);
|
||||||
|
result = s;
|
||||||
|
env->ReleaseStringUTFChars(jstr, s);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} // namespace CitraJNI
|
16
src/android/app/src/main/cpp/native_interface.h
Normal file
16
src/android/app/src/main/cpp/native_interface.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2019 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
namespace CitraJNI {
|
||||||
|
extern "C" {
|
||||||
|
jint JNI_OnLoad(JavaVM* vm, void* reserved);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetJString(JNIEnv* env, jstring jstr);
|
||||||
|
} // namespace CitraJNI
|
15
src/android/app/src/main/cpp/ui/main/main_activity.cpp
Normal file
15
src/android/app/src/main/cpp/ui/main/main_activity.cpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2019 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "common/file_util.h"
|
||||||
|
#include "native_interface.h"
|
||||||
|
|
||||||
|
namespace MainActivity {
|
||||||
|
extern "C" {
|
||||||
|
JNICALL void Java_org_citra_1emu_citra_ui_main_MainActivity_initUserPath(JNIEnv* env, jclass type,
|
||||||
|
jstring path) {
|
||||||
|
FileUtil::SetUserPath(CitraJNI::GetJString(env, path));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}; // namespace MainActivity
|
|
@ -6,4 +6,8 @@ package org.citra_emu.citra;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
|
||||||
public class CitraApplication extends Application {}
|
public class CitraApplication extends Application {
|
||||||
|
static {
|
||||||
|
System.loadLibrary("citra-android");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,15 +4,53 @@
|
||||||
|
|
||||||
package org.citra_emu.citra.ui.main;
|
package org.citra_emu.citra.ui.main;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
|
||||||
import org.citra_emu.citra.R;
|
import org.citra_emu.citra.R;
|
||||||
|
import org.citra_emu.citra.utils.FileUtil;
|
||||||
|
import org.citra_emu.citra.utils.PermissionUtil;
|
||||||
|
|
||||||
public final class MainActivity extends AppCompatActivity {
|
public final class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
// Java enums suck
|
||||||
|
private interface PermissionCodes { int INIT_USER_PATH = 0; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
PermissionUtil.verifyPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
|
PermissionCodes.INIT_USER_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||||
|
@NonNull int[] grantResults) {
|
||||||
|
switch (requestCode) {
|
||||||
|
case PermissionCodes.INIT_USER_PATH:
|
||||||
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
initUserPath(FileUtil.getUserPath().toString());
|
||||||
|
} else {
|
||||||
|
AlertDialog.Builder dialog =
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setTitle("Permission Error")
|
||||||
|
.setMessage("Citra requires storage permissions to function.")
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton("OK", (dialogInterface, which) -> {
|
||||||
|
PermissionUtil.verifyPermission(
|
||||||
|
MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
|
PermissionCodes.INIT_USER_PATH);
|
||||||
|
});
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void initUserPath(String path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2019 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
package org.citra_emu.citra.utils;
|
||||||
|
|
||||||
|
import android.os.Environment;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class FileUtil {
|
||||||
|
public static File getUserPath() {
|
||||||
|
File storage = Environment.getExternalStorageDirectory();
|
||||||
|
File userPath = new File(storage, "citra");
|
||||||
|
if (!userPath.isDirectory())
|
||||||
|
userPath.mkdir();
|
||||||
|
return userPath;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright 2019 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
package org.citra_emu.citra.utils;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
|
||||||
|
public class PermissionUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks a permission, if needed shows a dialog to request it
|
||||||
|
*
|
||||||
|
* @param activity the activity requiring the permission
|
||||||
|
* @param permission the permission needed
|
||||||
|
* @param requestCode supplied to the callback to determine the next action
|
||||||
|
*/
|
||||||
|
public static void verifyPermission(Activity activity, String permission, int requestCode) {
|
||||||
|
if (ContextCompat.checkSelfPermission(activity, permission) ==
|
||||||
|
PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// call the callback called by requestPermissions
|
||||||
|
activity.onRequestPermissionsResult(requestCode, new String[] {permission},
|
||||||
|
new int[] {PackageManager.PERMISSION_GRANTED});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityCompat.requestPermissions(activity, new String[] {permission}, requestCode);
|
||||||
|
}
|
||||||
|
}
|
|
@ -695,6 +695,8 @@ void SetUserPath(const std::string& path) {
|
||||||
|
|
||||||
g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP);
|
g_paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP);
|
||||||
g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP);
|
g_paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP);
|
||||||
|
#elif ANDROID
|
||||||
|
ASSERT_MSG(false, "Specified path {} is not valid", path);
|
||||||
#else
|
#else
|
||||||
if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) {
|
if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) {
|
||||||
user_path = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP;
|
user_path = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP;
|
||||||
|
|
Loading…
Reference in a new issue