mirror of
https://github.com/OMGeeky/andors-trail.git
synced 2026-02-23 15:38:29 +01:00
Merge remote-tracking branch 'origin/V0.8.4' into V0.8.4
This commit is contained in:
@@ -11,9 +11,7 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -122,8 +120,7 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
|
|
||||||
boolean hasSavegames = !Savegames.getUsedSavegameSlots(this).isEmpty();
|
boolean hasSavegames = !Savegames.getUsedSavegameSlots(this).isEmpty();
|
||||||
exportSaves.setEnabled(hasSavegames);
|
exportSaves.setEnabled(hasSavegames);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
exportImportContainer.setVisibility(View.GONE);
|
exportImportContainer.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,12 +130,17 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
private static final int WRITE_EXTERNAL_STORAGE_REQUEST = 2;
|
private static final int WRITE_EXTERNAL_STORAGE_REQUEST = 2;
|
||||||
|
|
||||||
private void checkAndRequestPermissions() {
|
private void checkAndRequestPermissions() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||||
if (getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
||||||
this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_REQUEST);
|
if (getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
|
||||||
|
READ_EXTERNAL_STORAGE_REQUEST);
|
||||||
}
|
}
|
||||||
if (getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
if (getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
this.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST);
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
this.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
|
WRITE_EXTERNAL_STORAGE_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,11 +154,15 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSavegameSlotButtons(ViewGroup parent, LayoutParams params, List<Integer> usedSavegameSlots) {
|
private void addSavegameSlotButtons(ViewGroup parent,
|
||||||
|
LayoutParams params,
|
||||||
|
List<Integer> usedSavegameSlots) {
|
||||||
int unused = 1;
|
int unused = 1;
|
||||||
for (int slot : usedSavegameSlots) {
|
for (int slot : usedSavegameSlots) {
|
||||||
final FileHeader header = Savegames.quickload(this, slot);
|
final FileHeader header = Savegames.quickload(this, slot);
|
||||||
if (header == null) continue;
|
if (header == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
while (unused < slot) {
|
while (unused < slot) {
|
||||||
Button b = new Button(this);
|
Button b = new Button(this);
|
||||||
@@ -180,65 +186,76 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelLoadSaveActivity(int slot){
|
private void cancelLoadSaveActivity(int slot) {
|
||||||
completeLoadSaveActivity(slot, false);
|
completeLoadSaveActivity(slot, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void completeLoadSaveActivity(int slot) {
|
private void completeLoadSaveActivity(int slot) {
|
||||||
completeLoadSaveActivity(slot, true);
|
completeLoadSaveActivity(slot, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void completeLoadSaveActivity(int slot, boolean success) {
|
private void completeLoadSaveActivity(int slot, boolean success) {
|
||||||
Intent i = new Intent();
|
Intent i = new Intent();
|
||||||
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) {
|
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) {
|
||||||
slot = getFirstFreeSlot();
|
slot = getFirstFreeSlot();
|
||||||
} else if (slot == SLOT_NUMBER_EXPORT_SAVEGAMES
|
} else if (slot == SLOT_NUMBER_EXPORT_SAVEGAMES
|
||||||
|| slot == SLOT_NUMBER_IMPORT_SAVEGAMES
|
|| slot == SLOT_NUMBER_IMPORT_SAVEGAMES
|
||||||
|| slot == SLOT_NUMBER_IMPORT_WORLDMAP) {
|
|| slot == SLOT_NUMBER_IMPORT_WORLDMAP) {
|
||||||
i.putExtra("import_export", true);
|
i.putExtra("import_export", true);
|
||||||
|
|
||||||
if(slot == SLOT_NUMBER_IMPORT_WORLDMAP){
|
if (slot == SLOT_NUMBER_IMPORT_WORLDMAP) {
|
||||||
i.putExtra("import_worldmap", true);
|
i.putExtra("import_worldmap", true);
|
||||||
}
|
}
|
||||||
if(slot == SLOT_NUMBER_IMPORT_SAVEGAMES){
|
if (slot == SLOT_NUMBER_IMPORT_SAVEGAMES) {
|
||||||
i.putExtra("import_savegames", true);
|
i.putExtra("import_savegames", true);
|
||||||
}
|
}
|
||||||
if(slot == SLOT_NUMBER_EXPORT_SAVEGAMES){
|
if (slot == SLOT_NUMBER_EXPORT_SAVEGAMES) {
|
||||||
i.putExtra("export", true);
|
i.putExtra("export", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (slot < SLOT_NUMBER_FIRST_SLOT)
|
} else if (slot < SLOT_NUMBER_FIRST_SLOT) {
|
||||||
slot = SLOT_NUMBER_FIRST_SLOT;
|
slot = SLOT_NUMBER_FIRST_SLOT;
|
||||||
|
}
|
||||||
|
|
||||||
i.putExtra("slot", slot);
|
i.putExtra("slot", slot);
|
||||||
if(success) setResult(Activity.RESULT_OK, i);
|
if (success) {
|
||||||
else setResult(Activity.RESULT_CANCELED, i);
|
setResult(Activity.RESULT_OK, i);
|
||||||
|
} else {
|
||||||
|
setResult(Activity.RESULT_CANCELED, i);
|
||||||
|
}
|
||||||
LoadSaveActivity.this.finish();
|
LoadSaveActivity.this.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getFirstFreeSlot() {
|
private int getFirstFreeSlot() {
|
||||||
int slot;
|
int slot;
|
||||||
List<Integer> usedSlots = Savegames.getUsedSavegameSlots(this);
|
List<Integer> usedSlots = Savegames.getUsedSavegameSlots(this);
|
||||||
if (usedSlots.isEmpty())
|
if (usedSlots.isEmpty()) {
|
||||||
slot = SLOT_NUMBER_FIRST_SLOT;
|
slot = SLOT_NUMBER_FIRST_SLOT;
|
||||||
else slot = Collections.max(usedSlots) + 1;
|
} else {
|
||||||
|
slot = Collections.max(usedSlots) + 1;
|
||||||
|
}
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getConfirmOverwriteQuestion(int slot) {
|
private String getConfirmOverwriteQuestion(int slot) {
|
||||||
if (isLoading)
|
if (isLoading) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return getConfirmOverwriteQuestionIgnoringLoading(slot);
|
return getConfirmOverwriteQuestionIgnoringLoading(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getConfirmOverwriteQuestionIgnoringLoading(int slot) {
|
private String getConfirmOverwriteQuestionIgnoringLoading(int slot) {
|
||||||
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT)
|
if (slot == SLOT_NUMBER_CREATE_NEW_SLOT) {
|
||||||
return null;//creating a new savegame
|
return null;//creating a new savegame
|
||||||
|
}
|
||||||
|
|
||||||
if (!Savegames.getSlotFile(slot, this).exists())
|
if (!Savegames.getSlotFile(slot, this).exists()) {
|
||||||
return null;//nothing in slot to overwrite
|
return null;//nothing in slot to overwrite
|
||||||
|
}
|
||||||
|
|
||||||
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_ALWAYS) {
|
if (preferences.displayOverwriteSavegame
|
||||||
|
== AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_ALWAYS) {
|
||||||
return getString(R.string.loadsave_save_overwrite_confirmation_all);
|
return getString(R.string.loadsave_save_overwrite_confirmation_all);
|
||||||
}
|
}
|
||||||
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_NEVER) {
|
if (preferences.displayOverwriteSavegame == AndorsTrailPreferences.CONFIRM_OVERWRITE_SAVEGAME_NEVER) {
|
||||||
@@ -247,10 +264,14 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
|
|
||||||
final String currentPlayerName = model.player.getName();
|
final String currentPlayerName = model.player.getName();
|
||||||
final FileHeader header = Savegames.quickload(this, slot);
|
final FileHeader header = Savegames.quickload(this, slot);
|
||||||
if (header == null) return null;
|
if (header == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
final String savedPlayerName = header.playerName;
|
final String savedPlayerName = header.playerName;
|
||||||
if (currentPlayerName.equals(savedPlayerName)) return null; //if the names match
|
if (currentPlayerName.equals(savedPlayerName)) {
|
||||||
|
return null; //if the names match
|
||||||
|
}
|
||||||
|
|
||||||
return getString(R.string.loadsave_save_overwrite_confirmation, savedPlayerName, currentPlayerName);
|
return getString(R.string.loadsave_save_overwrite_confirmation, savedPlayerName, currentPlayerName);
|
||||||
}
|
}
|
||||||
@@ -259,7 +280,7 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
final int slot = (Integer) view.getTag();
|
final int slot = (Integer) view.getTag();
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
switch (slot) {
|
switch (slot) {
|
||||||
case SLOT_NUMBER_IMPORT_WORLDMAP:
|
case SLOT_NUMBER_IMPORT_WORLDMAP:
|
||||||
clickImportWorldmap();
|
clickImportWorldmap();
|
||||||
@@ -273,8 +294,9 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isLoading
|
if (!isLoading
|
||||||
&& slot != SLOT_NUMBER_CREATE_NEW_SLOT
|
&& slot != SLOT_NUMBER_CREATE_NEW_SLOT
|
||||||
&& AndorsTrailApplication.CURRENT_VERSION == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
|
&& AndorsTrailApplication.CURRENT_VERSION
|
||||||
|
== AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
|
||||||
if (!isOverwriteTargetInIncompatibleVersion(slot)) {
|
if (!isOverwriteTargetInIncompatibleVersion(slot)) {
|
||||||
saveOrOverwriteSavegame(slot);
|
saveOrOverwriteSavegame(slot);
|
||||||
}
|
}
|
||||||
@@ -288,7 +310,7 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
private void saveOrOverwriteSavegame(int slot) {
|
private void saveOrOverwriteSavegame(int slot) {
|
||||||
final String message = getConfirmOverwriteQuestion(slot);
|
final String message = getConfirmOverwriteQuestion(slot);
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
showConfirmoverwriteQuestion(slot, message);
|
showConfirmOverwriteQuestion(slot, message);
|
||||||
} else {
|
} else {
|
||||||
completeLoadSaveActivity(slot);
|
completeLoadSaveActivity(slot);
|
||||||
}
|
}
|
||||||
@@ -296,8 +318,11 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
|
|
||||||
private boolean isOverwriteTargetInIncompatibleVersion(int slot) {
|
private boolean isOverwriteTargetInIncompatibleVersion(int slot) {
|
||||||
final FileHeader header = Savegames.quickload(this, slot);
|
final FileHeader header = Savegames.quickload(this, slot);
|
||||||
if (header != null && header.fileversion != AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
|
if (header != null
|
||||||
final CustomDialog d = CustomDialogFactory.createErrorDialog(this, "Overwriting not allowed", "You are currently using a development version of Andor's trail. Overwriting a regular savegame is not allowed in development mode.");
|
&& header.fileversion != AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION) {
|
||||||
|
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
|
||||||
|
"Overwriting not allowed",
|
||||||
|
"You are currently using a development version of Andor's trail. Overwriting a regular savegame is not allowed in development mode.");
|
||||||
CustomDialogFactory.show(d);
|
CustomDialogFactory.show(d);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -306,28 +331,32 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
|
|
||||||
//region Imports/Exports
|
//region Imports/Exports
|
||||||
|
|
||||||
|
//region Export
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
private void exportSaveGames(Intent data) {
|
private void exportSaveGames(Intent data) {
|
||||||
Uri uri = data.getData();
|
Uri uri = data.getData();
|
||||||
|
|
||||||
Context context = getApplicationContext();
|
Context context = getApplicationContext();
|
||||||
ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this).getContentResolver();
|
ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this)
|
||||||
|
.getContentResolver();
|
||||||
|
|
||||||
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
File storageDir = AndroidStorage.getStorageDirectory(context,
|
||||||
DocumentFile source = DocumentFile.fromFile(storageDir);
|
Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||||
DocumentFile target = DocumentFile.fromTreeUri(context, uri);
|
DocumentFile target = DocumentFile.fromTreeUri(context, uri);
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DocumentFile[] files = source.listFiles();
|
File[] files = storageDir.listFiles();
|
||||||
|
if (files == null) {
|
||||||
|
showErrorExportingSaveGamesUnknown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boolean hasExistingFiles = false;
|
boolean hasExistingFiles = false;
|
||||||
for (DocumentFile file :
|
for (File file : files) {
|
||||||
files) {
|
|
||||||
String fileName = file.getName();
|
String fileName = file.getName();
|
||||||
if (fileName == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
DocumentFile existingFile = target.findFile(fileName);
|
DocumentFile existingFile = target.findFile(fileName);
|
||||||
if (existingFile != null) {
|
if (existingFile != null) {
|
||||||
@@ -339,45 +368,70 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
if (hasExistingFiles) {
|
if (hasExistingFiles) {
|
||||||
showConfirmOverwriteByExportQuestion(resolver, target, files);
|
showConfirmOverwriteByExportQuestion(resolver, target, files);
|
||||||
} else {
|
} else {
|
||||||
exportSaveGamesFolderContentToFolder(resolver, target, files);
|
exportSaveGamesFolderContentToFolder(target, files);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
private void exportSaveGamesFolderContentToFolder(ContentResolver resolver, DocumentFile target, DocumentFile[] files) {
|
private void exportSaveGamesFolderContentToFolder(DocumentFile target, File[] files) {
|
||||||
DocumentFile[] sourceFiles = new DocumentFile[files.length];
|
DocumentFile[] sourceFiles = new DocumentFile[files.length];
|
||||||
|
|
||||||
DocumentFile[] worldmapFiles = null;
|
File[] worldmapFiles = null;
|
||||||
|
|
||||||
for (int i = 0; i < files.length; i++) {
|
for (int i = 0; i < files.length; i++) {
|
||||||
DocumentFile file = files[i];
|
File file = files[i];
|
||||||
if (file.isFile()) {
|
if (file.isFile()) {
|
||||||
sourceFiles[i] = file;
|
sourceFiles[i] = DocumentFile.fromFile(file);
|
||||||
} else if (file.isDirectory() && Objects.equals(file.getName(), Constants.FILENAME_WORLDMAP_DIRECTORY)) {
|
} else if (file.isDirectory() && Objects.equals(file.getName(),
|
||||||
|
Constants.FILENAME_WORLDMAP_DIRECTORY)) {
|
||||||
worldmapFiles = file.listFiles();
|
worldmapFiles = file.listFiles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Context context =this;
|
Context context = this;
|
||||||
DocumentFile[] finalWorldmapFiles = worldmapFiles;
|
File[] finalWorldmapFiles = worldmapFiles;
|
||||||
AndroidStorage.copyDocumentFilesToDirAsync(sourceFiles,
|
CopyFilesToExternalFolder(target, sourceFiles, context, finalWorldmapFiles);
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
|
private void CopyFilesToExternalFolder(DocumentFile target,
|
||||||
|
DocumentFile[] sourceFiles,
|
||||||
|
Context context,
|
||||||
|
File[] finalWorldmapFiles) {
|
||||||
|
AndroidStorage.copyDocumentFilesToDirAsync(sourceFiles,
|
||||||
|
context,
|
||||||
|
target,
|
||||||
|
getString(R.string.loadsave_exporting_savegames),
|
||||||
|
(success) -> {
|
||||||
|
if (success) {
|
||||||
|
CopyWorldmapFilesAsZip(target,
|
||||||
|
context,
|
||||||
|
finalWorldmapFiles);
|
||||||
|
} else {
|
||||||
|
completeLoadSaveActivity(
|
||||||
|
SLOT_NUMBER_EXPORT_SAVEGAMES,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
|
private void CopyWorldmapFilesAsZip(DocumentFile target,
|
||||||
|
Context context,
|
||||||
|
File[] finalWorldmapFiles) {
|
||||||
|
AndroidStorage.createZipDocumentFileFromFilesAsync(finalWorldmapFiles,
|
||||||
|
context,
|
||||||
|
target,
|
||||||
|
Constants.FILENAME_WORLDMAP_DIRECTORY,
|
||||||
|
getString(R.string.loadsave_exporting_worldmap),
|
||||||
|
(successWorldmap) -> completeLoadSaveActivity(
|
||||||
|
SLOT_NUMBER_EXPORT_SAVEGAMES,
|
||||||
|
successWorldmap));
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
private void importSaveGames(Intent data) {
|
private void importSaveGames(Intent data) {
|
||||||
Uri uri = data.getData();
|
Uri uri = data.getData();
|
||||||
ClipData uris = data.getClipData();
|
ClipData uris = data.getClipData();
|
||||||
@@ -388,7 +442,8 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
}
|
}
|
||||||
|
|
||||||
Context context = getApplicationContext();
|
Context context = getApplicationContext();
|
||||||
ContentResolver resolver = context.getContentResolver();
|
ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this)
|
||||||
|
.getContentResolver();
|
||||||
|
|
||||||
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||||
DocumentFile appSavegameFolder = DocumentFile.fromFile(storageDir);
|
DocumentFile appSavegameFolder = DocumentFile.fromFile(storageDir);
|
||||||
@@ -397,14 +452,18 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
uriList.add(uri);
|
uriList.add(uri);
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < uris.getItemCount(); i++)
|
for (int i = 0; i < uris.getItemCount(); i++) {
|
||||||
uriList.add(uris.getItemAt(i).getUri());
|
uriList.add(uris.getItemAt(i).getUri());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
importSaveGamesFromUris(context, resolver, appSavegameFolder, uriList);
|
importSaveGamesFromUris(context, resolver, appSavegameFolder, uriList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
private void importSaveGamesFromUris(Context context, ContentResolver resolver, DocumentFile appSavegameFolder, List<Uri> uriList) {
|
private void importSaveGamesFromUris(Context context,
|
||||||
|
ContentResolver resolver,
|
||||||
|
DocumentFile appSavegameFolder,
|
||||||
|
List<Uri> uriList) {
|
||||||
int count = uriList.size();
|
int count = uriList.size();
|
||||||
|
|
||||||
ArrayList<DocumentFile> alreadyExistingFiles = new ArrayList<>();
|
ArrayList<DocumentFile> alreadyExistingFiles = new ArrayList<>();
|
||||||
@@ -414,10 +473,11 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
Uri item = uriList.get(i);
|
Uri item = uriList.get(i);
|
||||||
DocumentFile itemFile = DocumentFile.fromSingleUri(context, item);
|
DocumentFile itemFile = DocumentFile.fromSingleUri(context, item);
|
||||||
boolean fileAlreadyExists = getExistsSavegameInOwnFiles(itemFile, appSavegameFolder);
|
boolean fileAlreadyExists = getExistsSavegameInOwnFiles(itemFile, appSavegameFolder);
|
||||||
if (fileAlreadyExists)
|
if (fileAlreadyExists) {
|
||||||
alreadyExistingFiles.add(itemFile);
|
alreadyExistingFiles.add(itemFile);
|
||||||
else
|
} else {
|
||||||
newFiles.add(itemFile);
|
newFiles.add(itemFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alreadyExistingFiles.size() > 0) {
|
if (alreadyExistingFiles.size() > 0) {
|
||||||
@@ -427,7 +487,10 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importSaveGames(ContentResolver resolver, DocumentFile appSavegameFolder, List<DocumentFile> saveFiles) {
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
|
private void importSaveGames(ContentResolver resolver,
|
||||||
|
DocumentFile appSavegameFolder,
|
||||||
|
List<DocumentFile> saveFiles) {
|
||||||
int size = saveFiles.size();
|
int size = saveFiles.size();
|
||||||
DocumentFile[] sources = new DocumentFile[size];
|
DocumentFile[] sources = new DocumentFile[size];
|
||||||
DocumentFile[] targets = new DocumentFile[size];
|
DocumentFile[] targets = new DocumentFile[size];
|
||||||
@@ -457,21 +520,18 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
}
|
}
|
||||||
|
|
||||||
AndroidStorage.copyDocumentFilesFromToAsync(sources,
|
AndroidStorage.copyDocumentFilesFromToAsync(sources,
|
||||||
this,
|
this,
|
||||||
targets,
|
targets,
|
||||||
(sucess) -> completeLoadSaveActivity(SLOT_NUMBER_IMPORT_SAVEGAMES, sucess));
|
getString(R.string.loadsave_importing_savegames),
|
||||||
}
|
(sucess) -> completeLoadSaveActivity(
|
||||||
|
SLOT_NUMBER_IMPORT_SAVEGAMES,
|
||||||
private void completeSavegameImportAndCheckIfDone(List<Integer> importsNeedingConfirmation, int slot) {
|
sucess));
|
||||||
importsNeedingConfirmation.remove((Object) slot);
|
|
||||||
if (importsNeedingConfirmation.isEmpty()) {
|
|
||||||
completeLoadSaveActivity(SLOT_NUMBER_IMPORT_SAVEGAMES);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getExistsSavegameInOwnFiles(DocumentFile savegameFile, DocumentFile appSavegameFolder) {
|
private boolean getExistsSavegameInOwnFiles(DocumentFile savegameFile, DocumentFile appSavegameFolder) {
|
||||||
if (savegameFile == null)
|
if (savegameFile == null) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
DocumentFile foundFile = appSavegameFolder.findFile(Objects.requireNonNull(savegameFile.getName()));
|
DocumentFile foundFile = appSavegameFolder.findFile(Objects.requireNonNull(savegameFile.getName()));
|
||||||
return foundFile != null && foundFile.exists();
|
return foundFile != null && foundFile.exists();
|
||||||
@@ -479,7 +539,6 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
|
|
||||||
private int getSlotFromSavegameFileName(String fileName) {
|
private int getSlotFromSavegameFileName(String fileName) {
|
||||||
if (fileName == null || !fileName.startsWith(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX)) {
|
if (fileName == null || !fileName.startsWith(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX)) {
|
||||||
//TODO: Maybe output a message that the file didn't have the right name?
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
String slotStr = fileName.substring(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX.length());
|
String slotStr = fileName.substring(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX.length());
|
||||||
@@ -489,32 +548,16 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
slot = Integer.parseInt(slotStr);
|
slot = Integer.parseInt(slotStr);
|
||||||
return slot;
|
return slot;
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
//TODO: Maybe output a message that the file didn't have the right name?
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
private DocumentFile getOrCreateDocumentFile(DocumentFile folder, String targetName) {
|
||||||
DocumentFile targetFile = folder.findFile(targetName);//try finding the file
|
DocumentFile targetFile = folder.findFile(targetName);//try finding the file
|
||||||
if (targetFile == null)//no file found, creating new one
|
if (targetFile == null)//no file found, creating new one
|
||||||
|
{
|
||||||
targetFile = folder.createFile(Constants.NO_FILE_EXTENSION_MIME_TYPE, targetName);
|
targetFile = folder.createFile(Constants.NO_FILE_EXTENSION_MIME_TYPE, targetName);
|
||||||
|
}
|
||||||
return targetFile;
|
return targetFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,72 +565,87 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
private void importWorldmap(Intent data) {
|
private void importWorldmap(Intent data) {
|
||||||
Uri uri = data.getData();
|
Uri uri = data.getData();
|
||||||
|
|
||||||
Context context = getApplicationContext();
|
Context context = AndorsTrailApplication.getApplicationFromActivity(this).getApplicationContext();
|
||||||
ContentResolver resolver = AndorsTrailApplication.getApplicationFromActivity(this).getContentResolver();
|
|
||||||
|
|
||||||
File storageDir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
DocumentFile chosenZip = DocumentFile.fromSingleUri(context, uri);
|
||||||
DocumentFile storageFolder = DocumentFile.fromFile(storageDir);
|
if (chosenZip == null || !chosenZip.isFile()) {
|
||||||
DocumentFile ownWorldmapFolder = storageFolder.findFile(Constants.FILENAME_WORLDMAP_DIRECTORY);
|
|
||||||
if (ownWorldmapFolder == null) {
|
|
||||||
ownWorldmapFolder = storageFolder.createDirectory(Constants.FILENAME_WORLDMAP_DIRECTORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
DocumentFile chosenFolder = DocumentFile.fromTreeUri(context, uri);
|
|
||||||
if (chosenFolder == null || !chosenFolder.isDirectory()) {
|
|
||||||
showErrorImportingWorldmapWrongDirectory();
|
showErrorImportingWorldmapWrongDirectory();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Constants.FILENAME_WORLDMAP_DIRECTORY.equals(chosenFolder.getName())) {
|
String chosenZipName = chosenZip.getName();
|
||||||
//user did not select the worldmap folder directly
|
if (!chosenZipName.startsWith(Constants.FILENAME_WORLDMAP_DIRECTORY)) {
|
||||||
DocumentFile file = chosenFolder.findFile(Constants.FILENAME_WORLDMAP_DIRECTORY);
|
showErrorImportingWorldmapWrongDirectory();
|
||||||
if (file == null || !file.isDirectory() || !Constants.FILENAME_WORLDMAP_DIRECTORY.equals(file.getName())) {
|
return;
|
||||||
//could not find a worldmap folder in the users selection
|
|
||||||
showErrorImportingWorldmapWrongDirectory();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
chosenFolder = file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidStorage.copyDocumentFilesToDirAsync(chosenFolder.listFiles(),
|
File ownWorldmapFolder = getOwnWorldmapFolder(context);
|
||||||
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 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.P)
|
||||||
private void clickExportSaveGames() {
|
private void clickExportSaveGames() {
|
||||||
startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(), -SLOT_NUMBER_EXPORT_SAVEGAMES);
|
showStartExportInfo(view -> startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(),
|
||||||
|
-SLOT_NUMBER_EXPORT_SAVEGAMES));
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
private void clickImportSaveGames() {
|
private void clickImportSaveGames() {
|
||||||
startActivityForResult(AndroidStorage.getNewSelectMultipleSavegameFilesIntent(), -SLOT_NUMBER_IMPORT_SAVEGAMES);
|
showStartImportSavesInfo(view -> startActivityForResult(AndroidStorage.getNewSelectMultipleSavegameFilesIntent(),
|
||||||
|
-SLOT_NUMBER_IMPORT_SAVEGAMES));
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
private void clickImportWorldmap() {
|
private void clickImportWorldmap() {
|
||||||
startActivityForResult(AndroidStorage.getNewOpenDirectoryIntent(), -SLOT_NUMBER_IMPORT_WORLDMAP);
|
showStartImportWorldmapInfo(view -> startActivityForResult(AndroidStorage.getNewSelectZipIntent(),
|
||||||
|
-SLOT_NUMBER_IMPORT_WORLDMAP));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
private void showConfirmOverwriteByExportQuestion(ContentResolver resolver, DocumentFile targetFolder, DocumentFile[] files) {
|
private void showConfirmOverwriteByExportQuestion(ContentResolver resolver,
|
||||||
|
DocumentFile targetFolder,
|
||||||
|
File[] files) {
|
||||||
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
||||||
getString(R.string.loadsave_export_overwrite_confirmation_title),
|
getString(R.string.loadsave_export_overwrite_confirmation_title),
|
||||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||||
getString(R.string.loadsave_export_overwrite_confirmation),
|
getString(R.string.loadsave_export_overwrite_confirmation),
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
CustomDialogFactory.addButton(d, android.R.string.yes, v -> exportSaveGamesFolderContentToFolder(resolver, targetFolder, files));
|
CustomDialogFactory.addButton(d,
|
||||||
|
android.R.string.yes,
|
||||||
|
v -> exportSaveGamesFolderContentToFolder(targetFolder, files));
|
||||||
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
||||||
|
|
||||||
CustomDialogFactory.show(d);
|
CustomDialogFactory.show(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
private void showConfirmOverwriteByImportQuestion(ContentResolver resolver,
|
private void showConfirmOverwriteByImportQuestion(ContentResolver resolver,
|
||||||
DocumentFile appSavegameFolder,
|
DocumentFile appSavegameFolder,
|
||||||
List<DocumentFile> alreadyExistingFiles,
|
List<DocumentFile> alreadyExistingFiles,
|
||||||
@@ -601,9 +659,9 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
|
|
||||||
Context context = AndorsTrailApplication.getApplicationFromActivity(this).getApplicationContext();
|
Context context = AndorsTrailApplication.getApplicationFromActivity(this).getApplicationContext();
|
||||||
|
|
||||||
ArrayList<CustomDialog> dialogs = new ArrayList<CustomDialog>(amount) ;
|
ArrayList<CustomDialog> dialogs = new ArrayList<>(amount);
|
||||||
|
|
||||||
for (int i = 0; i < amount ; i++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
DocumentFile alreadyExistingFile = alreadyExistingFiles.get(i);
|
DocumentFile alreadyExistingFile = alreadyExistingFiles.get(i);
|
||||||
int slot = getSlotFromSavegameFileName(alreadyExistingFile.getName());
|
int slot = getSlotFromSavegameFileName(alreadyExistingFile.getName());
|
||||||
FileHeader existingFileHeader = Savegames.quickload(context, slot);
|
FileHeader existingFileHeader = Savegames.quickload(context, slot);
|
||||||
@@ -620,20 +678,26 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder messageSb = new StringBuilder();
|
StringBuilder messageSb = new StringBuilder();
|
||||||
String existingFileDescription = getString(R.string.loadsave_import_existing_description, slot, existingFileHeader.describe());
|
String existingFileDescription = getString(R.string.loadsave_import_existing_description,
|
||||||
String importedFileDescription = getString(R.string.loadsave_import_imported_description, slot, importedFileHeader.describe());
|
Integer.toString(slot),
|
||||||
messageSb.append(getString(R.string.loadsave_import_file_exists_question, existingFileDescription, importedFileDescription));
|
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();
|
String m = messageSb.toString();
|
||||||
CustomDialog dialog = CustomDialogFactory.createDialog(this,
|
CustomDialog dialog = CustomDialogFactory.createDialog(this,
|
||||||
title,
|
title,
|
||||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||||
m,
|
m,
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_keep_existing, v -> {
|
CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_keep_existing, v -> {
|
||||||
//do nothing
|
//do nothing
|
||||||
@@ -646,7 +710,8 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
});
|
});
|
||||||
|
|
||||||
CustomDialogFactory.addButton(dialog, R.string.loadsave_import_option_add_as_new, v -> {
|
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(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);
|
newFiles.add(alreadyExistingFile);
|
||||||
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
|
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
|
||||||
});
|
});
|
||||||
@@ -662,13 +727,15 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
|
GoToNextConflictOrFinish(resolver, appSavegameFolder, newFiles, dialogs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
private void GoToNextConflictOrFinish(ContentResolver resolver, DocumentFile appSavegameFolder, List<DocumentFile> newFiles, ArrayList<CustomDialog> dialogs) {
|
private void GoToNextConflictOrFinish(ContentResolver resolver,
|
||||||
if(dialogs.stream().count() > 0){
|
DocumentFile appSavegameFolder,
|
||||||
|
List<DocumentFile> newFiles,
|
||||||
|
ArrayList<CustomDialog> dialogs) {
|
||||||
|
if (dialogs.stream().count() > 0) {
|
||||||
CustomDialog d = dialogs.remove(0);
|
CustomDialog d = dialogs.remove(0);
|
||||||
CustomDialogFactory.show(d);
|
CustomDialogFactory.show(d);
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
importSaveGames(resolver, appSavegameFolder, newFiles);
|
importSaveGames(resolver, appSavegameFolder, newFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -677,8 +744,9 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
if (resultCode != Activity.RESULT_OK)
|
if (resultCode != Activity.RESULT_OK) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
switch (-requestCode) {
|
switch (-requestCode) {
|
||||||
@@ -713,48 +781,90 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
|
|||||||
|
|
||||||
//region show Dialogs
|
//region show Dialogs
|
||||||
|
|
||||||
private void showErrorImportingWorldmapWrongDirectory() {
|
//region Import/Export
|
||||||
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
|
|
||||||
getString(R.string.loadsave_import_worldmap_unsuccessfull),
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
getString(R.string.loadsave_import_worldmap_wrong_directory));
|
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);
|
CustomDialogFactory.show(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showErrorImportingSaveGameUnknown() {
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
|
private void showStartImportSavesInfo(OnClickListener onOk) {
|
||||||
getString(R.string.loadsave_import_save_unsuccessfull),
|
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
||||||
getString(R.string.loadsave_import_save_error_unknown));
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
private void showErrorLoadingEmptySlot() {
|
private void showErrorLoadingEmptySlot() {
|
||||||
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
|
final CustomDialog d = CustomDialogFactory.createErrorDialog(this,
|
||||||
getString(R.string.startscreen_error_loading_game),
|
getString(R.string.startscreen_error_loading_game),
|
||||||
getString(R.string.startscreen_error_loading_empty_slot));
|
getString(R.string.startscreen_error_loading_empty_slot));
|
||||||
CustomDialogFactory.show(d);
|
CustomDialogFactory.show(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showSlotGetsDeletedOnLoadWarning(final int slot) {
|
private void showSlotGetsDeletedOnLoadWarning(final int slot) {
|
||||||
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
||||||
getString(R.string.startscreen_attention_slot_gets_delete_on_load),
|
getString(R.string.startscreen_attention_slot_gets_delete_on_load),
|
||||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||||
getString(R.string.startscreen_attention_message_slot_gets_delete_on_load),
|
getString(R.string.startscreen_attention_message_slot_gets_delete_on_load),
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
CustomDialogFactory.addButton(d, android.R.string.ok, v -> completeLoadSaveActivity(slot));
|
CustomDialogFactory.addButton(d, android.R.string.ok, v -> completeLoadSaveActivity(slot));
|
||||||
CustomDialogFactory.show(d);
|
CustomDialogFactory.show(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showConfirmoverwriteQuestion(final int slot, String message) {
|
private void showConfirmOverwriteQuestion(final int slot, String message) {
|
||||||
final String title =
|
final String title = getString(R.string.loadsave_save_overwrite_confirmation_title) + ' '
|
||||||
getString(R.string.loadsave_save_overwrite_confirmation_title) + ' '
|
+ getString(R.string.loadsave_save_overwrite_confirmation_slot, slot);
|
||||||
+ getString(R.string.loadsave_save_overwrite_confirmation_slot, slot);
|
|
||||||
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
final CustomDialog d = CustomDialogFactory.createDialog(this,
|
||||||
title,
|
title,
|
||||||
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
getResources().getDrawable(android.R.drawable.ic_dialog_alert),
|
||||||
message,
|
message,
|
||||||
null,
|
null,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
CustomDialogFactory.addButton(d, android.R.string.yes, v -> completeLoadSaveActivity(slot));
|
CustomDialogFactory.addButton(d, android.R.string.yes, v -> completeLoadSaveActivity(slot));
|
||||||
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
CustomDialogFactory.addDismissButton(d, android.R.string.no);
|
||||||
|
|||||||
@@ -6,14 +6,12 @@ import android.content.Intent;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.RequiresApi;
|
import android.support.annotation.RequiresApi;
|
||||||
import android.support.v4.content.FileProvider;
|
import android.support.v4.content.FileProvider;
|
||||||
import android.support.v4.provider.DocumentFile;
|
import android.support.v4.provider.DocumentFile;
|
||||||
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.webkit.MimeTypeMap;
|
|
||||||
|
|
||||||
import com.gpl.rpg.AndorsTrail.R;
|
import com.gpl.rpg.AndorsTrail.R;
|
||||||
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
import com.gpl.rpg.AndorsTrail.controller.Constants;
|
||||||
@@ -22,19 +20,22 @@ import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.function.Consumer;
|
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 final class AndroidStorage {
|
||||||
public static File getStorageDirectory(Context context, String name) {
|
public static File getStorageDirectory(Context context, String name) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
return context.getExternalFilesDir(name);
|
return context.getExternalFilesDir(name);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
File root = Environment.getExternalStorageDirectory();
|
File root = Environment.getExternalStorageDirectory();
|
||||||
return new File(root, name);
|
return new File(root, name);
|
||||||
}
|
}
|
||||||
@@ -42,16 +43,16 @@ public final class AndroidStorage {
|
|||||||
|
|
||||||
public static boolean shouldMigrateToInternalStorage(Context context) {
|
public static boolean shouldMigrateToInternalStorage(Context context) {
|
||||||
boolean ret = false;
|
boolean ret = false;
|
||||||
File externalSaveGameDirectory = new File(Environment.getExternalStorageDirectory(), Constants.FILENAME_SAVEGAME_DIRECTORY);
|
File externalSaveGameDirectory = new File(Environment.getExternalStorageDirectory(),
|
||||||
|
Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||||
File internalSaveGameDirectory = getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
File internalSaveGameDirectory = getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
|
||||||
|
|
||||||
if (externalSaveGameDirectory.exists()
|
if (externalSaveGameDirectory.exists()
|
||||||
&& externalSaveGameDirectory.isDirectory()
|
&& externalSaveGameDirectory.isDirectory()
|
||||||
&& externalSaveGameDirectory.listFiles().length > 0
|
&& externalSaveGameDirectory.listFiles().length > 0
|
||||||
&& (
|
&& (!internalSaveGameDirectory.exists()
|
||||||
!internalSaveGameDirectory.exists()
|
|| internalSaveGameDirectory.isDirectory()
|
||||||
|| internalSaveGameDirectory.isDirectory() && internalSaveGameDirectory.listFiles().length < 2)
|
&& internalSaveGameDirectory.listFiles().length < 2)) {
|
||||||
) {
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -60,11 +61,11 @@ public final class AndroidStorage {
|
|||||||
public static boolean migrateToInternalStorage(Context context) {
|
public static boolean migrateToInternalStorage(Context context) {
|
||||||
try {
|
try {
|
||||||
copy(new File(Environment.getExternalStorageDirectory(), Constants.CHEAT_DETECTION_FOLDER),
|
copy(new File(Environment.getExternalStorageDirectory(), Constants.CHEAT_DETECTION_FOLDER),
|
||||||
getStorageDirectory(context, Constants.CHEAT_DETECTION_FOLDER));
|
getStorageDirectory(context, Constants.CHEAT_DETECTION_FOLDER));
|
||||||
copy(new File(Environment.getExternalStorageDirectory(), Constants.FILENAME_SAVEGAME_DIRECTORY),
|
copy(new File(Environment.getExternalStorageDirectory(), Constants.FILENAME_SAVEGAME_DIRECTORY),
|
||||||
getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY));
|
getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
L.log("Error migrating data: " + e.toString());
|
L.log("Error migrating data: " + e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -105,54 +106,174 @@ 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<Boolean> callback) {
|
||||||
|
|
||||||
public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile, ContentResolver resolver, DocumentFile targetFolder) throws IOException {
|
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||||
copyDocumentFileToNewOrExistingFile(sourceFile, resolver, targetFolder, Constants.NO_FILE_EXTENSION_MIME_TYPE);
|
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();
|
||||||
|
|
||||||
|
//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<Boolean> callback) {
|
||||||
|
|
||||||
|
BackgroundWorker<Boolean> 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 {
|
public static void copyDocumentFileToNewOrExistingFile(DocumentFile sourceFile,
|
||||||
|
ContentResolver resolver,
|
||||||
|
DocumentFile targetFolder,
|
||||||
|
String mimeType) throws IOException {
|
||||||
String fileName = sourceFile.getName();
|
String fileName = sourceFile.getName();
|
||||||
DocumentFile file = targetFolder.findFile(fileName);
|
DocumentFile file = targetFolder.findFile(fileName);
|
||||||
if (file == null)
|
if (file == null) {
|
||||||
file = targetFolder.createFile(mimeType, fileName);
|
file = targetFolder.createFile(mimeType, fileName);
|
||||||
if (file == null)
|
}
|
||||||
|
if (file == null) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AndroidStorage.copyDocumentFile(sourceFile, resolver, file);
|
AndroidStorage.copyDocumentFile(sourceFile, resolver, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void copyDocumentFile(DocumentFile sourceFile, ContentResolver resolver, DocumentFile targetFile) throws IOException {
|
public static void copyDocumentFile(DocumentFile sourceFile,
|
||||||
|
ContentResolver resolver,
|
||||||
|
DocumentFile targetFile) throws IOException {
|
||||||
try (OutputStream outputStream = resolver.openOutputStream(targetFile.getUri());
|
try (OutputStream outputStream = resolver.openOutputStream(targetFile.getUri());
|
||||||
InputStream inputStream = resolver.openInputStream(sourceFile.getUri())) {
|
InputStream inputStream = resolver.openInputStream(sourceFile.getUri())) {
|
||||||
copyStream(inputStream, outputStream);
|
copyStream(inputStream, outputStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MIME-Type for a file.<p/>
|
|
||||||
* Fallback value is '* / *' (without spaces) <p/>
|
|
||||||
* Mostly copied together from: <a href="https://stackoverflow.com/q/8589645/17292289">StackOverflow</a>
|
|
||||||
*/
|
|
||||||
@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) {
|
public static String getUrlForFile(Context context, File worldmap) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
String applicationId = context.getPackageName();
|
String applicationId = context.getPackageName();
|
||||||
@@ -163,11 +284,9 @@ public final class AndroidStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
public static Intent getNewOpenDirectoryIntent() {
|
public static Intent getNewOpenDirectoryIntent() {
|
||||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
return new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||||
return intent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
@@ -179,50 +298,59 @@ public final class AndroidStorage {
|
|||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void copyDocumentFilesFromToAsync(DocumentFile[] sources, Context context, DocumentFile[] targets, Consumer<Boolean> callback) {
|
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||||
if(sources.length != targets.length)
|
public static Intent getNewSelectZipIntent() {
|
||||||
{
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
intent.setType("application/zip");
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||||
|
public static void copyDocumentFilesFromToAsync(DocumentFile[] sources,
|
||||||
|
Context context,
|
||||||
|
DocumentFile[] targets,
|
||||||
|
String loadingMessage,
|
||||||
|
Consumer<Boolean> callback) {
|
||||||
|
if (sources.length != targets.length) {
|
||||||
throw new IllegalArgumentException("Both arrays, target & source have to have the same size");
|
throw new IllegalArgumentException("Both arrays, target & source have to have the same size");
|
||||||
}
|
}
|
||||||
|
|
||||||
BackgroundWorker worker = new BackgroundWorker();
|
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||||
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context);
|
|
||||||
|
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
|
||||||
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
||||||
|
|
||||||
ContentResolver resolver = context.getContentResolver();
|
ContentResolver resolver = context.getContentResolver();
|
||||||
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
||||||
|
|
||||||
worker.setTask(new BackgroundWorker.worker() {
|
worker.setTask(workerCallback -> {
|
||||||
@Override
|
try {
|
||||||
public void doWork(BackgroundWorkerCallback callback) {
|
workerCallback.onInitialize();
|
||||||
try {
|
for (int i = 0; i < sources.length; i++) {
|
||||||
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];
|
|
||||||
|
|
||||||
if(source == null || target == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
copyDocumentFile(source, resolver,target);
|
|
||||||
float progress = i /(float) sources.length;
|
|
||||||
callback.onProgress(progress);
|
|
||||||
}
|
|
||||||
callback.onComplete(true);
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
if (worker.isCancelled()) {
|
if (worker.isCancelled()) {
|
||||||
callback.onFailure(new CancellationException("Cancelled"));
|
workerCallback.onFailure(new CancellationException("Cancelled"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
DocumentFile source = sources[i];
|
||||||
callback.onFailure(e);
|
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.setCallback(getDefaultBackgroundWorkerCallback(handler, progressDialog, callback));
|
||||||
@@ -233,9 +361,10 @@ public final class AndroidStorage {
|
|||||||
public static void copyDocumentFilesToDirAsync(DocumentFile[] files,
|
public static void copyDocumentFilesToDirAsync(DocumentFile[] files,
|
||||||
Context context,
|
Context context,
|
||||||
DocumentFile targetDirectory,
|
DocumentFile targetDirectory,
|
||||||
|
String loadingMessage,
|
||||||
Consumer<Boolean> callback) {
|
Consumer<Boolean> callback) {
|
||||||
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
BackgroundWorker<Boolean> worker = new BackgroundWorker<>();
|
||||||
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context);
|
CustomDialogFactory.CustomDialog progressDialog = getLoadingDialog(context, loadingMessage);
|
||||||
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
progressDialog.setOnCancelListener(dialog -> worker.cancel());
|
||||||
ContentResolver resolver = context.getContentResolver();
|
ContentResolver resolver = context.getContentResolver();
|
||||||
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
Handler handler = Handler.createAsync(Looper.getMainLooper());
|
||||||
@@ -249,11 +378,12 @@ public final class AndroidStorage {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DocumentFile file = files[i];
|
DocumentFile file = files[i];
|
||||||
if(file == null)
|
if (file == null) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
copyDocumentFileToNewOrExistingFile(file, resolver, targetDirectory);
|
copyDocumentFileToNewOrExistingFile(file, resolver, targetDirectory);
|
||||||
float progress = i /(float) files.length;
|
float progress = i / (float) files.length;
|
||||||
workerCallback.onProgress(progress);
|
workerCallback.onProgress(progress);
|
||||||
}
|
}
|
||||||
workerCallback.onComplete(true);
|
workerCallback.onComplete(true);
|
||||||
@@ -270,10 +400,11 @@ public final class AndroidStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static BackgroundWorkerCallback<Boolean> getDefaultBackgroundWorkerCallback(Handler handler,
|
private static BackgroundWorkerCallback<Boolean> getDefaultBackgroundWorkerCallback(Handler handler,
|
||||||
CustomDialogFactory.CustomDialog progressDialog,
|
CustomDialogFactory.CustomDialog progressDialog,
|
||||||
Consumer<Boolean> callback) {
|
Consumer<Boolean> callback) {
|
||||||
return new BackgroundWorkerCallback<Boolean>() {
|
return new BackgroundWorkerCallback<Boolean>() {
|
||||||
private int progress = -1;
|
private int progress = -1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
handler.post(() -> {
|
handler.post(() -> {
|
||||||
@@ -285,10 +416,17 @@ public final class AndroidStorage {
|
|||||||
public void onProgress(float progress) {
|
public void onProgress(float progress) {
|
||||||
handler.post(() -> {
|
handler.post(() -> {
|
||||||
int intProgress = (int) (progress * 100);
|
int intProgress = (int) (progress * 100);
|
||||||
if(this.progress == intProgress)
|
if (this.progress == intProgress) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.progress = intProgress;
|
this.progress = intProgress;
|
||||||
|
|
||||||
|
if (progress == -1) {
|
||||||
|
CustomDialogFactory.setDesc(progressDialog, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CustomDialogFactory.setDesc(progressDialog, intProgress + "%");
|
CustomDialogFactory.setDesc(progressDialog, intProgress + "%");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -296,10 +434,7 @@ public final class AndroidStorage {
|
|||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Exception e) {
|
public void onFailure(Exception e) {
|
||||||
handler.post(() -> {
|
this.onComplete(false);
|
||||||
progressDialog.dismiss();
|
|
||||||
callback.accept(false);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||||
@@ -307,20 +442,31 @@ public final class AndroidStorage {
|
|||||||
public void onComplete(Boolean result) {
|
public void onComplete(Boolean result) {
|
||||||
handler.post(() -> {
|
handler.post(() -> {
|
||||||
progressDialog.dismiss();
|
progressDialog.dismiss();
|
||||||
callback.accept(true);
|
callback.accept(result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context) {
|
private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context) {
|
||||||
return CustomDialogFactory.createDialog(context,
|
return getLoadingDialog(context, null);
|
||||||
context.getResources().getString(R.string.dialog_loading_message),
|
}
|
||||||
context.getResources().getDrawable(R.drawable.loading_anim),
|
|
||||||
null,
|
private static CustomDialogFactory.CustomDialog getLoadingDialog(Context context, String message) {
|
||||||
null,
|
if (message == null) {
|
||||||
false,
|
message = context.getResources().getString(R.string.dialog_loading_message);
|
||||||
false);
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ import java.util.concurrent.Executors;
|
|||||||
|
|
||||||
public final class BackgroundWorker<T> {
|
public final class BackgroundWorker<T> {
|
||||||
boolean cancelled = false;
|
boolean cancelled = false;
|
||||||
worker task;
|
worker<T> task;
|
||||||
BackgroundWorkerCallback callback;
|
BackgroundWorkerCallback<T> callback;
|
||||||
|
|
||||||
public void setTask(worker task) {
|
public void setTask(worker<T> task) {
|
||||||
this.task = task;
|
this.task = task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCallback(BackgroundWorkerCallback callback) {
|
public void setCallback(BackgroundWorkerCallback<T> callback) {
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ public final class BackgroundWorker<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface worker<T> {
|
interface worker<T> {
|
||||||
void doWork(BackgroundWorkerCallback callback);
|
void doWork(BackgroundWorkerCallback<T> callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BackgroundWorkerCallback<T> {
|
interface BackgroundWorkerCallback<T> {
|
||||||
|
|||||||
@@ -485,31 +485,40 @@
|
|||||||
<string name="skill_number_of_increases_several">You may select %1$d skills to improve.</string>
|
<string name="skill_number_of_increases_several">You may select %1$d skills to improve.</string>
|
||||||
<string name="levelup_adds_new_skillpoint">This level also gives you a new skill point to spend!</string>
|
<string name="levelup_adds_new_skillpoint">This level also gives you a new skill point to spend!</string>
|
||||||
|
|
||||||
<string name="loadsave_save_to_new_slot">Create new savegame slot</string>
|
<string name="loadsave_save_to_new_slot">Create new Savegame slot</string>
|
||||||
<string name="loadsave_save_overwrite_confirmation_title">Overwrite savegame?</string>
|
<string name="loadsave_save_overwrite_confirmation_title">Overwrite Savegame?</string>
|
||||||
<string name="loadsave_save_overwrite_confirmation">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?</string>
|
<string name="loadsave_save_overwrite_confirmation">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?</string>
|
||||||
|
|
||||||
<string name="loadsave_export">Export savegames</string>
|
<string name="loadsave_export">Export Savegames</string>
|
||||||
|
<string name="loadsave_export_info">Please select the directory to export all files to.</string>
|
||||||
|
<string name="loadsave_exporting_savegames">Exporting Savegames</string>
|
||||||
|
<string name="loadsave_exporting_worldmap">Exporting Worldmap</string>
|
||||||
<string name="loadsave_export_successfull">Export successful</string>
|
<string name="loadsave_export_successfull">Export successful</string>
|
||||||
<string name="loadsave_export_unsuccessfull">Export unsuccessful</string>
|
<string name="loadsave_export_unsuccessfull">Export unsuccessful</string>
|
||||||
<string name="loadsave_export_overwrite_confirmation_title">Overwrite Existing Files?</string>
|
<string name="loadsave_export_overwrite_confirmation_title">Overwrite Existing Files?</string>
|
||||||
<string name="loadsave_export_overwrite_confirmation">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?</string>
|
<string name="loadsave_export_overwrite_confirmation">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?</string>
|
||||||
<string name="loadsave_import_save">Import savegames</string>
|
<string name="loadsave_export_error_unknown">An unknown error occurred while exporting.</string>
|
||||||
|
|
||||||
|
<string name="loadsave_import_save">Import Savegames</string>
|
||||||
|
<string name="loadsave_import_save_info">Please select all Savegames you want to import.</string>
|
||||||
|
<string name="loadsave_importing_savegames">Importing Savegames</string>
|
||||||
<string name="loadsave_import_save_successfull">Import successful</string>
|
<string name="loadsave_import_save_successfull">Import successful</string>
|
||||||
<string name="loadsave_import_save_unsuccessfull">Import unsuccessful</string>
|
<string name="loadsave_import_save_unsuccessfull">Import unsuccessful</string>
|
||||||
<string name="loadsave_import_save_error_unknown">An unknown error occurred while importing.</string>
|
<string name="loadsave_import_error_unknown">An unknown error occurred while importing.</string>
|
||||||
<string name="loadsave_import_overwrite_confirmation_title">Overwrite Existing Slot?</string>
|
<string name="loadsave_import_overwrite_confirmation_title">Overwrite Existing Slot?</string>
|
||||||
|
|
||||||
<string name="loadsave_import_file_exists_question">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</string>
|
<string name="loadsave_import_file_exists_question">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</string>
|
||||||
<string name="loadsave_import_option_keep_existing">Keep existing save</string>
|
<string name="loadsave_import_option_keep_existing">Keep existing save</string>
|
||||||
<string name="loadsave_import_option_keep_imported">Keep imported save</string>
|
<string name="loadsave_import_option_keep_imported">Keep imported save</string>
|
||||||
<string name="loadsave_import_option_add_as_new">Add as new Save</string>
|
<string name="loadsave_import_option_add_as_new">Add as new Save</string>
|
||||||
<string name="loadsave_import_existing_description">Existing save: Slot: %1$s:\n\t%2$s</string>
|
<string name="loadsave_import_existing_description">Existing save: Slot: %1$s:\n\t%2$s</string>
|
||||||
<string name="loadsave_import_imported_description">Imported save: Slot: %1$s:\n\t%2$s</string>
|
<string name="loadsave_import_imported_description">Imported save: Slot: %1$s:\n\t%2$s</string>
|
||||||
<string name="loadsave_import_worldmap">Import worldmap</string>
|
<string name="loadsave_import_worldmap">Import worldmap</string>
|
||||||
|
<string name="loadsave_import_worldmap_info">Please select the Worldmap zip file.</string>
|
||||||
|
<string name="loadsave_importing_worldmap">Importing worldmap</string>
|
||||||
<string name="loadsave_import_worldmap_successfull">Import of Worldmap successful</string>
|
<string name="loadsave_import_worldmap_successfull">Import of Worldmap successful</string>
|
||||||
<string name="loadsave_import_worldmap_unsuccessfull">Import of Worldmap unsuccessful</string>
|
<string name="loadsave_import_worldmap_unsuccessfull">Import of Worldmap unsuccessful</string>
|
||||||
<string name="loadsave_import_worldmap_wrong_directory">Are you sure there is a worldmap in this folder? Please select the folder called \'worldmap\' inside your export location.</string>
|
<string name="loadsave_import_worldmap_wrong_file">Are you sure you selected a worldmap? Please select the zip file called \'worldmap.zip\' that was exported into your export location.</string>
|
||||||
|
|
||||||
<string name="iteminfo_displaytypes_ordinary">Ordinary</string>
|
<string name="iteminfo_displaytypes_ordinary">Ordinary</string>
|
||||||
<string name="iteminfo_displaytypes_quest">Quest item</string>
|
<string name="iteminfo_displaytypes_quest">Quest item</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user