Show a backup reminder if auto backups are not enabled

If the user doesn't have auto backups enabled, the reminder will pop up
up every time a significant change is made to the vault.

Users can get rid of the reminder by:
- Creating an export
- Enabling automatic backups (either ours or Android backups will do)
This commit is contained in:
Alexander Bakker 2022-04-10 16:47:44 +02:00
parent cf9fbf081c
commit 339a31b0f3
7 changed files with 66 additions and 20 deletions

View file

@ -308,6 +308,16 @@ public class Preferences {
return _prefs.getString("pref_backups_error", null); return _prefs.getString("pref_backups_error", null);
} }
public void setIsBackupReminderNeeded(boolean needed) {
if (isBackupsReminderNeeded() != needed) {
_prefs.edit().putBoolean("pref_backups_reminder_needed", needed).apply();
}
}
public boolean isBackupsReminderNeeded() {
return _prefs.getBoolean("pref_backups_reminder_needed", false);
}
public boolean isPinKeyboardEnabled() { public boolean isPinKeyboardEnabled() {
return _prefs.getBoolean("pref_pin_keyboard", false); return _prefs.getBoolean("pref_pin_keyboard", false);
} }

View file

@ -15,6 +15,7 @@ import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.view.ActionMode; import androidx.appcompat.view.ActionMode;
@ -80,7 +81,8 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
private Menu _menu; private Menu _menu;
private SearchView _searchView; private SearchView _searchView;
private EntryListView _entryListView; private EntryListView _entryListView;
private LinearLayout _btnBackupError; private LinearLayout _btnErrorBar;
private TextView _textErrorBar;
private FabScrollHelper _fabScrollHelper; private FabScrollHelper _fabScrollHelper;
@ -132,10 +134,8 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
Dialogs.showSecureDialog(dialog); Dialogs.showSecureDialog(dialog);
}); });
_btnBackupError = findViewById(R.id.btn_backup_error); _btnErrorBar = findViewById(R.id.btn_error_bar);
_btnBackupError.setOnClickListener(view -> { _textErrorBar = findViewById(R.id.text_error_bar);
startPreferencesActivity(BackupsPreferencesFragment.class, "pref_backups");
});
_fabScrollHelper = new FabScrollHelper(fab); _fabScrollHelper = new FabScrollHelper(fab);
_selectedEntries = new ArrayList<>(); _selectedEntries = new ArrayList<>();
@ -480,7 +480,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
handleSharedImage(); handleSharedImage();
updateLockIcon(); updateLockIcon();
doShortcutActions(); doShortcutActions();
updateBackupErrorBar(); updateErrorBar();
} }
@Override @Override
@ -637,13 +637,27 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
} }
} }
private void updateBackupErrorBar() { private void updateErrorBar() {
String error = null; String backupError = null;
if (_prefs.isBackupsEnabled()) { if (_prefs.isBackupsEnabled()) {
error = _prefs.getBackupsError(); backupError = _prefs.getBackupsError();
} }
_btnBackupError.setVisibility(error == null ? View.GONE : View.VISIBLE); if (backupError != null) {
_textErrorBar.setText(R.string.backup_error_bar_message);
_btnErrorBar.setOnClickListener(view -> {
startPreferencesActivity(BackupsPreferencesFragment.class, "pref_backups");
});
_btnErrorBar.setVisibility(View.VISIBLE);
} else if (_prefs.isBackupsReminderNeeded()) {
_textErrorBar.setText(R.string.backup_reminder_bar_message);
_btnErrorBar.setOnClickListener(view -> {
startPreferencesActivity();
});
_btnErrorBar.setVisibility(View.VISIBLE);
} else {
_btnErrorBar.setVisibility(View.GONE);
}
} }
@Override @Override

View file

@ -64,13 +64,7 @@ public class BackupsPreferencesFragment extends PreferencesFragment {
_backupsTriggerPreference = findPreference("pref_backups_trigger"); _backupsTriggerPreference = findPreference("pref_backups_trigger");
_backupsTriggerPreference.setOnPreferenceClickListener(preference -> { _backupsTriggerPreference.setOnPreferenceClickListener(preference -> {
if (_prefs.isBackupsEnabled()) { if (_prefs.isBackupsEnabled()) {
try { scheduleBackup();
_vaultManager.scheduleBackup();
Toast.makeText(getActivity(), R.string.backup_successful, Toast.LENGTH_LONG).show();
} catch (VaultRepositoryException e) {
e.printStackTrace();
Dialogs.showErrorDialog(getContext(), R.string.backup_error, e);
}
} }
return true; return true;
}); });
@ -108,6 +102,7 @@ public class BackupsPreferencesFragment extends PreferencesFragment {
_prefs.setBackupsError(null); _prefs.setBackupsError(null);
_backupsLocationPreference.setSummary(String.format("%s: %s", getString(R.string.pref_backups_location_summary), Uri.decode(uri.toString()))); _backupsLocationPreference.setSummary(String.format("%s: %s", getString(R.string.pref_backups_location_summary), Uri.decode(uri.toString())));
updateBackupPreference(); updateBackupPreference();
scheduleBackup();
} }
private void updateBackupPreference() { private void updateBackupPreference() {
@ -132,4 +127,14 @@ public class BackupsPreferencesFragment extends PreferencesFragment {
_vaultManager.startActivityForResult(this, intent, CODE_BACKUPS); _vaultManager.startActivityForResult(this, intent, CODE_BACKUPS);
} }
private void scheduleBackup() {
try {
_vaultManager.scheduleBackup();
Toast.makeText(getActivity(), R.string.backup_successful, Toast.LENGTH_LONG).show();
} catch (VaultRepositoryException e) {
e.printStackTrace();
Dialogs.showErrorDialog(getContext(), R.string.backup_error, e);
}
}
} }

View file

@ -214,6 +214,9 @@ public class ImportExportPreferencesFragment extends PreferencesFragment {
return; return;
} }
// if the user creates an export, hide the backup reminder
_prefs.setIsBackupReminderNeeded(false);
Uri uri = FileProvider.getUriForFile(getContext(), BuildConfig.FILE_PROVIDER_AUTHORITY, file); Uri uri = FileProvider.getUriForFile(getContext(), BuildConfig.FILE_PROVIDER_AUTHORITY, file);
Intent intent = new Intent(Intent.ACTION_SEND) Intent intent = new Intent(Intent.ACTION_SEND)
.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
@ -343,6 +346,9 @@ public class ImportExportPreferencesFragment extends PreferencesFragment {
e.printStackTrace(); e.printStackTrace();
Dialogs.showErrorDialog(getContext(), R.string.exporting_vault_error, e); Dialogs.showErrorDialog(getContext(), R.string.exporting_vault_error, e);
} else { } else {
// if the user creates an export, hide the backup reminder
_prefs.setIsBackupReminderNeeded(false);
Toast.makeText(getContext(), getString(R.string.exported_vault), Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), getString(R.string.exported_vault), Toast.LENGTH_SHORT).show();
} }
} }

View file

@ -165,8 +165,10 @@ public class VaultManager {
public void saveAndBackup() throws VaultRepositoryException { public void saveAndBackup() throws VaultRepositoryException {
save(); save();
boolean backedUp = false;
if (getVault().isEncryptionEnabled()) { if (getVault().isEncryptionEnabled()) {
if (_prefs.isBackupsEnabled()) { if (_prefs.isBackupsEnabled()) {
backedUp = true;
try { try {
scheduleBackup(); scheduleBackup();
_prefs.setBackupsError(null); _prefs.setBackupsError(null);
@ -176,12 +178,19 @@ public class VaultManager {
} }
if (_prefs.isAndroidBackupsEnabled()) { if (_prefs.isAndroidBackupsEnabled()) {
backedUp = true;
scheduleAndroidBackup(); scheduleAndroidBackup();
} }
} }
if (!backedUp) {
_prefs.setIsBackupReminderNeeded(true);
}
} }
public void scheduleBackup() throws VaultRepositoryException { public void scheduleBackup() throws VaultRepositoryException {
_prefs.setIsBackupReminderNeeded(false);
try { try {
File dir = new File(_context.getCacheDir(), "backup"); File dir = new File(_context.getCacheDir(), "backup");
if (!dir.exists() && !dir.mkdir()) { if (!dir.exists() && !dir.mkdir()) {
@ -197,6 +206,7 @@ public class VaultManager {
} }
public void scheduleAndroidBackup() { public void scheduleAndroidBackup() {
_prefs.setIsBackupReminderNeeded(false);
_androidBackups.dataChanged(); _androidBackups.dataChanged();
} }

View file

@ -24,7 +24,7 @@
app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
android:id="@+id/btn_backup_error" android:id="@+id/btn_error_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
@ -40,11 +40,11 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:tint="@color/icon_primary_inverted" app:tint="@color/icon_primary_inverted"
android:src="@drawable/ic_alert_black_24dp" /> android:src="@drawable/ic_info_outline_black_24dp" />
<TextView <TextView
android:id="@+id/text_error_bar"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/backup_error_bar_message"
android:textColor="@color/primary_text_inverted" android:textColor="@color/primary_text_inverted"
android:layout_marginStart="5dp" /> android:layout_marginStart="5dp" />
</LinearLayout> </LinearLayout>

View file

@ -311,6 +311,7 @@
</plurals> </plurals>
<string name="google_qr_export_unexpected">Expected QR code #%d, but scanned #%d instead</string> <string name="google_qr_export_unexpected">Expected QR code #%d, but scanned #%d instead</string>
<string name="backup_error_bar_message"><b>Vault backup failed recently</b></string> <string name="backup_error_bar_message"><b>Vault backup failed recently</b></string>
<string name="backup_reminder_bar_message"><b>Recent vault changes are not backed up</b></string>
<string name="switch_camera">Switch camera</string> <string name="switch_camera">Switch camera</string>
<string name="custom_notices_format_style" translatable="false" > <string name="custom_notices_format_style" translatable="false" >