diff --git a/skunkworks_crow/src/main/java/org/odk/share/utilities/FileUtils.java b/skunkworks_crow/src/main/java/org/odk/share/utilities/FileUtils.java index c18c23d9..6b0eb452 100644 --- a/skunkworks_crow/src/main/java/org/odk/share/utilities/FileUtils.java +++ b/skunkworks_crow/src/main/java/org/odk/share/utilities/FileUtils.java @@ -1,5 +1,6 @@ package org.odk.share.utilities; +import java.io.File; import java.util.Locale; public final class FileUtils { @@ -15,4 +16,30 @@ public static String getFileExtension(String fileName) { } return fileName.substring(dotIndex + 1).toLowerCase(Locale.ROOT); } + + /** + * Delete all contents under the path, would not remove the folder. + */ + public static boolean deleteFolderContents(String path) { + boolean result = true; + File file = new File(path); + if (file.exists()) { + File[] files = file.listFiles(); + if (files != null) { + for (File f : files) { + result = deleteRecursive(f); + } + } + } + return result; + } + + private static boolean deleteRecursive(File fileOrDirectory) { + if (fileOrDirectory.isDirectory()) { + for (File child : fileOrDirectory.listFiles()) { + deleteRecursive(child); + } + } + return fileOrDirectory.delete(); + } } diff --git a/skunkworks_crow/src/main/java/org/odk/share/views/ui/settings/PreferenceKeys.java b/skunkworks_crow/src/main/java/org/odk/share/views/ui/settings/PreferenceKeys.java index 8d026d51..31bf8b59 100644 --- a/skunkworks_crow/src/main/java/org/odk/share/views/ui/settings/PreferenceKeys.java +++ b/skunkworks_crow/src/main/java/org/odk/share/views/ui/settings/PreferenceKeys.java @@ -10,6 +10,7 @@ public class PreferenceKeys { public static final String KEY_HOTSPOT_PASSWORD = "hotspot_password"; public static final String KEY_HOTSPOT_PWD_REQUIRE = "hotspot_pwd_require"; public static final String KEY_ODK_DESTINATION_DIR = "odk_destination_dir"; + public static final String KEY_RESET_SETTINGS = "reset_settings"; public static final String KEY_DEFAULT_TRANSFER_METHOD = "default_transfer_method"; public static final String KEY_BLUETOOTH_NAME = "bluetooth_name"; public static final String KEY_BLUETOOTH_SECURE_MODE = "bluetooth_secure_mode"; diff --git a/skunkworks_crow/src/main/java/org/odk/share/views/ui/settings/SettingsActivity.java b/skunkworks_crow/src/main/java/org/odk/share/views/ui/settings/SettingsActivity.java index dd9d517b..f95c7956 100644 --- a/skunkworks_crow/src/main/java/org/odk/share/views/ui/settings/SettingsActivity.java +++ b/skunkworks_crow/src/main/java/org/odk/share/views/ui/settings/SettingsActivity.java @@ -1,6 +1,8 @@ package org.odk.share.views.ui.settings; +import android.app.ProgressDialog; import android.bluetooth.BluetoothAdapter; +import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; @@ -16,6 +18,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import android.widget.CheckBox; import android.widget.Toast; import androidx.appcompat.app.AlertDialog; @@ -24,6 +27,8 @@ import com.google.android.material.textfield.TextInputLayout; import org.odk.share.R; +import org.odk.share.application.Share; +import org.odk.share.utilities.FileUtils; /** @@ -35,11 +40,13 @@ public class SettingsActivity extends PreferenceActivity { EditTextPreference hotspotNamePreference; EditTextPreference bluetoothNamePreference; Preference hotspotPasswordPreference; + Preference resetPreference; CheckBoxPreference passwordRequirePreference; CheckBoxPreference btSecureModePreference; EditTextPreference odkDestinationDirPreference; ListPreference defaultMethodPreference; private SharedPreferences prefs; + private ProgressDialog progressDialog; @Override protected void onCreate(Bundle savedInstanceState) { @@ -62,6 +69,7 @@ public boolean onOptionsItemSelected(MenuItem item) { } private void addPreferences() { + resetPreference = findPreference(PreferenceKeys.KEY_RESET_SETTINGS); defaultMethodPreference = (ListPreference) findPreference(PreferenceKeys.KEY_DEFAULT_TRANSFER_METHOD); hotspotNamePreference = (EditTextPreference) findPreference(PreferenceKeys.KEY_HOTSPOT_NAME); bluetoothNamePreference = (EditTextPreference) findPreference(PreferenceKeys.KEY_BLUETOOTH_NAME); @@ -78,8 +86,8 @@ private void addPreferences() { getString(R.string.default_hotspot_ssid))); String defaultBluetoothName = BluetoothAdapter.getDefaultAdapter().getName(); bluetoothNamePreference.setText(defaultBluetoothName); - bluetoothNamePreference.setDefaultValue(defaultBluetoothName); bluetoothNamePreference.setSummary(prefs.getString(PreferenceKeys.KEY_BLUETOOTH_NAME, defaultBluetoothName)); + boolean isPasswordSet = prefs.getBoolean(PreferenceKeys.KEY_HOTSPOT_PWD_REQUIRE, false); odkDestinationDirPreference.setSummary(prefs.getString(PreferenceKeys.KEY_ODK_DESTINATION_DIR, getString(R.string.default_odk_destination_dir))); @@ -96,6 +104,7 @@ private void addPreferences() { odkDestinationDirPreference.setOnPreferenceChangeListener(preferenceChangeListener()); defaultMethodPreference.setOnPreferenceChangeListener(preferenceChangeListener()); + resetPreference.setOnPreferenceClickListener(preferenceClickListener()); hotspotPasswordPreference.setOnPreferenceClickListener(preferenceClickListener()); } @@ -105,6 +114,9 @@ private Preference.OnPreferenceClickListener preferenceClickListener() { case PreferenceKeys.KEY_HOTSPOT_PASSWORD: showPasswordDialog(); break; + case PreferenceKeys.KEY_RESET_SETTINGS: + resetApplication(); + break; } return false; }; @@ -129,8 +141,7 @@ private Preference.OnPreferenceChangeListener preferenceChangeListener() { return false; } else { bluetoothNamePreference.setSummary(bluetoothName); - BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - bluetoothAdapter.setName(bluetoothName); + BluetoothAdapter.getDefaultAdapter().setName(bluetoothName); } break; case PreferenceKeys.KEY_HOTSPOT_PASSWORD: @@ -198,4 +209,86 @@ private void showPasswordDialog() { alertDialog.setCancelable(true); alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); } + + /** + * Reset the application settings and the database. + */ + private void resetApplication() { + View checkBoxView = View.inflate(this, R.layout.pref_reset_dialog, null); + CheckBox cbResetPref = checkBoxView.findViewById(R.id.cb_reset_pref); + CheckBox cbResetData = checkBoxView.findViewById(R.id.cb_clear_db); + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + AlertDialog resetDialog = builder.setTitle(getString(R.string.title_reset_settings)) + .setView(checkBoxView) + .setCancelable(false) + .setPositiveButton(getString(R.string.ok), (DialogInterface dialog, int which) -> { + progressDialog = new ProgressDialog(this); + progressDialog.setTitle(getString(R.string.resetting)); + progressDialog.setMessage(getString(R.string.resetting_msg)); + progressDialog.setIndeterminate(true); + progressDialog.setCancelable(false); + progressDialog.show(); + dialog.dismiss(); + + if (!cbResetData.isChecked() && !cbResetPref.isChecked()) { + progressDialog.dismiss(); + Toast.makeText(this, getString(R.string.reset_select_nothing), Toast.LENGTH_LONG).show(); + } else { + startReset(cbResetPref, cbResetData); + } + }) + .setNegativeButton(getString(R.string.cancel), (DialogInterface dialog, int which) -> { + dialog.dismiss(); + }) + .create(); + resetDialog.show(); + } + + /** + * Start resetting the application and presenting the reset result in an {@link AlertDialog}. + */ + private void startReset(CheckBox cbResetPref, CheckBox cbResetData) { + StringBuilder stringBuilder = new StringBuilder(); + if (cbResetData.isChecked()) { + stringBuilder.append(getString(R.string.reset_result_data, + resetData() ? getString(R.string.reset_success) : getString(R.string.reset_failed))); + } + + if (cbResetPref.isChecked()) { + stringBuilder.append(getString(R.string.reset_result_pref, + resetPreference() ? getString(R.string.reset_success) : getString(R.string.reset_failed))); + } + + progressDialog.dismiss(); + new AlertDialog.Builder(this) + .setTitle(getString(R.string.reset_result)) + .setMessage(stringBuilder.toString()) + .setCancelable(false) + .setPositiveButton(getString(R.string.ok), (DialogInterface dialog, int which) -> { + dialog.dismiss(); + finish(); + }) + .create() + .show(); + } + + /** + * Reset the preference by resetting the {@link SharedPreferences}. + */ + private boolean resetPreference() { + SharedPreferences.Editor editor = prefs.edit(); + editor.clear(); + return editor.commit(); + } + + /** + * Removing the cache and database table by deleting the share + * folder and create a new one. + */ + private boolean resetData() { + boolean result = FileUtils.deleteFolderContents(Share.ODK_ROOT); + Share.createODKDirs(this); + return result; + } } diff --git a/skunkworks_crow/src/main/res/drawable/ic_refresh_black_24dp.xml b/skunkworks_crow/src/main/res/drawable/ic_refresh_black_24dp.xml new file mode 100644 index 00000000..8229a9a6 --- /dev/null +++ b/skunkworks_crow/src/main/res/drawable/ic_refresh_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/skunkworks_crow/src/main/res/layout/pref_reset_dialog.xml b/skunkworks_crow/src/main/res/layout/pref_reset_dialog.xml new file mode 100644 index 00000000..bb06190c --- /dev/null +++ b/skunkworks_crow/src/main/res/layout/pref_reset_dialog.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/skunkworks_crow/src/main/res/values/strings.xml b/skunkworks_crow/src/main/res/values/strings.xml index 853a3170..49db916b 100644 --- a/skunkworks_crow/src/main/res/values/strings.xml +++ b/skunkworks_crow/src/main/res/values/strings.xml @@ -143,6 +143,19 @@ The destination should not be empty Location Permission Needed Enable location from the settings. + Reset Application + Reset Saved Forms + reset forms sent for review and forms received for review. + Reset All Settings + reset internal settings and saved settings. + Please select items to reset + Resetting + Resetting application, please wait… + Reset Results + All Settings: %s + Saved Forms: %s \n + Success + Failed Switch Refresh diff --git a/skunkworks_crow/src/main/res/xml/preferences_menu.xml b/skunkworks_crow/src/main/res/xml/preferences_menu.xml index b7ac7d23..6c9349ce 100644 --- a/skunkworks_crow/src/main/res/xml/preferences_menu.xml +++ b/skunkworks_crow/src/main/res/xml/preferences_menu.xml @@ -1,7 +1,6 @@ - + @@ -59,6 +62,5 @@ android:key="bluetooth_secure_mode" android:summary="@string/summary_security_bluetooth" android:title="@string/secure_mode" /> -