From 7f67d9398ceccb4b8c26b7f2dbd1323d8fdcb81e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Thu, 10 Nov 2022 14:24:55 +0100 Subject: [PATCH] Refactor preference handling - Move all access to preferences into PrefManager.java - Move preference keys to separate file preference_keys.xml - Use getSharedPreferences instead of deprecated getDefaultSharedPreferences - Fix usage of incorrect string values in pref_notification.xml and pref_workout.xml - Migrate old translated preference values to new non-translatable values in PrefManager.migratePreferences - Migrate preference from different file to default preference file in PrefManager.migratePreferences --- .../activities/BaseActivity.java | 22 +- .../activities/MainActivity.java | 224 ++++++----------- .../MotivationAlertTextsActivity.java | 26 +- .../activities/SettingsActivity.java | 7 +- .../activities/SplashActivity.java | 5 +- .../activities/WorkoutActivity.java | 58 ++--- .../backup/BackupCreator.kt | 5 +- .../backup/BackupRestorer.kt | 69 ++--- .../helpers/NotificationHelper.java | 20 +- .../receivers/MotivationAlertReceiver.java | 18 +- .../services/TimerService.java | 50 +--- .../tutorial/PrefManager.java | 236 ++++++++++++++++-- app/src/main/res/values-de/strings.xml | 4 +- app/src/main/res/values/preference_keys.xml | 53 ++++ app/src/main/res/values/strings.xml | 29 +-- app/src/main/res/xml/pref_notification.xml | 4 +- app/src/main/res/xml/pref_workout.xml | 5 +- 17 files changed, 475 insertions(+), 360 deletions(-) create mode 100644 app/src/main/res/values/preference_keys.xml diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/BaseActivity.java b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/BaseActivity.java index a8455ba..0796990 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/BaseActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/BaseActivity.java @@ -15,21 +15,21 @@ package org.secuso.privacyfriendlycircuittraining.activities; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.preference.PreferenceManager; -import com.google.android.material.navigation.NavigationView; -import com.google.android.material.navigation.NavigationView.OnNavigationItemSelectedListener; -import androidx.core.app.TaskStackBuilder; -import androidx.core.view.GravityCompat; -import androidx.drawerlayout.widget.DrawerLayout; +import android.view.MenuItem; +import android.view.View; + import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import android.view.MenuItem; -import android.view.View; +import androidx.core.app.TaskStackBuilder; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; + +import com.google.android.material.navigation.NavigationView; +import com.google.android.material.navigation.NavigationView.OnNavigationItemSelectedListener; import org.secuso.privacyfriendlycircuittraining.R; import org.secuso.privacyfriendlycircuittraining.tutorial.PrefManager; @@ -58,13 +58,11 @@ public abstract class BaseActivity extends AppCompatActivity implements OnNaviga // Helper private Handler mHandler; - protected SharedPreferences mSharedPreferences; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); mHandler = new Handler(); overridePendingTransition(0, 0); @@ -174,7 +172,7 @@ private void callDrawerItem(final int itemId) { createBackStack(intent); break; case R.id.nav_tutorial: - PrefManager prefManager = new PrefManager(getBaseContext()); + PrefManager.performMigrations(getBaseContext()); //prefManager.setFirstTimeLaunch(true); intent = new Intent(this, TutorialActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/MainActivity.java b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/MainActivity.java index 0e40a09..2344712 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/MainActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/MainActivity.java @@ -21,13 +21,11 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.ServiceConnection; -import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.preference.PreferenceActivity; import android.preference.PreferenceManager; -import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -44,12 +42,10 @@ import org.secuso.privacyfriendlycircuittraining.database.PFASQLiteHelper; import org.secuso.privacyfriendlycircuittraining.fragments.GrantExactAlarmPermissionDialogFragment; import org.secuso.privacyfriendlycircuittraining.helpers.NotificationHelper; -import org.secuso.privacyfriendlycircuittraining.models.Exercise; import org.secuso.privacyfriendlycircuittraining.models.ExerciseSet; import org.secuso.privacyfriendlycircuittraining.services.TimerService; import org.secuso.privacyfriendlycircuittraining.tutorial.PrefManager; -import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; @@ -63,23 +59,14 @@ public class MainActivity extends BaseActivity { // CONFIGURE TIMER VARIABLES HERE // Max and min values for the workout and rest timer as well as the sets - private int workoutMaxTime = 300; // 5 min - private int workoutMinTime = 10; // 10 sec - private int restMaxTime = 300; // 5 min - private int restMinTime = 10; // 10 sec - private int maxSets = 16; - private int minSets = 1; - - // Default values for the timers - private final int workoutTimeDefault = 60; - private final int restTimeDefault = 30; - private final int setsDefault = 6; - private final int blockPeriodizationTimeDefault = 90; - private final int blockPeriodizationSetsDefault = 1; + private final int workoutMaxTime = 300; // 5 min + private final int workoutMinTime = 10; // 10 sec + private final int restMaxTime = 300; // 5 min + private final int restMinTime = 10; // 10 sec + private final int maxSets = 16; + private final int minSets = 1; // General - private SharedPreferences settings = null; - private PrefManager prefManager = null; private Intent intent = null; // Block periodization values and Button @@ -127,8 +114,6 @@ protected void onCreate(Bundle savedInstanceState) { PreferenceManager.setDefaultValues(this, R.xml.pref_statistics, true); PreferenceManager.setDefaultValues(this, R.xml.pref_workout, true); - this.settings = PreferenceManager.getDefaultSharedPreferences(this); - //Set default values for the timer configurations setDefaultTimerValues(); @@ -173,14 +158,14 @@ protected void onCreate(Bundle savedInstanceState) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { isBlockPeriodization = isChecked; blockPeriodizationSwitchState = isChecked; - settings.edit().putBoolean("blockPeriodizationSwitchButton", isChecked).apply(); + PrefManager.setBlockPeriodizationSwitchButton(getBaseContext(), isChecked); } }); //Suggest the user to enter his body data - prefManager = new PrefManager(this); - if(prefManager.isFirstTimeLaunch()){ - prefManager.setFirstTimeLaunch(false); + PrefManager.performMigrations(getBaseContext()); + if(PrefManager.isFirstTimeLaunch(getBaseContext())){ + PrefManager.setFirstTimeLaunch(getBaseContext(), false); showPersonalizationAlert(); } @@ -190,7 +175,7 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { isExerciseMode = isChecked; workoutModeSwitchState = isChecked; - settings.edit().putBoolean("workoutMode", isChecked).apply(); + PrefManager.setWorkoutMode(getBaseContext(), isChecked); if(isExerciseMode){ if(exerciseSetslist.size() == 0){ toast = Toast.makeText(getApplication(), getResources().getString(R.string.no_exercise_sets), Toast.LENGTH_LONG); @@ -206,7 +191,7 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { } else{ buttonView.getRootView().findViewById(R.id.exerciesetsRow).setVisibility(View.GONE); - sets = setsDefault; + sets = PrefManager.setsDefault; setsText.setText(Integer.toString(sets)); exerciseIds = null; } @@ -245,86 +230,65 @@ protected int getNavigationDrawerID() { * Click functions for timer values, block periodization AlertDialog and workout start button */ public void onClick(View view) { - SharedPreferences.Editor editor = this.settings.edit(); - - switch(view.getId()) { - case R.id.main_workout_interval_minus: - workoutTime = (workoutTime <= workoutMinTime) ? workoutMaxTime : workoutTime - 10; - workoutIntervalText.setText(formatTime(workoutTime)); - editor.putInt(this.getString(R.string.pref_timer_workout),(int) this.workoutTime); - editor.apply(); - break; - case R.id.main_workout_interval_plus: - this.workoutTime = (workoutTime >= workoutMaxTime) ? workoutMinTime : this.workoutTime + 10; - this.workoutIntervalText.setText(formatTime(workoutTime)); - editor.putInt(this.getString(R.string.pref_timer_workout),(int) this.workoutTime); - editor.apply(); - break; - case R.id.main_rest_interval_minus: - this.restTime = (restTime <= restMinTime) ? restMaxTime : this.restTime - 10; - this.restIntervalText.setText(formatTime(restTime)); - editor.putInt(this.getString(R.string.pref_timer_rest),(int) this.restTime); - editor.apply(); - break; - case R.id.main_rest_interval_plus: - this.restTime = (restTime >= restMaxTime) ? restMinTime : this.restTime + 10; - this.restIntervalText.setText(formatTime(restTime)); - editor.putInt(this.getString(R.string.pref_timer_rest),(int) this.restTime); - editor.apply(); - break; - case R.id.main_sets_minus: - this.sets = (sets <= minSets) ? maxSets : this.sets - 1; - this.setsText.setText(Integer.toString(sets)); - editor.putInt(this.getString(R.string.pref_timer_set), this.sets); - editor.apply(); - break; - case R.id.main_sets_plus: - this.sets = (sets >= maxSets) ? minSets : this.sets + 1; - this.setsText.setText(Integer.toString(sets)); - editor.putInt(this.getString(R.string.pref_timer_set), this.sets); - editor.apply(); - break; - case R.id.main_block_periodization: - AlertDialog blockAlert = buildBlockAlert(); - blockAlert.show(); - break; - case R.id.main_block_periodization_text: - this.blockPeriodizationSwitchButton.setChecked(!this.blockPeriodizationSwitchButton.isChecked()); - editor.putBoolean("blockPeriodizationSwitchButton", this.blockPeriodizationSwitchButton.isChecked()); - editor.apply(); - break; - case R.id.main_use_exercise_sets_text: - this.workoutMode.setChecked(!this.workoutMode.isChecked()); - editor.putBoolean("workoutMode", this.workoutMode.isChecked()); - editor.apply(); - break; - case R.id.start_workout: - intent = new Intent(this, WorkoutActivity.class); - - if(isExerciseMode){ - ExerciseIdsForRounds = getExercisesForRounds(exerciseIds, sets); - setsPerRound = sets * exerciseIds.size(); - } else { - ExerciseIdsForRounds = exerciseIds; - setsPerRound = sets; - } + int id = view.getId(); + if (id == R.id.main_workout_interval_minus) { + workoutTime = (workoutTime <= workoutMinTime) ? workoutMaxTime : workoutTime - 10; + workoutIntervalText.setText(formatTime(workoutTime)); + PrefManager.setTimerWorkout(getBaseContext(), (int) this.workoutTime); + } else if (id == R.id.main_workout_interval_plus) { + this.workoutTime = (workoutTime >= workoutMaxTime) ? workoutMinTime : this.workoutTime + 10; + this.workoutIntervalText.setText(formatTime(workoutTime)); + PrefManager.setTimerWorkout(getBaseContext(), (int) this.workoutTime); + } else if (id == R.id.main_rest_interval_minus) { + this.restTime = (restTime <= restMinTime) ? restMaxTime : this.restTime - 10; + this.restIntervalText.setText(formatTime(restTime)); + PrefManager.setTimerRest(getBaseContext(), (int) this.restTime); + } else if (id == R.id.main_rest_interval_plus) { + this.restTime = (restTime >= restMaxTime) ? restMinTime : this.restTime + 10; + this.restIntervalText.setText(formatTime(restTime)); + PrefManager.setTimerRest(getBaseContext(), (int) this.restTime); + } else if (id == R.id.main_sets_minus) { + this.sets = (sets <= minSets) ? maxSets : this.sets - 1; + this.setsText.setText(Integer.toString(sets)); + PrefManager.setTimerSet(getBaseContext(), this.sets); + } else if (id == R.id.main_sets_plus) { + this.sets = (sets >= maxSets) ? minSets : this.sets + 1; + this.setsText.setText(Integer.toString(sets)); + PrefManager.setTimerSet(getBaseContext(), this.sets); + } else if (id == R.id.main_block_periodization) { + AlertDialog blockAlert = buildBlockAlert(); + blockAlert.show(); + } else if (id == R.id.main_block_periodization_text) { + this.blockPeriodizationSwitchButton.setChecked(!this.blockPeriodizationSwitchButton.isChecked()); + PrefManager.setBlockPeriodizationSwitchButton(getBaseContext(), this.blockPeriodizationSwitchButton.isChecked()); + } else if (id == R.id.main_use_exercise_sets_text) { + this.workoutMode.setChecked(!this.workoutMode.isChecked()); + PrefManager.setWorkoutMode(getBaseContext(), this.workoutMode.isChecked()); + } else if (id == R.id.start_workout) { + intent = new Intent(this, WorkoutActivity.class); + + if (isExerciseMode) { + ExerciseIdsForRounds = getExercisesForRounds(exerciseIds, sets); + setsPerRound = sets * exerciseIds.size(); + } else { + ExerciseIdsForRounds = exerciseIds; + setsPerRound = sets; + } - if(setsPerRound == 0 || ExerciseIdsForRounds.size() == 0) { - Toast.makeText(this, R.string.exercise_set_has_no_exercises, Toast.LENGTH_SHORT).show(); - return; - } + if (setsPerRound == 0 || ExerciseIdsForRounds.size() == 0) { + Toast.makeText(this, R.string.exercise_set_has_no_exercises, Toast.LENGTH_SHORT).show(); + return; + } - if (isStartTimerEnabled(this)) { - timerService.startWorkout(workoutTime, restTime, startTime, setsPerRound, - isBlockPeriodization, blockPeriodizationTime, blockPeriodizationSets, ExerciseIdsForRounds, isExerciseMode); - } else { - timerService.startWorkout(workoutTime, restTime, 0, setsPerRound, - isBlockPeriodization, blockPeriodizationTime, blockPeriodizationSets, ExerciseIdsForRounds, isExerciseMode); - } + if (isStartTimerEnabled(this)) { + timerService.startWorkout(workoutTime, restTime, startTime, setsPerRound, + isBlockPeriodization, blockPeriodizationTime, blockPeriodizationSets, ExerciseIdsForRounds, isExerciseMode); + } else { + timerService.startWorkout(workoutTime, restTime, 0, setsPerRound, + isBlockPeriodization, blockPeriodizationTime, blockPeriodizationSets, ExerciseIdsForRounds, isExerciseMode); + } - this.startActivity(intent); - break; - default: + this.startActivity(intent); } } @@ -370,47 +334,34 @@ private AlertDialog buildBlockAlert(){ setButtonPlus.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - SharedPreferences.Editor editor = settings.edit(); - if(blockPeriodizationSets < sets-1){ blockPeriodizationSets += 1; } setsText.setText(Integer.toString(blockPeriodizationSets)); - editor.putInt(getString(R.string.pref_timer_periodization_set), blockPeriodizationSets); - editor.commit(); + PrefManager.setTimerPeriodizationSet(getBaseContext(), blockPeriodizationSets); } }); setButtonMinus.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - SharedPreferences.Editor editor = settings.edit(); - if(blockPeriodizationSets > 1){ blockPeriodizationSets -= 1; } setsText.setText(Integer.toString(blockPeriodizationSets)); - editor.putInt(getString(R.string.pref_timer_periodization_set), blockPeriodizationSets); - editor.commit(); + PrefManager.setTimerPeriodizationSet(getBaseContext(), blockPeriodizationSets); } }); timeButtonPlus.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - SharedPreferences.Editor editor = settings.edit(); - if(blockPeriodizationTime < blockPeriodizationTimeMax){ blockPeriodizationTime += 10; } timeText.setText(formatTime(blockPeriodizationTime)); - editor.putInt(getString(R.string.pref_timer_periodization_time), (int) blockPeriodizationTime); - editor.commit(); - + PrefManager.setTimerPeriodizationTime(getBaseContext(), (int) blockPeriodizationTime); } }); timeButtonMinus.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - SharedPreferences.Editor editor = settings.edit(); - if(blockPeriodizationTime > 10){ blockPeriodizationTime -= 10; } timeText.setText(formatTime(blockPeriodizationTime)); - editor.putInt(getString(R.string.pref_timer_periodization_time), (int) blockPeriodizationTime); - editor.commit(); + PrefManager.setTimerPeriodizationTime(getBaseContext(), (int) blockPeriodizationTime); } }); @@ -454,24 +405,14 @@ public void onClick(DialogInterface dialog, int id) { /** * Initializes the timer values for the GUI. Previously chosen setup is retrieved if one exists. */ - private void setDefaultTimerValues(){ - if(settings != null ) { - this.workoutTime = settings.getInt(this.getString(R.string.pref_timer_workout), workoutTimeDefault); - this.restTime = settings.getInt(this.getString(R.string.pref_timer_rest), restTimeDefault); - this.sets = settings.getInt(this.getString(R.string.pref_timer_set), setsDefault); - this.blockPeriodizationTime = settings.getInt(this.getString(R.string.pref_timer_periodization_time), blockPeriodizationTimeDefault); - this.blockPeriodizationSets = settings.getInt(this.getString(R.string.pref_timer_periodization_set), blockPeriodizationSetsDefault); - this.blockPeriodizationSwitchState = settings.getBoolean("blockPeriodizationSwitchButton", false); - this.workoutModeSwitchState = settings.getBoolean("workoutMode", false); - } else { - this.workoutTime = workoutTimeDefault; - this.restTime = restTimeDefault; - this.sets = setsDefault; - this.blockPeriodizationTime = blockPeriodizationTimeDefault; - this.blockPeriodizationSets = blockPeriodizationSetsDefault; - this.blockPeriodizationSwitchState = false; - this.workoutModeSwitchState = false; - } + private void setDefaultTimerValues() { + this.workoutTime = PrefManager.getTimerWorkout(getBaseContext()); + this.restTime = PrefManager.getTimerRest(getBaseContext()); + this.sets = PrefManager.getTimerSet(getBaseContext()); + this.blockPeriodizationTime = PrefManager.getTimerPeriodizationTime(getBaseContext()); + this.blockPeriodizationSets = PrefManager.getTimerPeriodizationSet(getBaseContext()); + this.blockPeriodizationSwitchState = PrefManager.getBlockPeriodizationSwitchButton(getBaseContext()); + this.workoutModeSwitchState = PrefManager.getWorkoutMode(getBaseContext()); } @@ -505,10 +446,7 @@ public void onDestroy() { * Helper methods and preference checks */ public boolean isStartTimerEnabled(Context context) { - if (this.settings != null) { - return settings.getBoolean(context.getString(R.string.pref_start_timer_switch_enabled), true); - } - return false; + return PrefManager.getStartTimerSwitchEnabled(getBaseContext()); } private String formatTime(long seconds) { diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/MotivationAlertTextsActivity.java b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/MotivationAlertTextsActivity.java index f1091c9..e1044dd 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/MotivationAlertTextsActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/MotivationAlertTextsActivity.java @@ -15,23 +15,24 @@ package org.secuso.privacyfriendlycircuittraining.activities; import android.content.DialogInterface; -import android.content.SharedPreferences; import android.os.Bundle; -import android.preference.PreferenceManager; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.ItemTouchHelper; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.RelativeLayout; import android.widget.Toast; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + import org.secuso.privacyfriendlycircuittraining.R; import org.secuso.privacyfriendlycircuittraining.adapters.MotivationAlertTextsAdapter; +import org.secuso.privacyfriendlycircuittraining.tutorial.PrefManager; import java.util.ArrayList; import java.util.Arrays; @@ -122,9 +123,7 @@ public void onResume() { * If motivation texts set is empty the view will be set to 'empty view' */ protected void showMotivationAlertTexts() { - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - Set defaultStringSet = new HashSet<>(Arrays.asList(getResources().getStringArray(R.array.pref_default_notification_motivation_alert_messages))); - Set stringSet = sharedPref.getStringSet(this.getString(R.string.pref_notification_motivation_alert_texts), defaultStringSet); + Set stringSet = PrefManager.getNotificationMotivationAlertTexts(getBaseContext()); motivationTexts = new ArrayList<>(Arrays.asList(stringSet.toArray(new String[stringSet.size()]))); this.mAdapter.setItems(motivationTexts); @@ -139,10 +138,7 @@ protected void showMotivationAlertTexts() { * Stores the motivation texts to shared preferences */ protected void save() { - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - SharedPreferences.Editor editor = sharedPref.edit(); - editor.putStringSet(this.getString(R.string.pref_notification_motivation_alert_texts), new HashSet<>(motivationTexts)); - editor.apply(); + PrefManager.setNotificationMotivationAlertTexts(getBaseContext(), new HashSet<>(motivationTexts)); } /** diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/SettingsActivity.java b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/SettingsActivity.java index 92e8e65..bdc0298 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/SettingsActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/SettingsActivity.java @@ -34,6 +34,7 @@ import org.secuso.privacyfriendlycircuittraining.R; import org.secuso.privacyfriendlycircuittraining.fragments.GrantExactAlarmPermissionDialogFragment; import org.secuso.privacyfriendlycircuittraining.helpers.NotificationHelper; +import org.secuso.privacyfriendlycircuittraining.tutorial.PrefManager; import java.util.List; @@ -103,9 +104,9 @@ private static void bindPreferenceSummaryToValue(Preference preference) { // Trigger the listener immediately with the preference's // current value. sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, - PreferenceManager - .getDefaultSharedPreferences(preference.getContext()) + PrefManager.getPreferences(preference.getContext()) .getString(preference.getKey(), "")); + } @Override @@ -248,7 +249,7 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { } //Hotfix since I could not get the intent to launch from XML file - final Preference motivationText = (Preference) findPreference(getString(R.string.pref_notification_motivation_texts)); + final Preference motivationText = (Preference) findPreference(getString(R.string.pref_notification_motivation_alert_texts)); if (motivationText != null) { motivationText.setOnPreferenceClickListener(new OnPreferenceClickListener() { diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/SplashActivity.java b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/SplashActivity.java index d63401f..0c07139 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/SplashActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/SplashActivity.java @@ -36,15 +36,14 @@ public class SplashActivity extends AppCompatActivity { - private PrefManager prefManager; private PFASQLiteHelper db = new PFASQLiteHelper(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - prefManager = new PrefManager(this); - if (prefManager.isFirstTimeLaunch()) { + PrefManager.performMigrations(getBaseContext()); + if (PrefManager.isFirstTimeLaunch(getBaseContext())) { //add two example exercises Uri ic_squat = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.drawable.ic_exercise_squat); diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/WorkoutActivity.java b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/WorkoutActivity.java index 44090a7..02128e5 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/WorkoutActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/activities/WorkoutActivity.java @@ -18,20 +18,15 @@ import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; +import android.content.DialogInterface.OnCancelListener; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; -import android.content.SharedPreferences; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.os.Bundle; import android.os.IBinder; -import android.preference.PreferenceManager; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import androidx.core.content.ContextCompat; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.Toolbar; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; @@ -41,13 +36,18 @@ import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; -import android.content.DialogInterface.OnCancelListener; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; import com.bumptech.glide.Glide; +import com.google.android.material.floatingactionbutton.FloatingActionButton; import org.secuso.privacyfriendlycircuittraining.R; import org.secuso.privacyfriendlycircuittraining.database.PFASQLiteHelper; import org.secuso.privacyfriendlycircuittraining.services.TimerService; +import org.secuso.privacyfriendlycircuittraining.tutorial.PrefManager; import java.util.ArrayList; @@ -61,9 +61,6 @@ */ public class WorkoutActivity extends AppCompatActivity { - //General - private SharedPreferences settings; - // GUI Text private TextView currentSetsInfo = null; private TextView workoutTimer = null; @@ -110,7 +107,6 @@ protected void onCreate(Bundle savedInstanceState) { this.progressBar = (ProgressBar) this.findViewById(R.id.progressBar); this.workoutTimer = (TextView) this.findViewById(R.id.workout_timer); this.workoutTitle = (TextView) this.findViewById(R.id.workout_title); - this.settings = PreferenceManager.getDefaultSharedPreferences(this); this.nextTimer = (ImageView) this.findViewById(R.id.workout_next); this.finishedView = findViewById(R.id.finishedView); this.finishedView.setVisibility(View.GONE); @@ -471,10 +467,10 @@ private void showCancelAlert(final boolean showFinish){ public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) { if (isChecked) { selectedItem.add(indexSelected); - settings.edit().putBoolean(getString(R.string.pref_cancel_workout_check), false).commit(); + PrefManager.setCancelWorkoutCheck(getBaseContext(), false); } else if (selectedItem.contains(indexSelected)) { selectedItem.remove(Integer.valueOf(indexSelected)); - settings.edit().putBoolean(getString(R.string.pref_cancel_workout_check), true).commit(); + PrefManager.setCancelWorkoutCheck(getBaseContext(), true); } } }); @@ -641,55 +637,33 @@ private void cleanTimerServiceFinish(){ * @param mute Flag to mute or unmute all sounds */ private void muteAllSounds(boolean mute){ - if(this.settings != null) { - SharedPreferences.Editor editor = settings.edit(); - editor.putBoolean(getResources().getString(R.string.pref_sounds_muted), mute); - editor.apply(); - } + PrefManager.setSoundsMuted(getBaseContext(), mute); } /* * Multiple checks for what was enabled inside the settings */ public boolean isKeepScreenOnEnabled(Context context){ - if(this.settings != null){ - return settings.getBoolean(context.getString(R.string.pref_keep_screen_on_switch_enabled), true); - } - return false; + return PrefManager.getKeepScreenOnSwitchEnabled(context); } public boolean isStartTimerEnabled(Context context) { - if (this.settings != null) { - return settings.getBoolean(context.getString(R.string.pref_start_timer_switch_enabled), true); - } - return false; + return PrefManager.getStartTimerSwitchEnabled(context); } public boolean isBlinkingProgressBarEnabled(Context context) { - if (this.settings != null) { - return settings.getBoolean(context.getString(R.string.pref_blinking_progress_bar), false); - } - return false; + return PrefManager.getBlinkingProgressBar(context); } public boolean isCaloriesEnabled(Context context) { - if (this.settings != null) { - return settings.getBoolean(context.getString(R.string.pref_calories_counter), true); - } - return false; + return PrefManager.getCaloriesCounter(context); } public boolean isSoundsMuted(Context context) { - if (this.settings != null) { - return settings.getBoolean(context.getString(R.string.pref_sounds_muted), true); - } - return true; + return PrefManager.getSoundsMuted(context); } public boolean isCancelDialogEnabled(Context context) { - if (this.settings != null) { - return settings.getBoolean(context.getString(R.string.pref_cancel_workout_check), true); - } - return true; + return PrefManager.getCancelWorkoutCheck(context); } } diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/backup/BackupCreator.kt b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/backup/BackupCreator.kt index 3771504..392c8a0 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/backup/BackupCreator.kt +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/backup/BackupCreator.kt @@ -1,7 +1,6 @@ package org.secuso.privacyfriendlycircuittraining.backup import android.content.Context -import android.preference.PreferenceManager import android.util.JsonWriter import android.util.Log import org.secuso.privacyfriendlybackup.api.backup.DatabaseUtil.getSupportSQLiteOpenHelper @@ -9,6 +8,7 @@ import org.secuso.privacyfriendlybackup.api.backup.DatabaseUtil.writeDatabase import org.secuso.privacyfriendlybackup.api.backup.PreferenceUtil.writePreferences import org.secuso.privacyfriendlybackup.api.pfa.IBackupCreator import org.secuso.privacyfriendlycircuittraining.database.PFASQLiteHelper +import org.secuso.privacyfriendlycircuittraining.tutorial.PrefManager import java.io.OutputStream import java.io.OutputStreamWriter @@ -33,7 +33,8 @@ class BackupCreator : IBackupCreator { Log.d(TAG, "Writing preferences") writer.name("preferences") - val pref = PreferenceManager.getDefaultSharedPreferences(context.applicationContext) + PrefManager.performMigrations(context) + val pref = PrefManager.getPreferences(context) writePreferences(writer, pref) writer.endObject() diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/backup/BackupRestorer.kt b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/backup/BackupRestorer.kt index c5d0c40..c475361 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/backup/BackupRestorer.kt +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/backup/BackupRestorer.kt @@ -2,14 +2,14 @@ package org.secuso.privacyfriendlycircuittraining.backup import android.content.Context import android.content.SharedPreferences -import android.preference.PreferenceManager import android.util.JsonReader import android.util.Log -import androidx.annotation.NonNull import org.secuso.privacyfriendlybackup.api.backup.DatabaseUtil import org.secuso.privacyfriendlybackup.api.backup.FileUtil import org.secuso.privacyfriendlybackup.api.pfa.IBackupRestorer +import org.secuso.privacyfriendlycircuittraining.R import org.secuso.privacyfriendlycircuittraining.database.PFASQLiteHelper +import org.secuso.privacyfriendlycircuittraining.tutorial.PrefManager import java.io.IOException import java.io.InputStream import java.io.InputStreamReader @@ -59,40 +59,52 @@ class BackupRestorer : IBackupRestorer { DatabaseUtil.deleteRoomDatabase(context, PFASQLiteHelper.DATABASE_NAME) FileUtil.copyFile(restoreDatabaseFile, actualDatabaseFile) - Log.d(TAG, "Database Restored") + Log.d(TAG, "Database restored") // delete restore database DatabaseUtil.deleteRoomDatabase(context, restoreDatabaseName) } @Throws(IOException::class) - private fun readPreferences(reader: JsonReader, preferences: SharedPreferences.Editor) { + private fun readPreferences(reader: JsonReader, preferences: SharedPreferences.Editor, context: Context) { reader.beginObject() + Log.d(TAG, "Restoring preferences...") while (reader.hasNext()) { - val name: String = reader.nextName() - when (name) { - "workoutMode", - "org.secuso.privacyfriendlytraining.pref_start_timer_switch_enabled", - "org.secuso.privacyfriendlytraining.pref.motivation_alert_enabled", - "org.secuso.privacyfriendlytraining.pref.calories", - "org.secuso.privacyfriendlytraining.pref.voicecountdownworkout", - "org.secuso.privacyfriendlytraining.pref.voicecountdownrest", - "Blinking progress bar", - "org.secuso.privacyfriendlytraining.pref.cancel_workout_check", - "org.secuso.privacyfriendlytraining.pref.soundrythm", - "org.secuso.privacyfriendlytraining.pref.voicehalftime", - "org.secuso.privacyfriendlytraining.pref_keep_screen_on_switch_enabled" -> preferences.putBoolean(name, reader.nextBoolean()) - "org.secuso.privacyfriendlytraining.pref.weight", - "org.secuso.privacyfriendlytraining.pref.gender", - "org.secuso.privacyfriendlytraining.pref.age", - "org.secuso.privacyfriendlytraining.pref.height" -> preferences.putString(name, reader.nextString()) - "org.secuso.privacyfriendlytraining.pref.timer_set" -> preferences.putInt(name, reader.nextInt()) - "org.secuso.privacyfriendlytraining.pref.motivation_alert_time" -> preferences.putLong(name, reader.nextLong()) - "Motivation texts" -> preferences.putStringSet(name, readPreferenceSet(reader)) + when (val name: String = reader.nextName()) { + context.getString(R.string.pref_is_first_time_launch), + context.getString(R.string.pref_workout_mode), + context.getString(R.string.pref_blinking_progress_bar), + context.getString(R.string.pref_block_periodization_switch_button), + context.getString(R.string.pref_keep_screen_on_switch_enabled), + context.getString(R.string.pref_start_timer_switch_enabled), + context.getString(R.string.pref_calories_counter), + context.getString(R.string.pref_sounds_muted), + context.getString(R.string.pref_cancel_workout_dialog), + context.getString(R.string.pref_notification_motivation_alert_enabled), + context.getString(R.string.pref_voice_countdown_workout), + context.getString(R.string.pref_voice_countdown_rest), + context.getString(R.string.pref_sound_rythm), + context.getString(R.string.pref_voice_halftime), + context.getString(R.string.pref_cancel_workout_check) -> preferences.putBoolean(name, reader.nextBoolean()) + context.getString(R.string.pref_age), + context.getString(R.string.pref_height), + context.getString(R.string.pref_weight), + context.getString(R.string.pref_gender) -> preferences.putString(name, reader.nextString()) + + context.getString(R.string.pref_timer_workout), + context.getString(R.string.pref_timer_rest), + context.getString(R.string.pref_timer_set), + context.getString(R.string.pref_timer_periodization_set), + context.getString(R.string.pref_timer_periodization_time) -> preferences.putInt(name, reader.nextInt()) + + context.getString(R.string.pref_notification_motivation_alert_time) -> preferences.putLong(name, reader.nextLong()) + + context.getString(R.string.pref_notification_motivation_alert_texts) -> preferences.putStringSet(name, readPreferenceSet(reader)) else -> throw RuntimeException("Unknown preference $name") } } reader.endObject() + Log.d(TAG, "Preferences restored") } private fun readPreferenceSet(reader: JsonReader): Set { @@ -100,7 +112,7 @@ class BackupRestorer : IBackupRestorer { reader.beginArray() while (reader.hasNext()) { - preferenceSet.add(reader.nextString()); + preferenceSet.add(reader.nextString()) } reader.endArray() return preferenceSet @@ -110,15 +122,14 @@ class BackupRestorer : IBackupRestorer { return try { val isReader = InputStreamReader(restoreData) val reader = JsonReader(isReader) - val preferences = PreferenceManager.getDefaultSharedPreferences(context).edit() + val preferences = PrefManager.getPreferences(context).edit() // START reader.beginObject() while (reader.hasNext()) { - val type: String = reader.nextName() - when (type) { + when (val type: String = reader.nextName()) { "database" -> readDatabase(reader, context) - "preferences" -> readPreferences(reader, preferences) + "preferences" -> readPreferences(reader, preferences, context) else -> throw RuntimeException("Can not parse type $type") } } diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/helpers/NotificationHelper.java b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/helpers/NotificationHelper.java index 204d64b..938cbde 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/helpers/NotificationHelper.java +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/helpers/NotificationHelper.java @@ -14,23 +14,20 @@ package org.secuso.privacyfriendlycircuittraining.helpers; +import static org.secuso.privacyfriendlycircuittraining.activities.MotivationAlertTextsActivity.LOG_CLASS; + import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Build; -import android.preference.PreferenceManager; -import android.provider.Settings; import android.util.Log; -import org.secuso.privacyfriendlycircuittraining.R; import org.secuso.privacyfriendlycircuittraining.receivers.MotivationAlertReceiver; +import org.secuso.privacyfriendlycircuittraining.tutorial.PrefManager; import java.util.Calendar; -import static org.secuso.privacyfriendlycircuittraining.activities.MotivationAlertTextsActivity.LOG_CLASS; - /** * Sets the motivation alert event to notify the user about a workout. * @@ -52,9 +49,7 @@ public static void setMotivationAlert(Context context) { PendingIntent motivationAlertPendingIntent = PendingIntent.getBroadcast(context, 1, motivationAlertIntent, PendingIntent.FLAG_IMMUTABLE); AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); - - long timestamp = sharedPref.getLong(context.getString(R.string.pref_notification_motivation_alert_time), 64800000); + long timestamp = PrefManager.getNotificationMotivationAlertTime(context); Calendar calendar = Calendar.getInstance(); @@ -91,12 +86,7 @@ public static void setMotivationAlert(Context context) { * @param context The application context */ public static boolean isMotivationAlertEnabled(Context context) { - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); - - if (sharedPref != null) { - return sharedPref.getBoolean(context.getString(R.string.pref_notification_motivation_alert_enabled), false); - } - return false; + return PrefManager.getNotificationMotivationAlertEnabled(context); } /** diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/receivers/MotivationAlertReceiver.java b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/receivers/MotivationAlertReceiver.java index d2046d2..e68f703 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/receivers/MotivationAlertReceiver.java +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/receivers/MotivationAlertReceiver.java @@ -14,31 +14,28 @@ package org.secuso.privacyfriendlycircuittraining.receivers; +import static org.secuso.privacyfriendlycircuittraining.activities.MotivationAlertTextsActivity.LOG_CLASS; + import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Build; -import android.preference.PreferenceManager; +import android.util.Log; + import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; import androidx.legacy.content.WakefulBroadcastReceiver; -import android.util.Log; import org.secuso.privacyfriendlycircuittraining.R; import org.secuso.privacyfriendlycircuittraining.activities.MainActivity; import org.secuso.privacyfriendlycircuittraining.helpers.NotificationHelper; +import org.secuso.privacyfriendlycircuittraining.tutorial.PrefManager; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Set; - -import static org.secuso.privacyfriendlycircuittraining.activities.MotivationAlertTextsActivity.LOG_CLASS; /** * Receives the motivation alert event and notifies the user. @@ -66,11 +63,8 @@ public void onReceive(Context context, Intent intent) { private void motivate(Context context) { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - //Choose a motivation text - Set defaultStringSet = new HashSet<>(Arrays.asList(context.getResources().getStringArray(R.array.pref_default_notification_motivation_alert_messages))); - List motivationTexts = new ArrayList<>(preferences.getStringSet(context.getString(R.string.pref_notification_motivation_alert_texts), defaultStringSet)); + List motivationTexts = new ArrayList<>(PrefManager.getNotificationMotivationAlertTexts(context)); if (motivationTexts.size() == 0) { Log.e(LOG_CLASS, "Motivation texts are empty. Cannot notify the user."); diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/services/TimerService.java b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/services/TimerService.java index cd73b5c..1e56a50 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/services/TimerService.java +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/services/TimerService.java @@ -22,20 +22,20 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.SharedPreferences; import android.media.MediaPlayer; import android.os.Binder; import android.os.CountDownTimer; import android.os.Handler; import android.os.IBinder; -import android.preference.PreferenceManager; -import androidx.core.app.NotificationCompat; import android.widget.RemoteViews; +import androidx.core.app.NotificationCompat; + import org.secuso.privacyfriendlycircuittraining.R; import org.secuso.privacyfriendlycircuittraining.activities.WorkoutActivity; import org.secuso.privacyfriendlycircuittraining.database.PFASQLiteHelper; import org.secuso.privacyfriendlycircuittraining.models.WorkoutSessionData; +import org.secuso.privacyfriendlycircuittraining.tutorial.PrefManager; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -53,9 +53,6 @@ */ public class TimerService extends Service { - //General - private SharedPreferences settings; - //Broadcast action identifier for the broadcasted service messages public static final String COUNTDOWN_BROADCAST = "org.secuso.privacyfriendlytraining.COUNTDOWN"; public static final String NOTIFICATION_BROADCAST = "org.secuso.privacyfriendlytraining.NOTIFICATION"; @@ -117,7 +114,6 @@ public void onCreate() { this.restTimer = createRestTimer(this.startTime); this.workoutTimer = createWorkoutTimer(this.workoutTime); - this.settings = PreferenceManager.getDefaultSharedPreferences(this); registerReceiver(notificationReceiver, new IntentFilter(NOTIFICATION_BROADCAST)); @@ -680,13 +676,11 @@ private int calculateUserCalories(float workoutDurationSeconds){ int weight = 0; int circleTrainingMET = 8; - if(this.settings != null) { - age = Integer.parseInt(settings.getString(this.getString(R.string.pref_age), "25")); - height = Integer.parseInt(settings.getString(this.getString(R.string.pref_height), "170")); - weight = (int)Double.parseDouble(settings.getString(this.getString(R.string.pref_weight), "70")); - } + age = Integer.parseInt(PrefManager.getAge(getBaseContext())); + height = Integer.parseInt(PrefManager.getHeight(getBaseContext())); + weight = (int) Double.parseDouble(PrefManager.getWeight(getBaseContext())); - float caloriesPerExercise = circleTrainingMET * (weight * workoutDurationSeconds/3600); + float caloriesPerExercise = circleTrainingMET * (weight * workoutDurationSeconds / 3600); return (int) caloriesPerExercise; } @@ -850,45 +844,27 @@ private void saveStatistics(){ * Multiple checks for what was enabled inside the settings */ public boolean isVoiceCountdownWorkoutEnabled(Context context){ - if(this.settings != null){ - return settings.getBoolean(context.getString(R.string.pref_voice_countdown_workout), false); - } - return false; + return PrefManager.getVoiceCountdownWorkout(context); } public boolean isVoiceCountdownRestEnabled(Context context){ - if(this.settings != null){ - return settings.getBoolean(context.getString(R.string.pref_voice_countdown_rest), false); - } - return false; + return PrefManager.getVoiceCountdownRest(context); } public boolean isWorkoutRythmEnabled(Context context){ - if(this.settings != null){ - return settings.getBoolean(context.getString(R.string.pref_sound_rythm), false); - } - return false; + return PrefManager.getSoundRythm(context); } public boolean isVoiceHalfTimeEnabled(Context context){ - if(this.settings != null){ - return settings.getBoolean(context.getString(R.string.pref_voice_halftime), false); - } - return false; + return PrefManager.getVoiceHalftime(context); } public boolean isCaloriesEnabled(Context context) { - if (this.settings != null) { - return settings.getBoolean(context.getString(R.string.pref_calories_counter), false); - } - return false; + return PrefManager.getCaloriesCounter(context); } public boolean isSoundsMuted(Context context) { - if (this.settings != null) { - return settings.getBoolean(context.getString(R.string.pref_sounds_muted), true); - } - return true; + return PrefManager.getSoundsMuted(context); } diff --git a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/tutorial/PrefManager.java b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/tutorial/PrefManager.java index be874f2..a1c9e41 100644 --- a/app/src/main/java/org/secuso/privacyfriendlycircuittraining/tutorial/PrefManager.java +++ b/app/src/main/java/org/secuso/privacyfriendlycircuittraining/tutorial/PrefManager.java @@ -17,34 +17,240 @@ import android.content.Context; import android.content.SharedPreferences; +import androidx.annotation.NonNull; + +import org.secuso.privacyfriendlycircuittraining.R; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.function.BiFunction; + /** * Class structure taken from tutorial at http://www.androidhive.info/2016/05/android-build-intro-slider-app/ */ public class PrefManager { - private SharedPreferences pref; - private SharedPreferences.Editor editor; + public static final int PREFERENCE_MODE = Context.MODE_PRIVATE; - // shared pref mode - private int PRIVATE_MODE = 0; + // Default values for the timers + private static final int workoutTimeDefault = 60; + private static final int restTimeDefault = 30; + public static final int setsDefault = 6; + private static final int blockPeriodizationTimeDefault = 90; + private static final int blockPeriodizationSetsDefault = 1; - // Shared preferences file name - private static final String PREF_NAME = "androidhive-welcome"; + public PrefManager(Context context) { + } - private static final String IS_FIRST_TIME_LAUNCH = "IsFirstTimeLaunch"; + public static void performMigrations(Context context) { + migratePreferences(context); + } - public PrefManager(Context context) { - pref = context.getSharedPreferences(PREF_NAME, PRIVATE_MODE); - editor = pref.edit(); + /** + * Migrate Preferences from app version <= v1.1 + * + * @param context + */ + private static void migratePreferences(Context context) { + // pre v1.1 attributes + int PRIVATE_MODE = 0; + + final String PREF_NAME = "androidhive-welcome"; + final String IS_FIRST_TIME_LAUNCH = "IsFirstTimeLaunch"; + + SharedPreferences prefs = getPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + + //migrate firstTimeLaunch + if (context.getSharedPreferences(PREF_NAME, PRIVATE_MODE).contains(IS_FIRST_TIME_LAUNCH)) { + setFirstTimeLaunch(context, context.getSharedPreferences(PREF_NAME, PRIVATE_MODE).getBoolean(IS_FIRST_TIME_LAUNCH, true)); + context.getSharedPreferences(PREF_NAME, PRIVATE_MODE).edit().remove(IS_FIRST_TIME_LAUNCH).apply(); + } + + //migrate translated preferences + + if (prefs.contains("Fortschrittsbalken blinkt")) { + editor.putBoolean(context.getString(R.string.pref_blinking_progress_bar), prefs.getBoolean("Fortschrittsbalken blinkt", false)); + editor.remove("Fortschrittsbalken blinkt"); + } + if (prefs.contains("Blinking progress bar")) { + editor.putBoolean(context.getString(R.string.pref_blinking_progress_bar), prefs.getBoolean("Blinking progress bar", false)); + editor.remove("Blinking progress bar"); + } + + if (prefs.contains("Motivationstexte")) { + Set defaultStringSet = new HashSet<>(Arrays.asList(context.getResources().getStringArray(R.array.pref_default_notification_motivation_alert_messages))); + editor.putStringSet(context.getString(R.string.pref_notification_motivation_alert_texts), prefs.getStringSet("Motivationstexte", defaultStringSet)); + editor.remove("Motivationstexte"); + } + + if (prefs.contains("Motivation texts")) { + Set defaultStringSet = new HashSet<>(Arrays.asList(context.getResources().getStringArray(R.array.pref_default_notification_motivation_alert_messages))); + editor.putStringSet(context.getString(R.string.pref_notification_motivation_alert_texts), prefs.getStringSet("Motivation texts", defaultStringSet)); + editor.remove("Motivation texts"); + } + + editor.apply(); + } + + /** + * Only use this method to access the SharedPreferences object. + * To access the preference values use the corresponding getter/setter functions of this class. + * + * @param context + * @return the default SharedPreferences for this app + */ + public static SharedPreferences getPreferences(@NonNull Context context) { + return context.getSharedPreferences(context.getString(R.string.preference_file_name), PREFERENCE_MODE); + } + + private static SharedPreferences.Editor getEditor(Context context) { + return getPreferences(context).edit(); + } + + public static void setFirstTimeLaunch(Context context, boolean value) { + getEditor(context).putBoolean(context.getString(R.string.pref_is_first_time_launch), value).apply(); + } + + public static void setBlockPeriodizationSwitchButton(Context context, boolean value) { + getEditor(context).putBoolean(context.getString(R.string.pref_block_periodization_switch_button), value).apply(); + } + + public static void setWorkoutMode(Context context, boolean value) { + getEditor(context).putBoolean(context.getString(R.string.pref_workout_mode), value).apply(); + } + + public static void setCancelWorkoutCheck(Context context, boolean value) { + getEditor(context).putBoolean(context.getString(R.string.pref_cancel_workout_check), value).apply(); + } + + public static void setSoundsMuted(Context context, boolean value) { + getEditor(context).putBoolean(context.getString(R.string.pref_sounds_muted), value).apply(); + } + + public static void setKeepScreenOnSwitchEnabled(Context context, boolean value) { + getEditor(context).putBoolean(context.getString(R.string.pref_keep_screen_on_switch_enabled), value).apply(); + } + + public static void setTimerWorkout(Context context, int value) { + getEditor(context).putInt(context.getString(R.string.pref_timer_workout), value).apply(); + } + + public static void setTimerRest(Context context, int value) { + getEditor(context).putInt(context.getString(R.string.pref_timer_rest), value).apply(); + } + + public static void setTimerSet(Context context, int value) { + getEditor(context).putInt(context.getString(R.string.pref_timer_set), value).apply(); + } + + public static void setTimerPeriodizationSet(Context context, int value) { + getEditor(context).putInt(context.getString(R.string.pref_timer_periodization_set), value).apply(); + } + + public static void setTimerPeriodizationTime(Context context, int value) { + getEditor(context).putInt(context.getString(R.string.pref_timer_periodization_time), value).apply(); + } + + public static void setNotificationMotivationAlertTexts(Context context, Set value) { + getEditor(context).putStringSet(context.getString(R.string.pref_notification_motivation_alert_texts), value).apply(); } - public void setFirstTimeLaunch(boolean isFirstTime) { - editor.putBoolean(IS_FIRST_TIME_LAUNCH, isFirstTime); - editor.commit(); + public static boolean isFirstTimeLaunch(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_is_first_time_launch), true); } - public boolean isFirstTimeLaunch() { - return pref.getBoolean(IS_FIRST_TIME_LAUNCH, true); + public static boolean getBlockPeriodizationSwitchButton(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_block_periodization_switch_button), false); } + public static boolean getWorkoutMode(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_workout_mode), false); + } + + public static boolean getKeepScreenOnSwitchEnabled(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_keep_screen_on_switch_enabled), true); + } + + public static boolean getStartTimerSwitchEnabled(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_start_timer_switch_enabled), true); + } + + public static boolean getBlinkingProgressBar(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_blinking_progress_bar), false); + } + + public static boolean getCaloriesCounter(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_calories_counter), true); + } + + public static boolean getSoundsMuted(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_sounds_muted), true); + } + + public static boolean getCancelWorkoutCheck(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_cancel_workout_check), true); + } + + public static boolean getNotificationMotivationAlertEnabled(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_notification_motivation_alert_enabled), false); + } + + public static boolean getVoiceCountdownWorkout(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_voice_countdown_workout), false); + } + + public static boolean getVoiceCountdownRest(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_voice_countdown_rest), false); + } + + public static boolean getSoundRythm(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_sound_rythm), false); + } + + public static boolean getVoiceHalftime(Context context) { + return getPreferences(context).getBoolean(context.getString(R.string.pref_voice_halftime), false); + } + + public static int getTimerWorkout(Context context) { + return getPreferences(context).getInt(context.getString(R.string.pref_timer_workout), workoutTimeDefault); + } + + public static int getTimerRest(Context context) { + return getPreferences(context).getInt(context.getString(R.string.pref_timer_rest), restTimeDefault); + } + + public static int getTimerSet(Context context) { + return getPreferences(context).getInt(context.getString(R.string.pref_timer_set), setsDefault); + } + + public static int getTimerPeriodizationSet(Context context) { + return getPreferences(context).getInt(context.getString(R.string.pref_timer_periodization_set), blockPeriodizationSetsDefault); + } + + public static int getTimerPeriodizationTime(Context context) { + return getPreferences(context).getInt(context.getString(R.string.pref_timer_periodization_time), blockPeriodizationTimeDefault); + } + + public static long getNotificationMotivationAlertTime(Context context) { + return getPreferences(context).getLong(context.getString(R.string.pref_notification_motivation_alert_time), 64800000); + } + + public static String getAge(Context context) { + return getPreferences(context).getString(context.getString(R.string.pref_age), "25"); + } + + public static String getHeight(Context context) { + return getPreferences(context).getString(context.getString(R.string.pref_height), "170"); + } + + public static String getWeight(Context context) { + return getPreferences(context).getString(context.getString(R.string.pref_weight), "70"); + } + + public static Set getNotificationMotivationAlertTexts(Context context) { + Set defaultStringSet = new HashSet<>(Arrays.asList(context.getResources().getStringArray(R.array.pref_default_notification_motivation_alert_messages))); + return getPreferences(context).getStringSet(context.getString(R.string.pref_notification_motivation_alert_texts), defaultStringSet); + } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f07311d..71f506b 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -126,7 +126,7 @@ Der Bildschrim bleibt während des Trainings an. Starttimer vor Training Vor dem Beginn des Trainings wird ein Starttimer angezeigt. - Fortschrittsbalken blinkt + Fortschrittsbalken blinkt Der Fortschrittsbalken der Zeitanzeige im Training blinkt während den letzten Sekunden. Sprachausgabe Eine Stimme zählt die letzten Sekunden jeder Trainingseinheit und Pause herunter. @@ -134,7 +134,7 @@ Statistiken Zeitpunkt der Motivationsbenachrichtigung Statistiken löschen - Motivationstexte + Motivationstexte Statistiken löschen Wollen Sie alle gespeicherten Statistiken löschen? Die Statistiken wurden zurückgesetzt! diff --git a/app/src/main/res/values/preference_keys.xml b/app/src/main/res/values/preference_keys.xml new file mode 100644 index 0000000..9a29b5a --- /dev/null +++ b/app/src/main/res/values/preference_keys.xml @@ -0,0 +1,53 @@ + + + + org.secuso.privacyfriendlycircuittraining_preferences + + + + + + IsFirstTimeLaunch + workoutMode + org.secuso.privacyfriendlytraining.pref_blinking_progress_bar + blockPeriodizationSwitchButton + org.secuso.privacyfriendlytraining.pref_keep_screen_on_switch_enabled + org.secuso.privacyfriendlytraining.pref_start_timer_switch_enabled + org.secuso.privacyfriendlytraining.pref.calories + org.secuso.privacyfriendlytraining.pref.sounds_muted + org.secuso.privacyfriendlytraining.pref_cancel_workout_dialog + org.secuso.privacyfriendlytraining.pref.motivation_alert_enabled + org.secuso.privacyfriendlytraining.pref.voicecountdownworkout + org.secuso.privacyfriendlytraining.pref.voicecountdownrest + org.secuso.privacyfriendlytraining.pref.soundrythm + org.secuso.privacyfriendlytraining.pref.voicehalftime + org.secuso.privacyfriendlytraining.pref.cancel_workout_check + + + + org.secuso.privacyfriendlytraining.pref.timer_workout + org.secuso.privacyfriendlytraining.pref.timer_rest + org.secuso.privacyfriendlytraining.pref.timer_set + org.secuso.privacyfriendlytraining.pref.timer_periodization_set + org.secuso.privacyfriendlytraining.pref.timer_periodization_time + + + + org.secuso.privacyfriendlytraining.pref.motivation_alert_time + + + + org.secuso.privacyfriendlytraining.pref.age + org.secuso.privacyfriendlytraining.pref.height + org.secuso.privacyfriendlytraining.pref.weight + org.secuso.privacyfriendlytraining.pref.gender + + + + org.secuso.privacyfriendlytraining.pref.motivation_texts + + + + org.secuso.privacyfriendlytraining.pref.delete_dialog + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index baa52be..81ec1f9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -126,12 +126,12 @@ The Screen remains turned on during the workout. Start timer A start timer is shown before the workout begins. - Blinking progress bar + Blinking progress bar The progress bar of the workout timer blinks during the final seconds. Voice Output A voice counts down the final seconds of each workout and rest phase. Motivation alert - Motivation texts + Motivation texts Motivation alert texts Statistics Delete statistics @@ -151,31 +151,6 @@ male - - org.secuso.privacyfriendlytraining.pref_cancel_workout_dialog - org.secuso.privacyfriendlytraining.pref_keep_screen_on_switch_enabled - org.secuso.privacyfriendlytraining.pref_start_timer_switch_enabled - org.secuso.privacyfriendlytraining.pref.motivation_alert_enabled - org.secuso.privacyfriendlytraining.pref.motivation_alert_time - org.secuso.privacyfriendlytraining.pref.motivation_alert_time - org.secuso.privacyfriendlytraining.pref.motivation_texts - org.secuso.privacyfriendlytraining.pref.delete_dialog - org.secuso.privacyfriendlytraining.pref.weight - org.secuso.privacyfriendlytraining.pref.height - org.secuso.privacyfriendlytraining.pref.age - org.secuso.privacyfriendlytraining.pref.gender - org.secuso.privacyfriendlytraining.pref.calories - org.secuso.privacyfriendlytraining.pref.voicecountdownworkout - org.secuso.privacyfriendlytraining.pref.voicecountdownrest - org.secuso.privacyfriendlytraining.pref.soundrythm - org.secuso.privacyfriendlytraining.pref.voicehalftime - org.secuso.privacyfriendlytraining.pref.cancel_workout_check - org.secuso.privacyfriendlytraining.pref.sounds_muted - org.secuso.privacyfriendlytraining.pref.timer_workout - org.secuso.privacyfriendlytraining.pref.timer_rest - org.secuso.privacyfriendlytraining.pref.timer_set - org.secuso.privacyfriendlytraining.pref.timer_periodization_time - org.secuso.privacyfriendlytraining.pref.timer_periodization_set 70.0 25 170 diff --git a/app/src/main/res/xml/pref_notification.xml b/app/src/main/res/xml/pref_notification.xml index b16efa3..399c04c 100644 --- a/app/src/main/res/xml/pref_notification.xml +++ b/app/src/main/res/xml/pref_notification.xml @@ -12,8 +12,8 @@ android:title="@string/pref_title_notification_motivation_alert_time" /> + android:title="@string/pref_notification_motivation_alert_texts_title" + android:key="@string/pref_notification_motivation_alert_texts">