diff --git a/app/src/main/java/com/stevesoltys/backup/activity/MainActivity.java b/app/src/main/java/com/stevesoltys/backup/activity/MainActivity.java index 7ecffa09..43dfba94 100644 --- a/app/src/main/java/com/stevesoltys/backup/activity/MainActivity.java +++ b/app/src/main/java/com/stevesoltys/backup/activity/MainActivity.java @@ -10,7 +10,7 @@ import com.stevesoltys.backup.R; public class MainActivity extends Activity implements View.OnClickListener { - public static final int CREATE_DOCUMENT_REQUEST_CODE = 1; + public static final int OPEN_DOCUMENT_TREE_REQUEST_CODE = 1; public static final int LOAD_DOCUMENT_REQUEST_CODE = 2; @@ -34,7 +34,7 @@ public class MainActivity extends Activity implements View.OnClickListener { switch (viewId) { case R.id.create_backup_button: - controller.showCreateDocumentActivity(this); + controller.showChooseFolderActivity(this); break; case R.id.restore_backup_button: @@ -53,8 +53,8 @@ public class MainActivity extends Activity implements View.OnClickListener { switch (requestCode) { - case CREATE_DOCUMENT_REQUEST_CODE: - controller.handleCreateDocumentResult(result, this); + case OPEN_DOCUMENT_TREE_REQUEST_CODE: + controller.handleChooseFolderResult(result, this); break; case LOAD_DOCUMENT_REQUEST_CODE: diff --git a/app/src/main/java/com/stevesoltys/backup/activity/MainActivityController.java b/app/src/main/java/com/stevesoltys/backup/activity/MainActivityController.java index 5d4806fb..c4155c77 100644 --- a/app/src/main/java/com/stevesoltys/backup/activity/MainActivityController.java +++ b/app/src/main/java/com/stevesoltys/backup/activity/MainActivityController.java @@ -2,31 +2,47 @@ package com.stevesoltys.backup.activity; import android.app.Activity; import android.content.ActivityNotFoundException; +import android.content.ContentResolver; import android.content.Intent; +import android.net.Uri; import android.widget.Toast; import com.stevesoltys.backup.activity.backup.CreateBackupActivity; import com.stevesoltys.backup.activity.restore.RestoreBackupActivity; -import static android.content.Intent.ACTION_CREATE_DOCUMENT; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + import static android.content.Intent.ACTION_OPEN_DOCUMENT; +import static android.content.Intent.ACTION_OPEN_DOCUMENT_TREE; import static android.content.Intent.CATEGORY_OPENABLE; +import static android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION; +import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; +import static android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION; +import static android.provider.DocumentsContract.buildDocumentUriUsingTree; +import static android.provider.DocumentsContract.createDocument; +import static android.provider.DocumentsContract.getTreeDocumentId; +import static com.stevesoltys.backup.activity.MainActivity.OPEN_DOCUMENT_TREE_REQUEST_CODE; /** * @author Steve Soltys + * @author Torsten Grote */ class MainActivityController { private static final String DOCUMENT_MIME_TYPE = "application/octet-stream"; + private static final String DOCUMENT_SUFFIX = "yyyy-MM-dd_HH_mm_ss"; - void showCreateDocumentActivity(Activity parent) { - Intent createDocumentIntent = new Intent(ACTION_CREATE_DOCUMENT); - createDocumentIntent.addCategory(CATEGORY_OPENABLE); - createDocumentIntent.setType(DOCUMENT_MIME_TYPE); + void showChooseFolderActivity(Activity parent) { + Intent createDocumentIntent = new Intent(ACTION_OPEN_DOCUMENT_TREE); + createDocumentIntent.addFlags(FLAG_GRANT_PERSISTABLE_URI_PERMISSION | + FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION); try { Intent documentChooser = Intent.createChooser(createDocumentIntent, "Select the backup location"); - parent.startActivityForResult(documentChooser, MainActivity.CREATE_DOCUMENT_REQUEST_CODE); + parent.startActivityForResult(documentChooser, OPEN_DOCUMENT_TREE_REQUEST_CODE); } catch (ActivityNotFoundException ex) { Toast.makeText(parent, "Please install a file manager.", Toast.LENGTH_SHORT).show(); @@ -47,14 +63,33 @@ class MainActivityController { } } - void handleCreateDocumentResult(Intent result, Activity parent) { + void handleChooseFolderResult(Intent result, Activity parent) { - if (result == null) { + if (result == null || result.getData() == null) { + return; + } + + Uri folderUri = result.getData(); + ContentResolver contentResolver = parent.getContentResolver(); + + // persist permission to access backup folder across reboots + int takeFlags = result.getFlags() & + (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION); + contentResolver.takePersistableUriPermission(folderUri, takeFlags); + + // create backup file in folder + Uri fileUri; + try { + fileUri = createBackupFile(contentResolver, folderUri); + } catch (IOException e) { + // TODO show better error message once more infrastructure is in place + Toast.makeText(parent, "Error creating backup file", Toast.LENGTH_SHORT).show(); + e.printStackTrace(); return; } Intent intent = new Intent(parent, CreateBackupActivity.class); - intent.setData(result.getData()); + intent.setData(fileUri); parent.startActivity(intent); } @@ -68,4 +103,18 @@ class MainActivityController { intent.setData(result.getData()); parent.startActivity(intent); } + + private Uri createBackupFile(ContentResolver contentResolver, Uri folderUri) throws IOException { + Uri documentUri = buildDocumentUriUsingTree(folderUri, getTreeDocumentId(folderUri)); + Uri fileUri = createDocument(contentResolver, documentUri, DOCUMENT_MIME_TYPE, getBackupFileName()); + if (fileUri == null) throw new IOException(); + return fileUri; + } + + private String getBackupFileName() { + SimpleDateFormat dateFormat = new SimpleDateFormat(DOCUMENT_SUFFIX, Locale.US); + String date = dateFormat.format(new Date()); + return "backup-" + date; + } + }