From 43f8fa89c0cb34bfc7cfbb6a50f2aeede61e0e2f Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Sun, 31 May 2020 19:48:36 +0300 Subject: [PATCH] Game now saves save files in external storage on Android when possible. May the lord have mercy on our souls. --- android/src/com/unciv/app/AndroidLauncher.kt | 2 ++ core/src/com/unciv/logic/GameSaver.kt | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/android/src/com/unciv/app/AndroidLauncher.kt b/android/src/com/unciv/app/AndroidLauncher.kt index 6caadd5f1c..888455cc41 100644 --- a/android/src/com/unciv/app/AndroidLauncher.kt +++ b/android/src/com/unciv/app/AndroidLauncher.kt @@ -7,6 +7,7 @@ import androidx.work.WorkManager import com.badlogic.gdx.backends.android.AndroidApplication import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration import com.unciv.UncivGame +import com.unciv.logic.GameSaver import java.io.File class AndroidLauncher : AndroidApplication() { @@ -17,6 +18,7 @@ class AndroidLauncher : AndroidApplication() { // Only allow mods on KK+, to avoid READ_EXTERNAL_STORAGE permission earlier versions need if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { copyMods() + GameSaver.externalFilesDirForAndroid = getExternalFilesDir(null)!!.path } val config = AndroidApplicationConfiguration().apply { useImmersiveMode = true } diff --git a/core/src/com/unciv/logic/GameSaver.kt b/core/src/com/unciv/logic/GameSaver.kt index e256927dda..31c360c18f 100644 --- a/core/src/com/unciv/logic/GameSaver.kt +++ b/core/src/com/unciv/logic/GameSaver.kt @@ -14,16 +14,26 @@ object GameSaver { private const val multiplayerFilesFolder = "MultiplayerGames" private const val settingsFileName = "GameSettings.json" + /** When set, we know we're on Android and can save to the app's personal external file directory + * See https://developer.android.com/training/data-storage/app-specific#external-access-files */ + var externalFilesDirForAndroid = "" + fun json() = Json().apply { setIgnoreDeprecated(true); ignoreUnknownFields = true } // Json() is NOT THREAD SAFE so we need to create a new one for each function fun getSubfolder(multiplayer: Boolean=false) = if(multiplayer) multiplayerFilesFolder else saveFilesFolder fun getSave(GameName: String, multiplayer: Boolean = false): FileHandle { - return Gdx.files.local("${getSubfolder(multiplayer)}/$GameName") + val localfile = Gdx.files.local("${getSubfolder(multiplayer)}/$GameName") + if(externalFilesDirForAndroid=="" || !Gdx.files.isExternalStorageAvailable) return localfile + val externalFile = Gdx.files.absolute(externalFilesDirForAndroid+"/${getSubfolder(multiplayer)}/$GameName") + if(localfile.exists() && !externalFile.exists()) return localfile + return externalFile } fun getSaves(multiplayer: Boolean = false): List { - return Gdx.files.local(getSubfolder(multiplayer)).list().map { it.name() } + val localSaves = Gdx.files.local(getSubfolder(multiplayer)).list().map { it.name() } + if(externalFilesDirForAndroid=="" || !Gdx.files.isExternalStorageAvailable) return localSaves + return localSaves + Gdx.files.absolute(externalFilesDirForAndroid+"/${getSubfolder(multiplayer)}").list().map { it.name() } } fun saveGame(game: GameInfo, GameName: String, multiplayer: Boolean = false) {