mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 13:20:03 +00:00 
			
		
		
		
	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue