From 7ae7e7a6b1e49e748cd04024a3714efcd7bf35b2 Mon Sep 17 00:00:00 2001 From: FFDA <8406967+FFDA@users.noreply.github.com> Date: Sun, 12 Feb 2023 15:06:13 +0200 Subject: [PATCH] Fixed auto backup; (#924) * Fixed auto backup; * Removed Backup Test setting; --- .../core/alarm/AlarmBackupHandler.java | 29 +++++--- .../gui/preferences/BackupPreferences.java | 70 ++++++++++++++----- .../app/src/main/res/values/strings.xml | 4 +- .../src/main/res/xml/backup_preferences.xml | 2 +- 4 files changed, 76 insertions(+), 29 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmBackupHandler.java b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmBackupHandler.java index fdf99916..fbe8c2c3 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmBackupHandler.java +++ b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmBackupHandler.java @@ -21,12 +21,12 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; -import android.os.Environment; import android.preference.PreferenceManager; +import androidx.documentfile.provider.DocumentFile; + import com.health.openscale.core.OpenScale; -import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; @@ -91,9 +91,19 @@ public class AlarmBackupHandler SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - File exportDir = new File(context.getExternalFilesDir(null).getPath(), - prefs.getString("exportDir", "openScale Backup")); - if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + // Extra check that there is a exportDir saved in settings + String exportDirString = prefs.getString("exportDir", null); + if (exportDirString == null) { + return; + } + + DocumentFile exportDir = DocumentFile.fromTreeUri(context, Uri.parse(exportDirString)); + // Check if it is possible to read and write to auto export dir + // If it is not possible auto backup function will be disabled + if (!exportDir.canRead() || !exportDir.canWrite()) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean("autoBackup", false); + editor.apply(); return; } @@ -102,14 +112,13 @@ public class AlarmBackupHandler databaseName = dateFormat.format(new Date()) + "_" + databaseName; } - File exportFile = new File(exportDir, databaseName); - - if (!exportDir.exists()) { - exportDir.mkdirs(); + DocumentFile exportFile = exportDir.findFile(databaseName); + if (exportFile == null) { + exportFile = exportDir.createFile("application/x-sqlite3", databaseName); } try { - openScale.exportDatabase(Uri.fromFile(exportFile)); + openScale.exportDatabase(exportFile.getUri()); Timber.d("openScale Auto Backup to %s", exportFile); } catch (IOException e) { Timber.e(e, "Error while exporting database"); diff --git a/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java b/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java index e973c7e0..1664f8d7 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/preferences/BackupPreferences.java @@ -25,12 +25,14 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.preference.PreferenceManager; import android.view.Menu; import android.view.MenuInflater; import android.widget.Toast; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.preference.CheckBoxPreference; @@ -50,17 +52,21 @@ public class BackupPreferences extends PreferenceFragmentCompat implements Share private static final String PREFERENCE_KEY_IMPORT_BACKUP = "importBackup"; private static final String PREFERENCE_KEY_EXPORT_BACKUP = "exportBackup"; private static final String PREFERENCE_KEY_AUTO_BACKUP = "autoBackup"; + private static final String PREFERENCE_KEY_AUTO_BACKUP_DIR = "exportDir"; private static final int IMPORT_DATA_REQUEST = 100; private static final int EXPORT_DATA_REQUEST = 101; private Preference importBackup; private Preference exportBackup; + private Preference autoBackupDir; private CheckBoxPreference autoBackup; private boolean isAutoBackupAskForPermission; + private SharedPreferences prefs; + private Fragment fragment; @Override @@ -71,6 +77,8 @@ public class BackupPreferences extends PreferenceFragmentCompat implements Share fragment = this; + prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + importBackup = (Preference) findPreference(PREFERENCE_KEY_IMPORT_BACKUP); importBackup.setOnPreferenceClickListener(new onClickListenerImportBackup()); @@ -80,6 +88,13 @@ public class BackupPreferences extends PreferenceFragmentCompat implements Share autoBackup = (CheckBoxPreference) findPreference(PREFERENCE_KEY_AUTO_BACKUP); autoBackup.setOnPreferenceClickListener(new onClickListenerAutoBackup()); + // Auto backup preference + autoBackupDir = (Preference) findPreference(PREFERENCE_KEY_AUTO_BACKUP_DIR); + autoBackupDir.setOnPreferenceClickListener(new onClickListenerAutoBackupDir()); + // Setting auto backup preference's summary to location or message that none is selected + String autoBackupDirString = prefs.getString("exportDir", null); + autoBackupDir.setSummary(autoBackupDirString != null ? Uri.parse(autoBackupDirString).getLastPathSegment() : getString(R.string.label_auto_backup_lacation)); + updateBackupPreferences(); } @@ -130,29 +145,50 @@ public class BackupPreferences extends PreferenceFragmentCompat implements Share private class onClickListenerAutoBackup implements Preference.OnPreferenceClickListener { @Override public boolean onPreferenceClick(Preference preference) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - if (autoBackup.isChecked()) { - autoBackup.setChecked(true); - } else { - autoBackup.setChecked(false); - } - } - else { - if (autoBackup.isChecked()) { - isAutoBackupAskForPermission = true; - - if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) - == PackageManager.PERMISSION_GRANTED) { - exportBackup(); - } else { - requestPermissionExportLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE); - } + if (autoBackup.isChecked()) { + autoBackup.setChecked(true); + // If exportDir location already saved user won't be prompted to select a new location + if (prefs.getString("exportDir", null) == null) { + Toast.makeText(getContext(), R.string.info_select_auto_backup_export_dir, Toast.LENGTH_SHORT).show(); + selectAutoBackupDir.launch(null); } + } else { + autoBackup.setChecked(false); } return true; } } + /** + * Function for "Export directory" setting + */ + private class onClickListenerAutoBackupDir implements Preference.OnPreferenceClickListener { + @Override + public boolean onPreferenceClick(@NonNull Preference preference) { + selectAutoBackupDir.launch(null); + return true; + } + } + + /** + * Launches Android File Picker to choose a directory where automatic backups should be saved + * If user exits File Picker without selecting an directory + * and previously none where select a "Auto backup" checkbox is removed + */ + ActivityResultLauncher selectAutoBackupDir = registerForActivityResult(new ActivityResultContracts.OpenDocumentTree(), result -> { + if (result != null) { + getActivity().getContentResolver().takePersistableUriPermission(result, Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + autoBackupDir.setSummary(result.getLastPathSegment()); + SharedPreferences.Editor editor = prefs.edit(); + editor.putString("exportDir", result.toString()); + editor.commit(); + } else { + if (prefs.getString("exportDir", null) == null) { + this.autoBackup.setChecked(false); + } + } + }); + private class onClickListenerImportBackup implements Preference.OnPreferenceClickListener { @Override public boolean onPreferenceClick(Preference preference) { diff --git a/android_app/app/src/main/res/values/strings.xml b/android_app/app/src/main/res/values/strings.xml index 774895a1..03772b6a 100644 --- a/android_app/app/src/main/res/values/strings.xml +++ b/android_app/app/src/main/res/values/strings.xml @@ -159,7 +159,7 @@ Export backup Import backup Backup - Export dir + Export directory not found Ignore out of range data Initial weight @@ -181,6 +181,7 @@ Select scale user Enter PIN/consent code for scale user %s Measuring weight: %.2f + Select auto backup export directory This scale has not been paired!\n\nHold the button on the bottom of the scale to switch it to pairing mode, and then reconnect to retrieve the device password. Pairing succeeded!\n\nReconnect to retrieve measurement data. An unexpected error occurred.\n\nPlease create a new issue including the error details on\nhttps://github.com/oliexdev/openScale/issues @@ -225,6 +226,7 @@ Estimated Based on weight, height, age, gender, etc. Auto backup + No auto backup location selected Backup schedule Overwrite previous backup daily diff --git a/android_app/app/src/main/res/xml/backup_preferences.xml b/android_app/app/src/main/res/xml/backup_preferences.xml index e93531aa..e08e361f 100644 --- a/android_app/app/src/main/res/xml/backup_preferences.xml +++ b/android_app/app/src/main/res/xml/backup_preferences.xml @@ -5,6 +5,7 @@ + - \ No newline at end of file