From e7ed8253bb6211fbe501a4d2e444b4146860d0ac Mon Sep 17 00:00:00 2001 From: staphen Date: Thu, 16 Feb 2023 20:17:45 -0500 Subject: [PATCH] [Android] Use correct external files dir in all activities --- .../diasurgical/devilutionx/DataActivity.java | 26 ++-- .../devilutionx/DevilutionXSDLActivity.java | 116 +++--------------- .../devilutionx/ExternalFilesManager.java | 103 ++++++++++++++++ .../devilutionx/ImportActivity.java | 7 +- 4 files changed, 135 insertions(+), 117 deletions(-) create mode 100644 android-project/app/src/main/java/org/diasurgical/devilutionx/ExternalFilesManager.java diff --git a/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java b/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java index dd58ab2b3..1a51e61e4 100644 --- a/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java +++ b/android-project/app/src/main/java/org/diasurgical/devilutionx/DataActivity.java @@ -19,7 +19,7 @@ import java.io.File; import java.util.Locale; public class DataActivity extends Activity { - private String externalDir; + private ExternalFilesManager fileManager; private DownloadReceiver mReceiver; private boolean isDownloadingSpawn = false; private boolean isDownloadingTranslation = false; @@ -38,7 +38,7 @@ public class DataActivity extends Activity { protected void onResume() { super.onResume(); - externalDir = getExternalFilesDir(null).getAbsolutePath(); + fileManager = new ExternalFilesManager(this); startGame(); } @@ -48,7 +48,7 @@ public class DataActivity extends Activity { } private void startGame() { - if (missingGameData()) { + if (isMissingGameData()) { Toast toast = Toast.makeText(getApplicationContext(), getString(R.string.missing_game_data), Toast.LENGTH_SHORT); toast.show(); return; @@ -72,8 +72,8 @@ public class DataActivity extends Activity { return false; } - File translationFile = new File(externalDir + "/" + language + ".mpq"); - if (translationFile.exists()) { + String translationFile = language + ".mpq"; + if (fileManager.hasFile(translationFile)) { isDownloadingTranslation = false; return false; } @@ -95,14 +95,14 @@ public class DataActivity extends Activity { /** * Check if the game data is present */ - private boolean missingGameData() { + private boolean isMissingGameData() { String lang = Locale.getDefault().toString(); if (pendingTranslationFile("pl") || pendingTranslationFile("ru")) { return true; } if (lang.startsWith("ko") || lang.startsWith("zh") || lang.startsWith("ja")) { - File fonts_mpq = new File(externalDir + "/fonts.mpq"); + File fonts_mpq = fileManager.getFile("/fonts.mpq"); if (!fonts_mpq.exists() || fonts_mpq.length() == 53991069 /* v2 */) { if (!isDownloadingFonts) { fonts_mpq.delete(); @@ -117,11 +117,9 @@ public class DataActivity extends Activity { } } - File fileLower = new File(externalDir + "/diabdat.mpq"); - File fileUpper = new File(externalDir + "/DIABDAT.MPQ"); - File spawnFile = new File(externalDir + "/spawn.mpq"); - - return !fileUpper.exists() && !fileLower.exists() && (!spawnFile.exists() || isDownloadingSpawn); + return !fileManager.hasFile("diabdat.mpq") && + !fileManager.hasFile("DIABDAT.MPQ") && + (!fileManager.hasFile("spawn.mpq") || isDownloadingSpawn); } /** @@ -147,7 +145,9 @@ public class DataActivity extends Activity { .setDescription(description) .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); - request.setDestinationInExternalFilesDir(this, null, fileName); + File file = fileManager.getFile(fileName); + Uri destination = Uri.fromFile(file); + request.setDestinationUri(destination); if (mReceiver == null) { mReceiver = new DownloadReceiver(); diff --git a/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java b/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java index 5c077c2b6..1d7d416a1 100644 --- a/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java +++ b/android-project/app/src/main/java/org/diasurgical/devilutionx/DevilutionXSDLActivity.java @@ -4,7 +4,6 @@ import android.content.Intent; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; -import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.ViewTreeObserver; @@ -12,16 +11,10 @@ import android.view.ViewTreeObserver; import org.libsdl.app.SDLActivity; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.Locale; -import java.util.Objects; public class DevilutionXSDLActivity extends SDLActivity { - private String externalDir; + private ExternalFilesManager fileManager; private boolean noExit; protected void onCreate(Bundle savedInstanceState) { @@ -30,7 +23,7 @@ public class DevilutionXSDLActivity extends SDLActivity { if (Build.VERSION.SDK_INT >= 25) trackVisibleSpace(); - externalDir = chooseExternalFilesDir(); + fileManager = new ExternalFilesManager(this); migrateSaveGames(); @@ -43,7 +36,7 @@ public class DevilutionXSDLActivity extends SDLActivity { protected void onStart() { super.onStart(); - if (missingGameData()) { + if (isMissingGameData()) { Intent intent = new Intent(this, DataActivity.class); startActivity(intent); noExit = true; @@ -63,27 +56,6 @@ public class DevilutionXSDLActivity extends SDLActivity { } } - private String chooseExternalFilesDir() { - if (Build.VERSION.SDK_INT >= 19) { - File[] externalDirs = getExternalFilesDirs(null); - - for (int i = 0; i < externalDirs.length; i++) { - File dir = externalDirs[i]; - File[] iniFiles = dir.listFiles((dir1, name) -> name == "diablo.ini"); - if (iniFiles.length > 0) - return dir.getAbsolutePath(); - } - - for (int i = 0; i < externalDirs.length; i++) { - File dir = externalDirs[i]; - if (dir.listFiles().length > 0) - return dir.getAbsolutePath(); - } - } - - return getExternalFilesDir(null).getAbsolutePath(); - } - private void trackVisibleSpace() { this.getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override @@ -100,80 +72,20 @@ public class DevilutionXSDLActivity extends SDLActivity { }); } - private boolean missingGameData() { + private boolean isMissingGameData() { String lang = Locale.getDefault().toString(); - if (lang.startsWith("pl")) { - File pl_mpq = new File(externalDir + "/pl.mpq"); - if (!pl_mpq.exists()) { - return true; - } - } - if (lang.startsWith("ru")) { - File ru_mpq = new File(externalDir + "/ru.mpq"); - if (!ru_mpq.exists()) { - return true; - } - } + if (lang.startsWith("pl") && !fileManager.hasFile("pl.mpq")) + return true; + if (lang.startsWith("ru") && !fileManager.hasFile("ru.mpq")) + return true; if (lang.startsWith("ko") || lang.startsWith("zh") || lang.startsWith("ja")) { - File fonts_mpq = new File(externalDir + "/fonts.mpq"); - if (!fonts_mpq.exists()) { + if (!fileManager.hasFile("fonts.mpq")) return true; - } } - File fileLower = new File(externalDir + "/diabdat.mpq"); - File fileUpper = new File(externalDir + "/DIABDAT.MPQ"); - File spawnFile = new File(externalDir + "/spawn.mpq"); - - return !fileUpper.exists() && !fileLower.exists() && !spawnFile.exists(); - } - - private boolean copyFile(File src, File dst) { - try { - InputStream in = new FileInputStream(src); - try { - OutputStream out = new FileOutputStream(dst); - try { - // Transfer bytes from in to out - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - } finally { - out.close(); - } - } finally { - in.close(); - } - } catch (IOException exception) { - Log.e("copyFile", Objects.requireNonNull(exception.getMessage())); - if (dst.exists()) { - //noinspection ResultOfMethodCallIgnored - dst.delete(); - } - return false; - } - - return true; - } - - private void migrateFile(File file) { - File newPath = new File(externalDir + "/" + file.getName()); - - if (newPath.exists()) { - if (file.canWrite()) { - //noinspection ResultOfMethodCallIgnored - file.delete(); - } - return; - } - if (!file.renameTo(newPath)) { - if (copyFile(file, newPath) && file.canWrite()) { - //noinspection ResultOfMethodCallIgnored - file.delete(); - } - } + return !fileManager.hasFile("diabdat.mpq") && + !fileManager.hasFile("DIABDAT.MPQ") && + !fileManager.hasFile("spawn.mpq"); } private void migrateSaveGames() { @@ -181,7 +93,7 @@ public class DevilutionXSDLActivity extends SDLActivity { if (files == null) return; for (File internalFile : files) { - migrateFile(internalFile); + fileManager.migrateFile(internalFile); } } @@ -194,6 +106,8 @@ public class DevilutionXSDLActivity extends SDLActivity { } protected String[] getArguments() { + String externalDir = fileManager.getExternalFilesDirectory(); + if (BuildConfig.DEBUG) { return new String[]{ "--data-dir", diff --git a/android-project/app/src/main/java/org/diasurgical/devilutionx/ExternalFilesManager.java b/android-project/app/src/main/java/org/diasurgical/devilutionx/ExternalFilesManager.java new file mode 100644 index 000000000..3d8d2643f --- /dev/null +++ b/android-project/app/src/main/java/org/diasurgical/devilutionx/ExternalFilesManager.java @@ -0,0 +1,103 @@ +package org.diasurgical.devilutionx; + +import android.content.Context; +import android.os.Build; +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Objects; + +public class ExternalFilesManager { + private String externalFilesDirectory; + + public ExternalFilesManager(Context context) { + externalFilesDirectory = chooseExternalFilesDirectory(context); + } + + public String getExternalFilesDirectory() { + return externalFilesDirectory; + } + + public boolean hasFile(String fileName) { + File file = getFile(fileName); + return file.exists(); + } + + public File getFile(String fileName) { + return new File(externalFilesDirectory + "/" + fileName); + } + + public void migrateFile(File file) { + File newPath = new File(externalFilesDirectory + "/" + file.getName()); + + if (newPath.exists()) { + if (file.canWrite()) { + //noinspection ResultOfMethodCallIgnored + file.delete(); + } + return; + } + if (!file.renameTo(newPath)) { + if (copyFile(file, newPath) && file.canWrite()) { + //noinspection ResultOfMethodCallIgnored + file.delete(); + } + } + } + + private String chooseExternalFilesDirectory(Context context) { + if (Build.VERSION.SDK_INT >= 19) { + File[] externalDirs = context.getExternalFilesDirs(null); + + for (int i = 0; i < externalDirs.length; i++) { + File dir = externalDirs[i]; + File[] iniFiles = dir.listFiles((dir1, name) -> name.equals("diablo.ini")); + if (iniFiles.length > 0) + return dir.getAbsolutePath(); + } + + for (int i = 0; i < externalDirs.length; i++) { + File dir = externalDirs[i]; + if (dir.listFiles().length > 0) + return dir.getAbsolutePath(); + } + } + + return context.getExternalFilesDir(null).getAbsolutePath(); + } + + private boolean copyFile(File src, File dst) { + try { + InputStream in = new FileInputStream(src); + try { + OutputStream out = new FileOutputStream(dst); + try { + // Transfer bytes from in to out + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + } finally { + out.close(); + } + } finally { + in.close(); + } + } catch (IOException exception) { + Log.e("copyFile", Objects.requireNonNull(exception.getMessage())); + if (dst.exists()) { + //noinspection ResultOfMethodCallIgnored + dst.delete(); + } + return false; + } + + return true; + } +} diff --git a/android-project/app/src/main/java/org/diasurgical/devilutionx/ImportActivity.java b/android-project/app/src/main/java/org/diasurgical/devilutionx/ImportActivity.java index 969dc0664..2948d994c 100644 --- a/android-project/app/src/main/java/org/diasurgical/devilutionx/ImportActivity.java +++ b/android-project/app/src/main/java/org/diasurgical/devilutionx/ImportActivity.java @@ -12,6 +12,7 @@ import android.support.annotation.RequiresApi; import android.support.v4.provider.DocumentFile; import android.util.Log; +import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -65,8 +66,8 @@ public class ImportActivity extends Activity { DocumentFile file = Objects.requireNonNull(DocumentFile.fromSingleUri(getApplicationContext(), fileUri)); String fileName = file.getName(); - String externalFilesDir = getExternalFilesDir(null).getAbsolutePath(); - String externalFilesPath = externalFilesDir + "/" + fileName; + ExternalFilesManager fileManager = new ExternalFilesManager(this); + File externalFile = fileManager.getFile(fileName); try { InputStream inputStream = null; @@ -75,7 +76,7 @@ public class ImportActivity extends Activity { try { ContentResolver contentResolver = getContentResolver(); inputStream = contentResolver.openInputStream(fileUri); - outputStream = new FileOutputStream(externalFilesPath); + outputStream = new FileOutputStream(externalFile); // Transfer bytes from in to out byte[] buf = new byte[4096];