Skip to content

Commit

Permalink
Fix: improved working directory setting (#32)
Browse files Browse the repository at this point in the history
* checking working directory accessibility at startup

* backup: save to dowloads/share

* restore backup file (WIP)

* fixed restore

* restart main activity on restore job complete

* moved backup/restore to settings view

* data restore confirm

* renamed output file

* removed internal backup mode

* changed confirm messages

* code cleanup

---------

Co-authored-by: Stefano Ricci <[email protected]>
  • Loading branch information
SteRiccio and SteRiccio authored Apr 2, 2024
1 parent 1fda7b1 commit 2be977b
Show file tree
Hide file tree
Showing 39 changed files with 807 additions and 129 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.openforis.collect.android.gui;

import android.app.Activity;
import android.os.Bundle;
import android.view.MenuItem;

Expand Down Expand Up @@ -70,4 +71,10 @@ public void run() {
}
});
}

public static void restartMainActivity(Activity context) {
ServiceLocator.reset(context);
Activities.startNewClearTask(context, MainActivity.class);
context.finish();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ protected void initialize() {
private void initializeServices() {
try {
ServiceLocator.init(this);
} catch (WorkingDirNotWritable ignore) {
DialogFragment newFragment = new SecondaryStorageNotFoundFragment();
} catch (WorkingDirNotAccessible ignore) {
DialogFragment newFragment = new WorkingDirectoryNotAccessibleFragment();
newFragment.show(getSupportFragmentManager(), "secondaryStorageNotFound");
} catch (StorageAccessException e) {
handleStorageAccessException(e);
} catch (Exception e) {
handleStorageAccessException(new StorageAccessException());
}
}

Expand Down Expand Up @@ -98,6 +98,8 @@ protected void onCreate(@Nullable Bundle savedState) {

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);

if (!Permissions.isPermissionGranted(grantResults)) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public class ServiceLocator {
* Initializes the ServiceLocator.
* Returns true if there is a selected survey, false otherwise
*/
public static boolean init(Context applicationContext) throws WorkingDirNotWritable {
public static boolean init(Context applicationContext) throws WorkingDirNotAccessible {
if (surveyService == null) {
SettingsActivity.init(applicationContext);
UILanguageInitializer.init(applicationContext);
Expand Down Expand Up @@ -161,7 +161,8 @@ private static void deleteDatabase(String databaseName, String surveyName, Andro
}

public static boolean isSurveyImported(String surveyName, Context context) {
return context.getDatabasePath(databasePath(MODEL_DB, surveyName, context).getAbsolutePath()).exists();
File dbFile = context.getDatabasePath(databasePath(MODEL_DB, surveyName, context).getAbsolutePath());
return dbFile.exists();
}

private static AndroidDatabase createModelDatabase(String surveyName, Context applicationContext) {
Expand Down Expand Up @@ -264,9 +265,7 @@ private static CollectModelManager createCollectModelManager(AndroidDatabase mod
RecordFileManager recordFileManager = new RecordFileManager() {{
storageDirectory = AppDirs.surveyImagesDir(surveyName, context);
if (!storageDirectory.exists()) {
if (!storageDirectory.mkdirs())
throw new WorkingDirNotWritable(storageDirectory);
AndroidFiles.makeDiscoverable(storageDirectory, context);
AndroidFiles.createAndMakeDiscoverableDir(storageDirectory, context);
}
}};
recordFileManager.setDefaultRootStoragePath(AppDirs.surveyDatabasesDir(surveyName, context).getAbsolutePath());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private void migrateIfNeeded(Version surveyAppVersion, File targetSurveyDatabase

public static void importDefaultSurvey(Context context) {
try {
File tempDir = createTempDir();
File tempDir = org.openforis.collect.android.util.FileUtils.createTempDir();
InputStream sourceInput = SurveyImporter.class.getResourceAsStream("/demo.collect-mobile");
File intermediateSurveyPath = new File(tempDir, "demo.collect-mobile");
FileOutputStream intermediateOutput = new FileOutputStream(intermediateSurveyPath);
Expand Down Expand Up @@ -138,13 +138,13 @@ private SurveyBackupInfo info(File dir) {
} catch (IOException e) {
throw new MalformedSurvey(sourceSurveyPath, e);
} finally {
close(is);
IOUtils.closeQuietly(is);
}
return info;
}

private File unzipSurveyDefinition() throws IOException {
File folder = createTempDir();
File folder = org.openforis.collect.android.util.FileUtils.createTempDir();
File zipFile = new File(sourceSurveyPath);
if (!zipFile.exists())
throw new FileNotFoundException("File not found: " + sourceSurveyPath);
Expand All @@ -157,23 +157,6 @@ private File unzipSurveyDefinition() throws IOException {
return folder;
}

private static File createTempDir() throws IOException {
File tempDir = File.createTempFile("collect", Long.toString((System.nanoTime())));
if (!tempDir.delete())
throw new IOException("Failed to create temp dir:" + tempDir.getAbsolutePath());
if (!tempDir.mkdir())
throw new IOException("Failed to create temp dir:" + tempDir.getAbsolutePath());
return tempDir;
}

private void close(InputStream is) {
if (is != null)
try {
is.close();
} catch (IOException ignore) {
}
}

public static String surveyMinorVersion(Version version) {
return version.getMajor() + "." + version.getMinor() + ".x";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,6 @@ private static class ImportSurveyTask extends SlowAsyncTask<Void, Void, Boolean>
protected Boolean runTask() throws Exception {
super.runTask();
File file = AndroidFiles.copyUriContentToCache(context, uri);
if (file == null) {
throw new IllegalStateException(String.format(
"Failed to import survey; could not determine file path for URI: %s", uri));
}
if (file.length() == 0) {
throw new IllegalStateException(context.getString(R.string.survey_import_failed_empty_file_message));
}
if (ServiceLocator.importSurvey(file.getAbsolutePath(), overwrite, context) || overwrite) {
onSurveyImportComplete();
return false; //survey imported successfully
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.openforis.collect.android.NodeEvent;
import org.openforis.collect.android.SurveyListener;
import org.openforis.collect.android.SurveyService;
import org.openforis.collect.android.gui.backup.Backup;
import org.openforis.collect.android.gui.barcode.BarcodeCaptureActivity;
import org.openforis.collect.android.gui.detail.ExportDialogFragment;
import org.openforis.collect.android.gui.entitytable.EntityTableDialogFragment;
Expand Down Expand Up @@ -81,7 +80,6 @@ public class SurveyNodeActivity extends BaseActivity implements SurveyListener,
private VideoFileAttributeComponent videoListener;
private DocumentFileAttributeComponent fileDocumentListener;
private BarcodeTextAttributeComponent barcodeCaptureListener;

private boolean twoPane;

public static void startClearSurveyNodeActivity(Context context) {
Expand Down Expand Up @@ -270,10 +268,6 @@ public void navigateDown(View view) {
navigateDown();
}

public void backup(MenuItem item) {
Backup.showBackupModeChooseDialog(this);
}

public void exportDialog(MenuItem item) {
if (Permissions.checkStoragePermissionOrRequestIt(this)) {

Expand Down Expand Up @@ -432,6 +426,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (fileDocumentListener != null && data != null) {
fileDocumentListener.documentSelected(data.getData());
}
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.openforis.collect.android.gui;

import java.io.File;

public class WorkingDirNotAccessible extends RuntimeException {
public WorkingDirNotAccessible(File workingDir) {
super("workingDir:" + workingDir);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
import org.openforis.collect.android.gui.util.Activities;
import org.openforis.collect.android.gui.util.AppDirs;

public class SecondaryStorageNotFoundFragment extends DialogFragment {
public class WorkingDirectoryNotAccessibleFragment extends DialogFragment {

public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.storage_not_found_message)
builder.setTitle(R.string.working_directory_not_accessible_message)
.setMessage(AppDirs.root(getActivity()).getAbsolutePath())
.setPositiveButton(R.string.storage_not_found_retry, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,31 @@
import android.widget.ListView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;

import org.apache.commons.io.FileUtils;
import org.openforis.collect.R;
import org.openforis.collect.android.collectadapter.BackupGenerator;
import org.openforis.collect.android.gui.util.Activities;
import org.openforis.collect.android.gui.util.AndroidFiles;
import org.openforis.collect.android.gui.util.App;
import org.openforis.collect.android.gui.util.AppDirs;
import org.openforis.collect.android.gui.util.Dates;
import org.openforis.collect.android.gui.util.Dialogs;
import org.openforis.collect.android.gui.util.MimeType;
import org.openforis.collect.android.sqlite.AndroidDatabase;

import java.io.File;
import java.io.IOException;

public class Backup {

public static void showBackupModeChooseDialog(FragmentActivity activity) {
private static String BACKUP_FILE_PREFIX = "of_collect_mobile_backup_";
public static String BACKUP_FILE_EXTENSION = "ofcmbck";

public static void showBackupModeChooseDialog(AppCompatActivity activity) {
DialogFragment dialogFragment = new BackupModeDialogFragment();
dialogFragment.show(activity.getSupportFragmentManager(), "backupModeSelection");
}
Expand Down Expand Up @@ -105,6 +114,55 @@ public void run() {
}
}

private void backupIntoDownloads() {
try {
File downloadDir = AndroidFiles.getDownloadsDir(context);
File backupFile = generateBackupFile(downloadDir);
if (backupFile == null) return;
AndroidFiles.makeDiscoverable(backupFile, context);
Dialogs.alert(context, R.string.backup_file_generation_complete, R.string.backup_file_generation_into_downloads_complete_message);
} catch (Exception e) {
showBackupErrorMessage(e);
}
}

private void backupAndShare() {
File backupFile = generateBackupFile(null);
if (backupFile == null) return;
Activities.shareFile(context, backupFile, MimeType.BINARY, R.string.share_file, false);
}

private File generateBackupFile(File parentDir) {
File destFile = null, tempFile = null;
try {
File destParentDir;
String destFileName = BACKUP_FILE_PREFIX + Dates.formatNowISO() + "." + BACKUP_FILE_EXTENSION;
if (parentDir == null) {
tempFile = File.createTempFile(BACKUP_FILE_PREFIX, "." + BACKUP_FILE_EXTENSION);
destParentDir = tempFile.getParentFile();
destFile = new File(destParentDir, destFileName);
FileUtils.moveFile(tempFile, destFile);
} else {
destParentDir = parentDir;
destFile = new File(destParentDir, destFileName);
}
if (AndroidFiles.enoughSpaceToCopy(surveysDir, destParentDir)) {
BackupGenerator backupGenerator = new BackupGenerator(surveysDir, App.versionName(context), destFile);
backupGenerator.generate();
} else {
destFile.delete();
}
} catch (IOException e) {
showBackupErrorMessage(e);
if (tempFile != null) {
tempFile.delete();
}
if (destFile != null) {
destFile.delete();
}
}
return destFile;
}

private void showInsertSdCardDialog() {
Intent intent = new Intent();
Expand Down Expand Up @@ -176,7 +234,10 @@ public void onClick(View v) {
backupExecutor.backupToNewSdCard();
break;
case 1:
backupExecutor.backupInternally();
backupExecutor.backupIntoDownloads();
break;
case 2:
backupExecutor.backupAndShare();
break;
}
alertDialog.dismiss();
Expand Down
Loading

0 comments on commit 2be977b

Please sign in to comment.