diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java index a8e726270..d51798569 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/activity/LoadSaveActivity.java @@ -11,9 +11,7 @@ import java.util.List; import java.util.Objects; import android.Manifest; -import android.annotation.TargetApi; import android.app.Activity; -import android.app.Dialog; import android.content.ClipData; import android.content.ContentResolver; import android.content.Context; @@ -152,11 +150,15 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O } } - private void addSavegameSlotButtons(ViewGroup parent, LayoutParams params, List usedSavegameSlots) { - int unused = 1; - for (int slot : usedSavegameSlots) { - final FileHeader header = Savegames.quickload(this, slot); - if (header == null) continue; + private void addSavegameSlotButtons(ViewGroup parent, + LayoutParams params, + List usedSavegameSlots) { + int unused = 1; + for (int slot : usedSavegameSlots) { + final FileHeader header = Savegames.quickload(this, slot); + if (header == null) { + continue; + } while (unused < slot) { Button b = new Button(this); @@ -206,37 +208,49 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O i.putExtra("export", true); } - } else if (slot < SLOT_NUMBER_FIRST_SLOT) - slot = SLOT_NUMBER_FIRST_SLOT; + } + else if (slot < SLOT_NUMBER_FIRST_SLOT) { + slot = SLOT_NUMBER_FIRST_SLOT; + } - i.putExtra("slot", slot); - if(success) setResult(Activity.RESULT_OK, i); - else setResult(Activity.RESULT_CANCELED, i); - LoadSaveActivity.this.finish(); - } + i.putExtra("slot", slot); + if (success) { + setResult(Activity.RESULT_OK, i); + } + else { + setResult(Activity.RESULT_CANCELED, i); + } + LoadSaveActivity.this.finish(); + } - private int getFirstFreeSlot() { - int slot; - List usedSlots = Savegames.getUsedSavegameSlots(this); - if (usedSlots.isEmpty()) - slot = SLOT_NUMBER_FIRST_SLOT; - else slot = Collections.max(usedSlots) + 1; - return slot; - } + private int getFirstFreeSlot() { + int slot; + List usedSlots = Savegames.getUsedSavegameSlots(this); + if (usedSlots.isEmpty()) { + slot = SLOT_NUMBER_FIRST_SLOT; + } + else { + slot = Collections.max(usedSlots) + 1; + } + return slot; + } - private String getConfirmOverwriteQuestion(int slot) { - if (isLoading) - return null; + private String getConfirmOverwriteQuestion(int slot) { + if (isLoading) { + return null; + } return getConfirmOverwriteQuestionIgnoringLoading(slot); } - private String getConfirmOverwriteQuestionIgnoringLoading(int slot) { - if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) - return null;//creating a new savegame + private String getConfirmOverwriteQuestionIgnoringLoading(int slot) { + if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) { + return null;//creating a new savegame + } - if (!Savegames.getSlotFile(slot, this).exists()) - return null;//nothing in slot to overwrite + if (!Savegames.getSlotFile(slot, this).exists()) { + return null;//nothing in slot to overwrite + } if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_ALWAYS) { return getString(R.string.loadsave_save_overwrite_confirmation_all); @@ -245,12 +259,16 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O return null; } - final String currentPlayerName = model.player.getName(); - final FileHeader header = Savegames.quickload(this, slot); - if (header == null) return null; + final String currentPlayerName = model.player.getName(); + final FileHeader header = Savegames.quickload(this, slot); + if (header == null) { + return null; + } - final String savedPlayerName = header.playerName; - if (currentPlayerName.equals(savedPlayerName)) return null; //if the names match + final String savedPlayerName = header.playerName; + if (currentPlayerName.equals(savedPlayerName)) { + return null; //if the names match + } return getString(R.string.loadsave_save_overwrite_confirmation, savedPlayerName, currentPlayerName); } @@ -259,40 +277,44 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O public void onClick(View view) { final int slot = (Integer) view.getTag(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - switch (slot) { - case SLOT_NUMBER_IMPORT_WORLDMAP: - clickImportWorldmap(); - return; - case SLOT_NUMBER_IMPORT_SAVEGAMES: - clickImportSaveGames(); - return; - case SLOT_NUMBER_EXPORT_SAVEGAMES: - clickExportSaveGames(); - return; - } - } - if (!isLoading - && slot != SLOT_NUMBER_CREATE_NEW_SLOT - && AndorsTrailApplication.CURRENT_VERSION == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) { - if (!isOverwriteTargetInIncompatibleVersion(slot)) { - saveOrOverwriteSavegame(slot); - } - } else if (isLoading) { - loadSaveGame(slot); - } else { - saveOrOverwriteSavegame(slot); - } - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + switch (slot) { + case SLOT_NUMBER_IMPORT_WORLDMAP: + clickImportWorldmap(); + return; + case SLOT_NUMBER_IMPORT_SAVEGAMES: + clickImportSaveGames(); + return; + case SLOT_NUMBER_EXPORT_SAVEGAMES: + clickExportSaveGames(); + return; + } + } + if (!isLoading + && slot != SLOT_NUMBER_CREATE_NEW_SLOT + && AndorsTrailApplication.CURRENT_VERSION + == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) { + if (!isOverwriteTargetInIncompatibleVersion(slot)) { + saveOrOverwriteSavegame(slot); + } + } + else if (isLoading) { + loadSaveGame(slot); + } + else { + saveOrOverwriteSavegame(slot); + } + } - private void saveOrOverwriteSavegame(int slot) { - final String message = getConfirmOverwriteQuestion(slot); - if (message != null) { - showConfirmoverwriteQuestion(slot, message); - } else { - completeLoadSaveActivity(slot); - } - } + private void saveOrOverwriteSavegame(int slot) { + final String message = getConfirmOverwriteQuestion(slot); + if (message != null) { + showConfirmOverwriteQuestion(slot, message); + } + else { + completeLoadSaveActivity(slot); + } + } private boolean isOverwriteTargetInIncompatibleVersion(int slot) { final FileHeader header = Savegames.quickload(this, slot); @@ -313,21 +335,22 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O Context context = getApplicationContext(); ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this).getContentResolver(); - File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY); - DocumentFile source = DocumentFile.fromFile(storageDir); - DocumentFile target = DocumentFile.fromTreeUri(context, uri); - if (target == null) { - return; - } + File storageDir = AndroidStorage.getStorageDirectory(context, + Constants.FILENAME_SAVEGAME_DIRECTORY); + DocumentFile target = DocumentFile.fromTreeUri(context, uri); + if (target == null) { + return; + } - DocumentFile[] files = source.listFiles(); + File[] files = storageDir.listFiles(); + if (files == null) { + showErrorExportingSaveGamesUnknown(); + return; + } - boolean hasExistingFiles = false; - for (DocumentFile file : - files) { - String fileName = file.getName(); - if (fileName == null) - continue; + boolean hasExistingFiles = false; + for (File file : files) { + String fileName = file.getName(); DocumentFile existingFile = target.findFile(fileName); if (existingFile != null) { @@ -336,101 +359,127 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O } } - if (hasExistingFiles) { - showConfirmOverwriteByExportQuestion(resolver, target, files); - } else { - exportSaveGamesFolderContentToFolder(resolver, target, files); - } - } + if (hasExistingFiles) { + showConfirmOverwriteByExportQuestion(resolver, target, files); + } + else { + exportSaveGamesFolderContentToFolder(target, files); + } + } - @RequiresApi(api = Build.VERSION_CODES.P) - private void exportSaveGamesFolderContentToFolder(ContentResolver resolver, DocumentFile target, DocumentFile[] files) { - DocumentFile[] sourceFiles = new DocumentFile[files.length]; + @RequiresApi(api = Build.VERSION_CODES.P) + private void exportSaveGamesFolderContentToFolder(DocumentFile target, File[] files) { + DocumentFile[] sourceFiles = new DocumentFile[files.length]; - DocumentFile[] worldmapFiles = null; + File[] worldmapFiles = null; - for (int i = 0; i < files.length; i++) { - DocumentFile file = files[i]; - if (file.isFile()) { - sourceFiles[i] = file; - } else if (file.isDirectory() && Objects.equals(file.getName(), Constants.FILENAME_WORLDMAP_DIRECTORY)) { - worldmapFiles = file.listFiles(); - } - } - Context context =this; - DocumentFile[] finalWorldmapFiles = worldmapFiles; - AndroidStorage.copyDocumentFilesToDirAsync(sourceFiles, - context, - target, - (sucess) -> { - if (sucess) { - DocumentFile worldmapFolder = target.createDirectory(Constants.FILENAME_WORLDMAP_DIRECTORY); - AndroidStorage.copyDocumentFilesToDirAsync(finalWorldmapFiles, - context, - worldmapFolder, - (sucessWorldmap) -> completeLoadSaveActivity(SLOT_NUMBER_EXPORT_SAVEGAMES, sucessWorldmap)); - } else { - completeLoadSaveActivity(SLOT_NUMBER_EXPORT_SAVEGAMES, false); - } - }); + for (int i = 0; i < files.length; i++) { + File file = files[i]; + if (file.isFile()) { + sourceFiles[i] = DocumentFile.fromFile(file); + } + else if (file.isDirectory() && Objects.equals(file.getName(), + Constants.FILENAME_WORLDMAP_DIRECTORY)) { + worldmapFiles = file.listFiles(); + } + } + Context context = this; + File[] finalWorldmapFiles = worldmapFiles; + AndroidStorage.copyDocumentFilesToDirAsync(sourceFiles, + context, + target, + getString(R.string.loadsave_exporting_savegames), + (success) -> { + if (success) { + AndroidStorage.createZipDocumentFileFromFilesAsync( + finalWorldmapFiles, + context, + target, + Constants.FILENAME_WORLDMAP_DIRECTORY, + getString(R.string.loadsave_exporting_worldmap), + (successWorldmap) -> completeLoadSaveActivity( + SLOT_NUMBER_EXPORT_SAVEGAMES, + successWorldmap)); + } + else { + completeLoadSaveActivity( + SLOT_NUMBER_EXPORT_SAVEGAMES, + false); + } + }); } - @RequiresApi(api = Build.VERSION_CODES.N) - private void importSaveGames(Intent data) { - Uri uri = data.getData(); - ClipData uris = data.getClipData(); + @RequiresApi(api = Build.VERSION_CODES.P) + private void importSaveGames(Intent data) { + Uri uri = data.getData(); + ClipData uris = data.getClipData(); if (uri == null && uris == null) { //no file was selected return; } - Context context = getApplicationContext(); - ContentResolver resolver = context.getContentResolver(); + Context context = getApplicationContext(); + ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this) + .getContentResolver(); File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY); DocumentFile appSavegameFolder = DocumentFile.fromFile(storageDir); - List uriList = new ArrayList<>(); - if (uri != null) { - uriList.add(uri); - } else { - for (int i = 0; i < uris.getItemCount(); i++) - uriList.add(uris.getItemAt(i).getUri()); - } - importSaveGamesFromUris(context, resolver, appSavegameFolder, uriList); - } + List uriList = new ArrayList<>(); + if (uri != null) { + uriList.add(uri); + } + else { + for (int i = 0; i < uris.getItemCount(); i++) { + uriList.add(uris.getItemAt(i).getUri()); + } + } + importSaveGamesFromUris(context, resolver, appSavegameFolder, uriList); + } - @RequiresApi(api = Build.VERSION_CODES.N) - private void importSaveGamesFromUris(Context context, ContentResolver resolver, DocumentFile appSavegameFolder, List uriList) { - int count = uriList.size(); + @RequiresApi(api = Build.VERSION_CODES.P) + private void importSaveGamesFromUris(Context context, + ContentResolver resolver, + DocumentFile appSavegameFolder, + List uriList) { + int count = uriList.size(); ArrayList alreadyExistingFiles = new ArrayList<>(); ArrayList newFiles = new ArrayList<>(); - for (int i = 0; i < count; i++) { - Uri item = uriList.get(i); - DocumentFile itemFile = DocumentFile.fromSingleUri(context, item); - boolean fileAlreadyExists = getExistsSavegameInOwnFiles(itemFile, appSavegameFolder); - if (fileAlreadyExists) - alreadyExistingFiles.add(itemFile); - else - newFiles.add(itemFile); - } + for (int i = 0; i < count; i++) { + Uri item = uriList.get(i); + DocumentFile itemFile = DocumentFile.fromSingleUri(context, item); + boolean fileAlreadyExists = getExistsSavegameInOwnFiles(itemFile, appSavegameFolder); + if (fileAlreadyExists) { + alreadyExistingFiles.add(itemFile); + } + else { + newFiles.add(itemFile); + } + } - if (alreadyExistingFiles.size() > 0) { - showConfirmOverwriteByImportQuestion(resolver, appSavegameFolder, alreadyExistingFiles, newFiles); - } else { - importSaveGames(resolver, appSavegameFolder, newFiles); - } - } + if (alreadyExistingFiles.size() > 0) { + showConfirmOverwriteByImportQuestion(resolver, + appSavegameFolder, + alreadyExistingFiles, + newFiles); + } + else { + importSaveGames(resolver, appSavegameFolder, newFiles); + } + } - private void importSaveGames(ContentResolver resolver, DocumentFile appSavegameFolder, List saveFiles) { - int size = saveFiles.size(); - DocumentFile[] sources = new DocumentFile[size]; - DocumentFile[] targets = new DocumentFile[size]; + @RequiresApi(api = Build.VERSION_CODES.P) + private void importSaveGames(ContentResolver resolver, + DocumentFile appSavegameFolder, + List saveFiles) { + int size = saveFiles.size(); + DocumentFile[] sources = new DocumentFile[size]; + DocumentFile[] targets = new DocumentFile[size]; boolean saveAsNew = false; for (int i = 0; i < size; i++) { @@ -456,22 +505,20 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O targets[i] = getOrCreateDocumentFile(appSavegameFolder, targetName); } - AndroidStorage.copyDocumentFilesFromToAsync(sources, - this, - targets, - (sucess) -> completeLoadSaveActivity(SLOT_NUMBER_IMPORT_SAVEGAMES, sucess)); - } + AndroidStorage.copyDocumentFilesFromToAsync(sources, + this, + targets, + getString(R.string.loadsave_importing_savegames), + (sucess) -> completeLoadSaveActivity( + SLOT_NUMBER_IMPORT_SAVEGAMES, + sucess)); + } - private void completeSavegameImportAndCheckIfDone(List importsNeedingConfirmation, int slot) { - importsNeedingConfirmation.remove((Object) slot); - if (importsNeedingConfirmation.isEmpty()) { - completeLoadSaveActivity(SLOT_NUMBER_IMPORT_SAVEGAMES); - } - } - - private boolean getExistsSavegameInOwnFiles(DocumentFile savegameFile, DocumentFile appSavegameFolder) { - if (savegameFile == null) - return false; + private boolean getExistsSavegameInOwnFiles(DocumentFile savegameFile, + DocumentFile appSavegameFolder) { + if (savegameFile == null) { + return false; + } DocumentFile foundFile = appSavegameFolder.findFile(Objects.requireNonNull(savegameFile.getName())); return foundFile != null && foundFile.exists(); @@ -494,106 +541,109 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O } } - private void importSaveGameFile(ContentResolver resolver, DocumentFile appSavegameFolder, DocumentFile itemFile, int slot) { - String targetName = Savegames.getSlotFileName(slot); - DocumentFile targetFile = getOrCreateDocumentFile(appSavegameFolder, targetName); - - if (targetFile == null || !targetName.equals(targetFile.getName())) { - showErrorImportingSaveGameUnknown();//TODO: maybe replace with a more specific error message - return; - } - - try { - AndroidStorage.copyDocumentFile(itemFile, resolver, targetFile); - } catch (IOException e) { - showErrorImportingSaveGameUnknown(); - e.printStackTrace(); - } - } - - private DocumentFile getOrCreateDocumentFile(DocumentFile folder, String targetName) { - DocumentFile targetFile = folder.findFile(targetName);//try finding the file - if (targetFile == null)//no file found, creating new one - targetFile = folder.createFile(Constants.NO_FILE_EXTENSION_MIME_TYPE, targetName); - return targetFile; - } + private DocumentFile getOrCreateDocumentFile(DocumentFile folder, String targetName) { + DocumentFile targetFile = folder.findFile(targetName);//try finding the file + if (targetFile == null)//no file found, creating new one + { + targetFile = folder.createFile(Constants.NO_FILE_EXTENSION_MIME_TYPE, targetName); + } + return targetFile; + } @RequiresApi(api = Build.VERSION_CODES.P) private void importWorldmap(Intent data) { Uri uri = data.getData(); - Context context = getApplicationContext(); - ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this).getContentResolver(); + Context context = AndorsTrailApplication.getApplicationFromActivity(this) + .getApplicationContext(); - File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY); - DocumentFile storageFolder = DocumentFile.fromFile(storageDir); - DocumentFile ownWorldmapFolder = storageFolder.findFile(Constants.FILENAME_WORLDMAP_DIRECTORY); - if (ownWorldmapFolder == null) { - ownWorldmapFolder = storageFolder.createDirectory(Constants.FILENAME_WORLDMAP_DIRECTORY); - } + DocumentFile chosenZip = DocumentFile.fromSingleUri(context, uri); + if (chosenZip == null || !chosenZip.isFile()) { + showErrorImportingWorldmapWrongDirectory(); + return; + } + String chosenZipName = chosenZip.getName(); + if (!chosenZipName.startsWith(Constants.FILENAME_WORLDMAP_DIRECTORY)) { + showErrorImportingWorldmapWrongDirectory(); + return; + } - DocumentFile chosenFolder = DocumentFile.fromTreeUri(context, uri); - if (chosenFolder == null || !chosenFolder.isDirectory()) { - showErrorImportingWorldmapWrongDirectory(); - return; - } - if (!Constants.FILENAME_WORLDMAP_DIRECTORY.equals(chosenFolder.getName())) { - //user did not select the worldmap folder directly - DocumentFile file = chosenFolder.findFile(Constants.FILENAME_WORLDMAP_DIRECTORY); - if (file == null || !file.isDirectory() || !Constants.FILENAME_WORLDMAP_DIRECTORY.equals(file.getName())) { - //could not find a worldmap folder in the users selection - showErrorImportingWorldmapWrongDirectory(); - return; - } + File ownWorldmapFolder = getOwnWorldmapFolder(context); - chosenFolder = file; - } - AndroidStorage.copyDocumentFilesToDirAsync(chosenFolder.listFiles(), - this, - ownWorldmapFolder, - (success) -> completeLoadSaveActivity(SLOT_NUMBER_IMPORT_WORLDMAP, success)); - } + AndroidStorage.unzipDocumentFileToDirectoryAsync(chosenZip, + this, + ownWorldmapFolder, + false, + getString(R.string.loadsave_importing_worldmap), + (success) -> completeLoadSaveActivity( + SLOT_NUMBER_IMPORT_WORLDMAP, + success)); + } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - private void clickExportSaveGames() { - startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(), -SLOT_NUMBER_EXPORT_SAVEGAMES); - } + private File getOwnWorldmapFolder(Context context) { + File storageDir = AndroidStorage.getStorageDirectory(context, + Constants.FILENAME_SAVEGAME_DIRECTORY); + File ownWorldmapFolder = null; + for (File f : storageDir.listFiles()) { + if (f.getName().equals(Constants.FILENAME_WORLDMAP_DIRECTORY)) { + ownWorldmapFolder = f; + break; + } + } + if (ownWorldmapFolder == null) { + ownWorldmapFolder = new File(storageDir, Constants.FILENAME_WORLDMAP_DIRECTORY); + ownWorldmapFolder.mkdir(); + } + return ownWorldmapFolder; + } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - private void clickImportSaveGames() { - startActivityForResult(AndroidStorage.getNewSelectMultipleSavegameFilesIntent(), -SLOT_NUMBER_IMPORT_SAVEGAMES); + @RequiresApi(api = Build.VERSION_CODES.P) + private void clickExportSaveGames() { + showStartExportInfo(view -> startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(), + -SLOT_NUMBER_EXPORT_SAVEGAMES)); + } + + @RequiresApi(api = Build.VERSION_CODES.P) + private void clickImportSaveGames() { + showStartImportSavesInfo(view -> startActivityForResult(AndroidStorage.getNewSelectMultipleSavegameFilesIntent(), + -SLOT_NUMBER_IMPORT_SAVEGAMES)); + } + + @RequiresApi(api = Build.VERSION_CODES.P) + private void clickImportWorldmap() { + showStartImportWorldmapInfo(view -> startActivityForResult(AndroidStorage.getNewSelectZipIntent(), + -SLOT_NUMBER_IMPORT_WORLDMAP)); } - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - private void clickImportWorldmap() { - startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(), -SLOT_NUMBER_IMPORT_WORLDMAP); + @RequiresApi(api = Build.VERSION_CODES.P) + private void showConfirmOverwriteByExportQuestion(ContentResolver resolver, + DocumentFile targetFolder, + File[] files) { + final CustomDialog d = CustomDialogFactory.createDialog(this, + getString(R.string.loadsave_export_overwrite_confirmation_title), + getResources().getDrawable(android.R.drawable.ic_dialog_alert), + getString(R.string.loadsave_export_overwrite_confirmation), + null, + true); - } - - @RequiresApi(api = Build.VERSION_CODES.P) - private void showConfirmOverwriteByExportQuestion(ContentResolver resolver, DocumentFile targetFolder, DocumentFile[] files) { - final CustomDialog d = CustomDialogFactory.createDialog(this, - getString(R.string.loadsave_export_overwrite_confirmation_title), - getResources().getDrawable(android.R.drawable.ic_dialog_alert), - getString(R.string.loadsave_export_overwrite_confirmation), - null, - true); - - CustomDialogFactory.addButton(d, android.R.string.yes, v -> exportSaveGamesFolderContentToFolder(resolver, targetFolder, files)); - CustomDialogFactory.addDismissButton(d, android.R.string.no); + CustomDialogFactory.addButton(d, + android.R.string.yes, + v -> exportSaveGamesFolderContentToFolder(targetFolder, + files)); + CustomDialogFactory.addDismissButton(d, android.R.string.no); CustomDialogFactory.show(d); } - @RequiresApi(api = Build.VERSION_CODES.N) - private void showConfirmOverwriteByImportQuestion(ContentResolver resolver, - DocumentFile appSavegameFolder, - List alreadyExistingFiles, - List newFiles) { - final String title = getString(R.string.loadsave_import_overwrite_confirmation_title); - String message = getString(R.string.loadsave_import_file_exists_question); + @RequiresApi(api = Build.VERSION_CODES.P) + private void showConfirmOverwriteByImportQuestion(ContentResolver resolver, + DocumentFile appSavegameFolder, + List alreadyExistingFiles, + List newFiles) { + final String title = getString(R.string.loadsave_import_overwrite_confirmation_title); + String message = getString(R.string.loadsave_import_file_exists_question); StringBuilder sb = new StringBuilder(); sb.append('\n'); @@ -619,10 +669,18 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O continue; } - StringBuilder messageSb = new StringBuilder(); - String existingFileDescription = getString(R.string.loadsave_import_existing_description, slot, existingFileHeader.describe()); - String importedFileDescription = getString(R.string.loadsave_import_imported_description, slot, importedFileHeader.describe()); - messageSb.append(getString(R.string.loadsave_import_file_exists_question, existingFileDescription, importedFileDescription)); + StringBuilder messageSb = new StringBuilder(); + String existingFileDescription = + getString(R.string.loadsave_import_existing_description, + Integer.toString(slot), + existingFileHeader.describe()); + String importedFileDescription = + getString(R.string.loadsave_import_imported_description, + Integer.toString(slot), + importedFileHeader.describe()); + messageSb.append(getString(R.string.loadsave_import_file_exists_question, + existingFileDescription, + importedFileDescription)); String m = messageSb.toString(); @@ -645,11 +703,13 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs); }); - CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_add_as_new, v -> { - newFiles.add(null);//add a null element as marker to know later if the next file should be imported as new or overwrite the existing one - newFiles.add(alreadyExistingFile); - GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs); - }); + CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_add_as_new, + v -> { + newFiles.add(null);//add a null element as marker to know later if the next file + // should be imported as new or overwrite the existing one + newFiles.add(alreadyExistingFile); + GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs); + }); CustomDialogFactory.addCancelButton(dialog, android.R.string.cancel); CustomDialogFactory.setCancelListener(dialog, v -> { @@ -662,23 +722,27 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs); } - @RequiresApi(api = Build.VERSION_CODES.N) - private void GoToNextConflictOrFinish(ContentResolver resolver, DocumentFile appSavegameFolder, List newFiles, ArrayList dialogs) { - if(dialogs.stream().count() > 0){ - CustomDialog d = dialogs.remove(0); - CustomDialogFactory.show(d); - } - else{ - importSaveGames(resolver, appSavegameFolder, newFiles); - } - } + @RequiresApi(api = Build.VERSION_CODES.P) + private void GoToNextConflictOrFinish(ContentResolver resolver, + DocumentFile appSavegameFolder, + List newFiles, + ArrayList dialogs) { + if (dialogs.stream().count() > 0) { + CustomDialog d = dialogs.remove(0); + CustomDialogFactory.show(d); + } + else { + importSaveGames(resolver, appSavegameFolder, newFiles); + } + } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (resultCode != Activity.RESULT_OK) - return; + if (resultCode != Activity.RESULT_OK) { + return; + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { switch (-requestCode) { @@ -713,19 +777,58 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O //region show Dialogs - private void showErrorImportingWorldmapWrongDirectory() { - final CustomDialog d = CustomDialogFactory.createErrorDialog(this, - getString(R.string.loadsave_import_worldmap_unsuccessfull), - getString(R.string.loadsave_import_worldmap_wrong_directory)); - CustomDialogFactory.show(d); - } + @RequiresApi(api = Build.VERSION_CODES.P) + private void showStartExportInfo(OnClickListener onOk) { + final CustomDialog d = CustomDialogFactory.createDialog(this, + getString(R.string.loadsave_export), + getResources().getDrawable(android.R.drawable.ic_dialog_info), + getString(R.string.loadsave_export_info), + null, + true); + CustomDialogFactory.addButton(d, android.R.string.yes, onOk); + CustomDialogFactory.addDismissButton(d, android.R.string.no); + CustomDialogFactory.show(d); + } - private void showErrorImportingSaveGameUnknown() { - final CustomDialog d = CustomDialogFactory.createErrorDialog(this, - getString(R.string.loadsave_import_save_unsuccessfull), - getString(R.string.loadsave_import_save_error_unknown)); - CustomDialogFactory.show(d); - } + @RequiresApi(api = Build.VERSION_CODES.P) + private void showStartImportSavesInfo(OnClickListener onOk) { + final CustomDialog d = CustomDialogFactory.createDialog(this, + getString(R.string.loadsave_import_save), + getResources().getDrawable(android.R.drawable.ic_dialog_info), + getString(R.string.loadsave_import_save_info), + null, + true); + CustomDialogFactory.addButton(d, android.R.string.yes, onOk); + CustomDialogFactory.addDismissButton(d, android.R.string.no); + CustomDialogFactory.show(d); + } + + @RequiresApi(api = Build.VERSION_CODES.P) + private void showStartImportWorldmapInfo(OnClickListener onOk) { + final CustomDialog d = CustomDialogFactory.createDialog(this, + getString(R.string.loadsave_import_worldmap), + getResources().getDrawable(android.R.drawable.ic_dialog_info), + getString(R.string.loadsave_import_worldmap_info), + null, + true); + CustomDialogFactory.addButton(d, android.R.string.yes, onOk); + CustomDialogFactory.addDismissButton(d, android.R.string.no); + CustomDialogFactory.show(d); + } + + private void showErrorImportingWorldmapWrongDirectory() { + final CustomDialog d = CustomDialogFactory.createErrorDialog(this, + getString(R.string.loadsave_import_worldmap_unsuccessfull), + getString(R.string.loadsave_import_worldmap_wrong_file)); + CustomDialogFactory.show(d); + } + + private void showErrorExportingSaveGamesUnknown() { + final CustomDialog d = CustomDialogFactory.createErrorDialog(this, + getString(R.string.loadsave_export_unsuccessfull), + getString(R.string.loadsave_export_error_unknown)); + CustomDialogFactory.show(d); + } private void showErrorLoadingEmptySlot() { final CustomDialog d = CustomDialogFactory.createErrorDialog(this, @@ -745,16 +848,15 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O CustomDialogFactory.show(d); } - private void showConfirmoverwriteQuestion(final int slot, String message) { - final String title = - getString(R.string.loadsave_save_overwrite_confirmation_title) + ' ' - + getString(R.string.loadsave_save_overwrite_confirmation_slot, slot); - final CustomDialog d = CustomDialogFactory.createDialog(this, - title, - getResources().getDrawable(android.R.drawable.ic_dialog_alert), - message, - null, - true); + private void showConfirmOverwriteQuestion(final int slot, String message) { + final String title = getString(R.string.loadsave_save_overwrite_confirmation_title) + ' ' + + getString(R.string.loadsave_save_overwrite_confirmation_slot, slot); + final CustomDialog d = CustomDialogFactory.createDialog(this, + title, + getResources().getDrawable(android.R.drawable.ic_dialog_alert), + message, + null, + true); CustomDialogFactory.addButton(d, android.R.string.yes, v -> completeLoadSaveActivity(slot)); CustomDialogFactory.addDismissButton(d, android.R.string.no); diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/AndroidStorage.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/AndroidStorage.java index a64a3d5ad..010f27ae4 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/AndroidStorage.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/AndroidStorage.java @@ -6,14 +6,12 @@ import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Environment; -import android.support.annotation.NonNull; import android.support.annotation.RequiresApi; import android.support.v4.content.FileProvider; import android.support.v4.provider.DocumentFile; import android.os.Handler; import android.os.Looper; -import android.webkit.MimeTypeMap; import com.gpl.rpg.AndorsTrail.R; import com.gpl.rpg.AndorsTrail.controller.Constants; @@ -22,12 +20,16 @@ import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.concurrent.CancellationException; import java.util.function.Consumer; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; public final class AndroidStorage { public static File getStorageDirectory(Context context, String name) { @@ -57,18 +59,20 @@ public final class AndroidStorage { return ret; } - public static boolean migrateToInternalStorage(Context context) { - try { - copy(new File(Environment.getExternalStorageDirectory(), Constants.CHEAT_DETECTION_FOLDER), - getStorageDirectory(context, Constants.CHEAT_DETECTION_FOLDER)); - copy(new File(Environment.getExternalStorageDirectory(), Constants.FILENAME_SAVEGAME_DIRECTORY), - getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY)); - } catch (IOException e) { - L.log("Error migrating data: " + e.toString()); - return false; - } - return true; - } + public static boolean migrateToInternalStorage(Context context) { + try { + copy(new File(Environment.getExternalStorageDirectory(), + Constants.CHEAT_DETECTION_FOLDER), + getStorageDirectory(context, Constants.CHEAT_DETECTION_FOLDER)); + copy(new File(Environment.getExternalStorageDirectory(), + Constants.FILENAME_SAVEGAME_DIRECTORY), + getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY)); + } catch (IOException e) { + L.log("Error migrating data: " + e); + return false; + } + return true; + } private static void copy(File sourceLocation, File targetLocation) throws IOException { if (!sourceLocation.exists()) { @@ -105,19 +109,167 @@ public final class AndroidStorage { } } + @RequiresApi(api = Build.VERSION_CODES.P) + public static void createZipDocumentFileFromFilesAsync(File[] files, + Context context, + DocumentFile targetDirectory, + String fileName, + String loadingMessage, + Consumer callback) { - public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile, ContentResolver resolver, DocumentFile targetFolder) throws IOException { - copyDocumentFileToNewOrExistingFile(sourceFile, resolver, targetFolder, Constants.NO_FILE_EXTENSION_MIME_TYPE); - } + BackgroundWorker worker = new BackgroundWorker<>(); + CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, + loadingMessage); + progressDialog.setOnCancelListener(dialog -> worker.cancel()); + ContentResolver resolver = context.getContentResolver(); + Handler handler = Handler.createAsync(Looper.getMainLooper()); - public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile, ContentResolver resolver, DocumentFile targetFolder, String mimeType) throws IOException { - String fileName = sourceFile.getName(); - DocumentFile file = targetFolder.findFile(fileName); - if (file == null) - file = targetFolder.createFile(mimeType, fileName); - if (file == null) - return; + worker.setTask(workerCallback -> { + try { + workerCallback.onInitialize(); + + //region create zip file + File zip = File.createTempFile("temp_worldmap", ".zip"); + try (OutputStream out = new FileOutputStream(zip)) { + ZipOutputStream zipOut = new ZipOutputStream(out); + for (int i = 0; i < files.length; i++) { + File file = files[i]; + try (FileInputStream fis = new FileInputStream(file)) { + workerCallback.onProgress((float) i / files.length); + zipOut.putNextEntry(new ZipEntry(file.getName())); + copyStream(fis, zipOut); + zipOut.closeEntry(); + } + } + zipOut.close(); + } + //endregion + + DocumentFile worldmapZip = DocumentFile.fromFile(zip); + DocumentFile worldmapTarget = targetDirectory.createFile("application/zip", + fileName); + if (worldmapTarget != null && worldmapTarget.exists()) { + AndroidStorage.copyDocumentFile(worldmapZip, resolver, worldmapTarget); + workerCallback.onComplete(true); + } + else { + throw new FileNotFoundException("Could not create File"); + } + } catch (NullPointerException e) { + if (worker.isCancelled()) { + workerCallback.onFailure(new CancellationException("Cancelled")); + } + else { + workerCallback.onFailure(e); + } + } catch (Exception e) { + workerCallback.onFailure(e); + } + }); + + worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback)); + worker.run(); + + + } + + public static void unzipToDirectory(File zipFile, + File targetDirectory, + boolean overwriteNotSkip) throws IOException { + + try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) { + unzipStreamToDirectory(targetDirectory, overwriteNotSkip, zis); + } + + } + + @RequiresApi(api = Build.VERSION_CODES.P) + public static void unzipDocumentFileToDirectoryAsync(DocumentFile zipFile, + Context context, + File targetDirectory, + boolean overwriteNotSkip, + String loadingMessage, + Consumer callback) { + + BackgroundWorker worker = new BackgroundWorker<>(); + CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, + loadingMessage); + progressDialog.setOnCancelListener(dialog -> worker.cancel()); + ContentResolver resolver = context.getContentResolver(); + Handler handler = Handler.createAsync(Looper.getMainLooper()); + + worker.setTask(workerCallback -> { + try { + workerCallback.onInitialize(); + workerCallback.onProgress(-1);//set dummy progress since we don't know the + // progress of the unzip + unzipDocumentFileToDirectory(zipFile, resolver, targetDirectory, overwriteNotSkip); + workerCallback.onComplete(true); + } catch (IOException e) { + workerCallback.onFailure(e); + } + }); + + worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback)); + worker.run(); + + } + + public static void unzipDocumentFileToDirectory(DocumentFile zipFile, + ContentResolver resolver, + File targetDirectory, + boolean overwriteNotSkip) throws IOException { + try (ZipInputStream zis = new ZipInputStream(resolver.openInputStream(zipFile.getUri()))) { + unzipStreamToDirectory(targetDirectory, overwriteNotSkip, zis); + } + } + + private static void unzipStreamToDirectory(File targetDirectory, + boolean overwriteNotSkip, + ZipInputStream zis) throws IOException { + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + File file = new File(targetDirectory, entry.getName()); + + if (entry.isDirectory()) { + file.mkdirs(); + } + else { + file.getParentFile().mkdirs(); + if (file.exists() && !overwriteNotSkip) { + continue; + } + + try (FileOutputStream fos = new FileOutputStream(file)) { + copyStream(zis, fos); + } + } + } + } + + public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile, + ContentResolver resolver, + DocumentFile targetFolder) throws IOException { + copyDocumentFileToNewOrExistingFile(sourceFile, + resolver, + targetFolder, + Constants.NO_FILE_EXTENSION_MIME_TYPE); + } + + + public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile, + ContentResolver resolver, + DocumentFile targetFolder, + String mimeType) throws IOException { + String fileName = sourceFile.getName(); + DocumentFile file = targetFolder.findFile(fileName); + if (file == null) { + file = targetFolder.createFile(mimeType, fileName); + } + if (file == null) { + return; + } AndroidStorage.copyDocumentFile(sourceFile, resolver, file); } @@ -129,46 +281,23 @@ public final class AndroidStorage { } } + public static String getUrlForFile(Context context, File worldmap) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + String applicationId = context.getPackageName(); + Uri uri = FileProvider.getUriForFile(context, + applicationId + ".fileprovider", + worldmap); + return uri.toString(); + } + else { + return "file://" + worldmap.getAbsolutePath(); + } + } - /** - * Gets the MIME-Type for a file.

- * Fallback value is '* / *' (without spaces)

- * Mostly copied together from: StackOverflow - */ - @NonNull - public static String getMimeType(ContentResolver resolver, Uri uri) { - String type = null; - if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { - type = resolver.getType(uri); - return type; - } - - final String extension = MimeTypeMap.getFileExtensionFromUrl(uri.getPath()); - if (extension != null) { - type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase()); - } - if (type == null) { - type = "*/*"; // fallback type. - } - return type; - } - - public static String getUrlForFile(Context context, File worldmap) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - String applicationId = context.getPackageName(); - Uri uri = FileProvider.getUriForFile(context, applicationId + ".fileprovider", worldmap); - return uri.toString(); - } else { - return "file://" + worldmap.getAbsolutePath(); - } - } - - - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - public static Intent getNewOpenDirectoryIntent() { - Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); - return intent; - } + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public static Intent getNewOpenDirectoryIntent() { + return new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); + } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public static Intent getNewSelectMultipleSavegameFilesIntent() { @@ -179,78 +308,93 @@ public final class AndroidStorage { return intent; } - public static void copyDocumentFilesFromToAsync(DocumentFile[] sources, Context context, DocumentFile[] targets, Consumer callback) { - if(sources.length != targets.length) - { - throw new IllegalArgumentException("Both arrays, target & source have to have the same size"); - } + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public static Intent getNewSelectZipIntent() { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("application/zip"); + return intent; + } - BackgroundWorker worker = new BackgroundWorker(); - CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context); - progressDialog.setOnCancelListener(dialog -> worker.cancel()); - ContentResolver resolver = context.getContentResolver(); - Handler handler = Handler.createAsync(Looper.getMainLooper()); + @RequiresApi(api = Build.VERSION_CODES.P) + public static void copyDocumentFilesFromToAsync(DocumentFile[] sources, + Context context, + DocumentFile[] targets, + String loadingMessage, + Consumer callback) { + if (sources.length != targets.length) { + throw new IllegalArgumentException( + "Both arrays, target & source have to have the same size"); + } - worker.setTask(new BackgroundWorker.worker() { - @Override - public void doWork(BackgroundWorkerCallback callback) { - try { - callback.onInitialize(); - for (int i = 0; i < sources.length ; i++) { - if (worker.isCancelled()) { - callback.onFailure(new CancellationException("Cancelled")); - return; - } - DocumentFile source = sources[i]; - DocumentFile target = targets[i]; + BackgroundWorker worker = new BackgroundWorker<>(); + + CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, + loadingMessage); + progressDialog.setOnCancelListener(dialog -> worker.cancel()); + + ContentResolver resolver = context.getContentResolver(); + Handler handler = Handler.createAsync(Looper.getMainLooper()); + + worker.setTask(workerCallback -> { + try { + workerCallback.onInitialize(); + for (int i = 0; i < sources.length; i++) { + if (worker.isCancelled()) { + workerCallback.onFailure(new CancellationException("Cancelled")); + return; + } + DocumentFile source = sources[i]; + DocumentFile target = targets[i]; if(source == null || target == null) { continue; } + copyDocumentFile(source, resolver, target); + float progress = i / (float) sources.length; + workerCallback.onProgress(progress); + } + workerCallback.onComplete(true); + } catch (NullPointerException e) { + if (worker.isCancelled()) { + workerCallback.onFailure(new CancellationException("Cancelled")); + return; + } + } catch (Exception e) { + workerCallback.onFailure(e); + } + }); + worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback)); + worker.run(); + } - copyDocumentFile(source, resolver,target); - float progress = i /(float) sources.length; - callback.onProgress(progress); - } - callback.onComplete(true); - } catch (NullPointerException e) { - if (worker.isCancelled()) { - callback.onFailure(new CancellationException("Cancelled")); - return; - } - } catch (Exception e) { - callback.onFailure(e); - } - } - }); - worker.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback)); - worker.run(); - } + @RequiresApi(api = Build.VERSION_CODES.P) + public static void copyDocumentFilesToDirAsync(DocumentFile[] files, + Context context, + DocumentFile targetDirectory, + String loadingMessage, + Consumer callback) { + BackgroundWorker worker = new BackgroundWorker<>(); + CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, + loadingMessage); + progressDialog.setOnCancelListener(dialog -> worker.cancel()); + ContentResolver resolver = context.getContentResolver(); + Handler handler = Handler.createAsync(Looper.getMainLooper()); - @RequiresApi(api = Build.VERSION_CODES.P) - public static void copyDocumentFilesToDirAsync(DocumentFile[] files, - Context context, - DocumentFile targetDirectory, - Consumer callback) { - BackgroundWorker worker = new BackgroundWorker<>(); - CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context); - progressDialog.setOnCancelListener(dialog -> worker.cancel()); - ContentResolver resolver = context.getContentResolver(); - Handler handler = Handler.createAsync(Looper.getMainLooper()); - - worker.setTask(workerCallback -> { - try { - workerCallback.onInitialize(); - for (int i = 0; i < files.length; i++) { - if (worker.isCancelled()) { - workerCallback.onFailure(new CancellationException("Cancelled")); - return; - } - DocumentFile file = files[i]; - if(file == null) - continue; + worker.setTask(workerCallback -> { + try { + workerCallback.onInitialize(); + for (int i = 0; i < files.length; i++) { + if (worker.isCancelled()) { + workerCallback.onFailure(new CancellationException("Cancelled")); + return; + } + DocumentFile file = files[i]; + if (file == null) { + continue; + } copyDocumentFileToNewOrExistingFile(file, resolver, targetDirectory); float progress = i /(float) files.length; @@ -281,46 +425,62 @@ public final class AndroidStorage { }); } - @Override - public void onProgress(float progress) { - handler.post(() -> { - int intProgress = (int) (progress * 100); - if(this.progress == intProgress) - return; + @Override + public void onProgress(float progress) { + handler.post(() -> { + int intProgress = (int) (progress * 100); + if (this.progress == intProgress) { + return; + } - this.progress = intProgress; - CustomDialogFactory.setDesc(progressDialog, intProgress + "%"); - }); - } + this.progress = intProgress; - @RequiresApi(api = Build.VERSION_CODES.N) - @Override - public void onFailure(Exception e) { - handler.post(() -> { - progressDialog.dismiss(); - callback.accept(false); - }); - } + if (progress == -1) { + CustomDialogFactory.setDesc(progressDialog, null); + return; + } - @RequiresApi(api = Build.VERSION_CODES.N) - @Override - public void onComplete(Boolean result) { - handler.post(() -> { - progressDialog.dismiss(); - callback.accept(true); - }); - } - }; - } + CustomDialogFactory.setDesc(progressDialog, intProgress + "%"); + }); + } - private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context) { - return CustomDialogFactory.createDialog(context, - context.getResources().getString(R.string.dialog_loading_message), - context.getResources().getDrawable(R.drawable.loading_anim), - null, - null, - false, - false); - } + @RequiresApi(api = Build.VERSION_CODES.N) + @Override + public void onFailure(Exception e) { + this.onComplete(false); + } + + @RequiresApi(api = Build.VERSION_CODES.N) + @Override + public void onComplete(Boolean result) { + handler.post(() -> { + progressDialog.dismiss(); + callback.accept(result); + }); + } + }; + } + + private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context) { + return getLoadingDialog(context, null); + } + + private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context, + String message) { + if (message == null) { + message = context.getResources().getString(R.string.dialog_loading_message); + } + + CustomDialogFactory.CustomDialog dialog = CustomDialogFactory.createDialog(context, + message, + context.getResources() + .getDrawable(R.drawable.loading_anim), + null, + null, + true, + false); + CustomDialogFactory.addCancelButton(dialog, android.R.string.no); + return dialog; + } } diff --git a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/BackgroundWorker.java b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/BackgroundWorker.java index 79e3343cd..b9820f5c6 100644 --- a/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/BackgroundWorker.java +++ b/AndorsTrail/app/src/main/java/com/gpl/rpg/AndorsTrail/util/BackgroundWorker.java @@ -4,14 +4,14 @@ import java.util.concurrent.Executors; public final class BackgroundWorker { boolean cancelled = false; - worker task; - BackgroundWorkerCallback callback; + worker task; + BackgroundWorkerCallback callback; - public void setTask(worker task) { + public void setTask(worker task) { this.task = task; } - public void setCallback(BackgroundWorkerCallback callback) { + public void setCallback(BackgroundWorkerCallback callback) { this.callback = callback; } @@ -20,7 +20,7 @@ public final class BackgroundWorker { } interface worker { - void doWork(BackgroundWorkerCallback callback); + void doWork(BackgroundWorkerCallback callback); } interface BackgroundWorkerCallback { diff --git a/AndorsTrail/res/values/strings.xml b/AndorsTrail/res/values/strings.xml index b337fe7c8..9d8dce163 100644 --- a/AndorsTrail/res/values/strings.xml +++ b/AndorsTrail/res/values/strings.xml @@ -485,31 +485,40 @@ You may select %1$d skills to improve. This level also gives you a new skill point to spend! - Create new savegame slot - Overwrite savegame? - This savegame contains a different player name (%1$s) than your current player name (%2$s). Are you sure you want to overwrite this savegame? + Create new Savegame slot + Overwrite Savegame? + This Savegame contains a different player name (%1$s) than your current player name (%2$s). Are you sure you want to overwrite this savegame? - Export savegames + Export Savegames + Please select the directory to export all files to. + Exporting Savegames + Exporting Worldmap Export successful Export unsuccessful Overwrite Existing Files? The target Folder contains existing files with the same name of some Files that should be exported. Are you sure you want to overwrite those files? - Import savegames + An unknown error occurred while exporting. + + Import Savegames + Please select all Savegames you want to import. + Importing Savegames Import successful Import unsuccessful - An unknown error occurred while importing. + An unknown error occurred while importing. Overwrite Existing Slot? - Theere is already a savegame in the target slot. Do you want to keep the existing save, overwrite it with the imported save or import the save to a slot?\n\n%1$s\n\n%2$s + There is already a savegame in the target slot. Do you want to keep the existing save, overwrite it with the imported save or import the save to a slot?\n\n%1$s\n\n%2$s Keep existing save Keep imported save Add as new Save Existing save: Slot: %1$s:\n\t%2$s Imported save: Slot: %1$s:\n\t%2$s Import worldmap + Please select the Worldmap zip file. + Importing worldmap Import of Worldmap successful Import of Worldmap unsuccessful - Are you sure there is a worldmap in this folder? Please select the folder called \'worldmap\' inside your export location. + Are you sure you selected a worldmap? Please select the zip file called \'worldmap.zip\' that was exported into your export location. Ordinary Quest item