mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-09 15:49:25 +01:00
Android: Don't hard code the user dircetory path to /sdcard/dolphin-emu
Android is allowed to pick any path for the external storage media and that's why we should always use Environment.getExternalStorageDirectory() to get the external storage path
This commit is contained in:
parent
9a166dca57
commit
ae8b469b80
@ -15,8 +15,6 @@ public class DolphinApplication extends Application
|
||||
{
|
||||
super.onCreate();
|
||||
|
||||
NativeLibrary.SetUserDirectory(""); // Empty string means use the default path
|
||||
|
||||
if (PermissionsHandler.hasWriteAccess(getApplicationContext()))
|
||||
DirectoryInitializationService.startService(getApplicationContext());
|
||||
|
||||
|
@ -158,13 +158,22 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
|
||||
DirectoryInitializationService.BROADCAST_ACTION);
|
||||
|
||||
directoryStateReceiver =
|
||||
new DirectoryStateReceiver(directoryInitializationState -> {
|
||||
if (directoryInitializationState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED) {
|
||||
new DirectoryStateReceiver(directoryInitializationState ->
|
||||
{
|
||||
if (directoryInitializationState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
|
||||
{
|
||||
mEmulationState.run(activity.isActivityRecreated());
|
||||
} else if (directoryInitializationState == DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED) {
|
||||
}
|
||||
else if (directoryInitializationState == DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
|
||||
{
|
||||
Toast.makeText(getContext(), R.string.write_permission_needed, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
else if (directoryInitializationState == DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
|
||||
{
|
||||
Toast.makeText(getContext(), R.string.external_storage_not_mounted, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
});
|
||||
|
||||
// Registers the DirectoryStateReceiver and its intent filters
|
||||
|
@ -10,6 +10,7 @@ import android.app.IntentService;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
@ -22,6 +23,8 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
||||
/**
|
||||
* A service that spawns its own thread in order to copy several binary and shader files
|
||||
@ -32,12 +35,15 @@ public final class DirectoryInitializationService extends IntentService
|
||||
public static final String BROADCAST_ACTION = "org.dolphinemu.dolphinemu.BROADCAST";
|
||||
|
||||
public static final String EXTRA_STATE = "directoryState";
|
||||
private static DirectoryInitializationState directoryState = null;
|
||||
private static volatile DirectoryInitializationState directoryState = null;
|
||||
private static String userPath;
|
||||
private static AtomicBoolean isDolphinDirectoryInitializationRunning = new AtomicBoolean(false);
|
||||
|
||||
public enum DirectoryInitializationState
|
||||
{
|
||||
DOLPHIN_DIRECTORIES_INITIALIZED,
|
||||
EXTERNAL_STORAGE_PERMISSION_NEEDED
|
||||
EXTERNAL_STORAGE_PERMISSION_NEEDED,
|
||||
CANT_FIND_EXTERNAL_STORAGE
|
||||
}
|
||||
|
||||
public DirectoryInitializationService()
|
||||
@ -55,21 +61,50 @@ public final class DirectoryInitializationService extends IntentService
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent)
|
||||
{
|
||||
if (directoryState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
|
||||
isDolphinDirectoryInitializationRunning.set(true);
|
||||
|
||||
if (directoryState != DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
|
||||
{
|
||||
sendBroadcastState(DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED);
|
||||
if (PermissionsHandler.hasWriteAccess(this))
|
||||
{
|
||||
if (setDolphinUserDirectory())
|
||||
{
|
||||
initializeInternalStorage();
|
||||
initializeExternalStorage();
|
||||
|
||||
directoryState = DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED;
|
||||
}
|
||||
else
|
||||
{
|
||||
directoryState = DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
directoryState = DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED;
|
||||
}
|
||||
}
|
||||
else if (PermissionsHandler.hasWriteAccess(this))
|
||||
|
||||
isDolphinDirectoryInitializationRunning.set(false);
|
||||
sendBroadcastState(directoryState);
|
||||
}
|
||||
|
||||
private boolean setDolphinUserDirectory()
|
||||
{
|
||||
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
|
||||
{
|
||||
initializeInternalStorage();
|
||||
initializeExternalStorage();
|
||||
directoryState = DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED;
|
||||
sendBroadcastState(directoryState);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendBroadcastState(DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED);
|
||||
File externalPath = Environment.getExternalStorageDirectory();
|
||||
if (externalPath != null)
|
||||
{
|
||||
userPath = externalPath.getAbsolutePath() + "/dolphin-emu";
|
||||
Log.debug("[DirectoryInitializationService] User Dir: " + userPath);
|
||||
NativeLibrary.SetUserDirectory(userPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initializeInternalStorage()
|
||||
@ -128,6 +163,20 @@ public final class DirectoryInitializationService extends IntentService
|
||||
return directoryState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED;
|
||||
}
|
||||
|
||||
public static String getUserDirectory()
|
||||
{
|
||||
if (directoryState == null)
|
||||
{
|
||||
throw new IllegalStateException("DirectoryInitializationService has to run at least once!");
|
||||
}
|
||||
else if (isDolphinDirectoryInitializationRunning.get())
|
||||
{
|
||||
throw new IllegalStateException("DirectoryInitializationService has to finish running first!");
|
||||
}
|
||||
return userPath;
|
||||
|
||||
}
|
||||
|
||||
private void sendBroadcastState(DirectoryInitializationState state)
|
||||
{
|
||||
Intent localIntent =
|
||||
|
@ -161,6 +161,13 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showExternalStorageNotMountedHint()
|
||||
{
|
||||
Toast.makeText(this, R.string.external_storage_not_mounted, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<String, SettingSection> getSettings(int file)
|
||||
{
|
||||
|
@ -6,6 +6,7 @@ import android.os.Bundle;
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.model.settings.SettingSection;
|
||||
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
|
||||
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService.DirectoryInitializationState;
|
||||
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
|
||||
import org.dolphinemu.dolphinemu.utils.Log;
|
||||
import org.dolphinemu.dolphinemu.utils.SettingsFile;
|
||||
@ -40,9 +41,6 @@ public final class SettingsActivityPresenter
|
||||
{
|
||||
if (savedInstanceState == null)
|
||||
{
|
||||
mSettings.add(SettingsFile.SETTINGS_DOLPHIN, SettingsFile.readFile(SettingsFile.FILE_NAME_DOLPHIN, mView));
|
||||
mSettings.add(SettingsFile.SETTINGS_GFX, SettingsFile.readFile(SettingsFile.FILE_NAME_GFX, mView));
|
||||
mSettings.add(SettingsFile.SETTINGS_WIIMOTE, SettingsFile.readFile(SettingsFile.FILE_NAME_WIIMOTE, mView));
|
||||
this.menuTag = menuTag;
|
||||
}
|
||||
else
|
||||
@ -58,6 +56,13 @@ public final class SettingsActivityPresenter
|
||||
|
||||
void loadSettingsUI()
|
||||
{
|
||||
if (mSettings.isEmpty())
|
||||
{
|
||||
mSettings.add(SettingsFile.SETTINGS_DOLPHIN, SettingsFile.readFile(SettingsFile.FILE_NAME_DOLPHIN, mView));
|
||||
mSettings.add(SettingsFile.SETTINGS_GFX, SettingsFile.readFile(SettingsFile.FILE_NAME_GFX, mView));
|
||||
mSettings.add(SettingsFile.SETTINGS_WIIMOTE, SettingsFile.readFile(SettingsFile.FILE_NAME_WIIMOTE, mView));
|
||||
}
|
||||
|
||||
mView.showSettingsFragment(menuTag, false);
|
||||
mView.onSettingsFileLoaded(mSettings);
|
||||
}
|
||||
@ -72,14 +77,23 @@ public final class SettingsActivityPresenter
|
||||
DirectoryInitializationService.BROADCAST_ACTION);
|
||||
|
||||
directoryStateReceiver =
|
||||
new DirectoryStateReceiver(directoryInitializationState -> {
|
||||
if (directoryInitializationState == DirectoryInitializationService.DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED) {
|
||||
new DirectoryStateReceiver(directoryInitializationState ->
|
||||
{
|
||||
if (directoryInitializationState == DirectoryInitializationState.DOLPHIN_DIRECTORIES_INITIALIZED)
|
||||
{
|
||||
mView.hideLoading();
|
||||
loadSettingsUI();
|
||||
} else if (directoryInitializationState == DirectoryInitializationService.DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED) {
|
||||
}
|
||||
else if (directoryInitializationState == DirectoryInitializationState.EXTERNAL_STORAGE_PERMISSION_NEEDED)
|
||||
{
|
||||
mView.showPermissionNeededHint();
|
||||
mView.hideLoading();
|
||||
}
|
||||
else if (directoryInitializationState == DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE)
|
||||
{
|
||||
mView.showExternalStorageNotMountedHint();
|
||||
mView.hideLoading();
|
||||
}
|
||||
});
|
||||
|
||||
mView.startDirectoryInitializationService(directoryStateReceiver, statusIntentFilter);
|
||||
|
@ -118,6 +118,11 @@ public interface SettingsActivityView
|
||||
*/
|
||||
void showPermissionNeededHint();
|
||||
|
||||
/**
|
||||
* Show a hint to the user that the app needs the external storage to be mounted
|
||||
*/
|
||||
void showExternalStorageNotMountedHint();
|
||||
|
||||
/**
|
||||
* Start the DirectoryInitializationService and listen for the result.
|
||||
*
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.dolphinemu.dolphinemu.utils;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.dolphinemu.dolphinemu.model.settings.BooleanSetting;
|
||||
@ -9,6 +8,7 @@ import org.dolphinemu.dolphinemu.model.settings.IntSetting;
|
||||
import org.dolphinemu.dolphinemu.model.settings.Setting;
|
||||
import org.dolphinemu.dolphinemu.model.settings.SettingSection;
|
||||
import org.dolphinemu.dolphinemu.model.settings.StringSetting;
|
||||
import org.dolphinemu.dolphinemu.services.DirectoryInitializationService;
|
||||
import org.dolphinemu.dolphinemu.ui.settings.SettingsActivityView;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@ -393,8 +393,7 @@ public final class SettingsFile
|
||||
@NonNull
|
||||
private static File getSettingsFile(String fileName)
|
||||
{
|
||||
String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath();
|
||||
return new File(storagePath + "/dolphin-emu/Config/" + fileName + ".ini");
|
||||
return new File(DirectoryInitializationService.getUserDirectory() + "/Config/" + fileName + ".ini");
|
||||
}
|
||||
|
||||
private static SettingSection sectionFromLine(String line)
|
||||
|
@ -251,4 +251,6 @@
|
||||
<string name="load_settings">Loading Settings...</string>
|
||||
|
||||
<string name="emulation_change_disc">Change Disc</string>
|
||||
|
||||
<string name="external_storage_not_mounted">The external storage needs to be available in order to use Dolphin</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user