diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5cf9a2d..db8df51 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -69,10 +69,10 @@
android:theme="@style/SplashTheme">
+
-
@@ -86,7 +86,6 @@
android:name=".activities.TimerActivity"
android:label="@string/activity_title_break_reminder"
android:theme="@style/AppTheme.NoActionBar" />
-
-
-
+
+ >
+
+
\ No newline at end of file
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/AboutActivity.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/AboutActivity.java
index d50d10e..099f31b 100644
--- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/AboutActivity.java
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/AboutActivity.java
@@ -35,9 +35,9 @@ public class AboutActivity extends AppCompatActivity {
private void setupActionBar() {
ActionBar actionBar = getSupportActionBar();
- actionBar.setTitle(R.string.about);
if (actionBar != null) {
// Show the Up button in the action bar.
+ actionBar.setTitle(R.string.about);
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/ChooseExerciseActivity.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/ChooseExerciseActivity.java
new file mode 100644
index 0000000..f2a19d5
--- /dev/null
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/ChooseExerciseActivity.java
@@ -0,0 +1,122 @@
+package org.secuso.privacyfriendlybreakreminder.activities;
+
+import android.content.Intent;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.support.v7.util.SortedList;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ImageView;
+
+import org.secuso.privacyfriendlybreakreminder.R;
+import org.secuso.privacyfriendlybreakreminder.activities.adapter.ExerciseAdapter;
+import org.secuso.privacyfriendlybreakreminder.activities.layout.FlowLayout;
+import org.secuso.privacyfriendlybreakreminder.database.SQLiteHelper;
+import org.secuso.privacyfriendlybreakreminder.database.data.Exercise;
+import org.secuso.privacyfriendlybreakreminder.exercises.ExerciseLocale;
+import org.secuso.privacyfriendlybreakreminder.exercises.ExerciseSections;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import static org.secuso.privacyfriendlybreakreminder.activities.adapter.ExerciseAdapter.ID_COMPARATOR;
+
+public class ChooseExerciseActivity extends AppCompatActivity {
+
+ private static final String TAG = ChooseExerciseActivity.class.getSimpleName();
+
+ public static final String EXTRA_SELECTED_EXERCISES = TAG+".EXTRA_SELECTED_EXERCISES";
+
+ FlowLayout filterButtonLayout;
+ RecyclerView exerciseList;
+
+ ExerciseAdapter exerciseAdapter;
+ SQLiteHelper databaseHelper;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_choose_exercise);
+
+ initResources();
+
+ ActionBar ab = getSupportActionBar();
+ if(ab != null) {
+ ab.setDisplayHomeAsUpEnabled(true);
+ }
+
+ int[] chosenExercises = getIntent().getIntArrayExtra(EXTRA_SELECTED_EXERCISES);
+ List chosenExercisesList = new ArrayList<>();
+
+ for(int i : chosenExercises) chosenExercisesList.add(i);
+
+ exerciseAdapter.add(databaseHelper.getExerciseList(ExerciseLocale.getLocale()));
+ exerciseAdapter.setCheckedItems(chosenExercisesList);
+ }
+
+ private void initResources() {
+ databaseHelper = new SQLiteHelper(this);
+
+ filterButtonLayout = (FlowLayout) findViewById(R.id.layout_filter_buttons);
+ exerciseList = (RecyclerView) findViewById(R.id.exercise_list);
+ exerciseAdapter = new ExerciseAdapter(this, ID_COMPARATOR);
+ exerciseAdapter.showCheckboxes(true);
+
+ GridLayoutManager gridLayout = new GridLayoutManager(this, 3);
+ exerciseList.setLayoutManager(gridLayout);
+ exerciseList.setAdapter(exerciseAdapter);
+
+ filterButtonLayout.removeAllViews();
+
+ for(ExerciseSections section : ExerciseSections.getSectionList()) {
+ // TODO: Add Buttons for every section we have
+ //View view = LayoutInflater.from(this).inflate(R.layout.layout_section_filter_button, null, false);
+ //TextView image = (TextView) view.findViewById(R.id.button_text);
+ //filterButtonLayout.addView(view);
+ }
+ }
+
+ public void onClick(View v) {
+
+ // TODO get onclicklistener to call this method so we can filter the list
+ //exerciseAdapter.replaceAll(databaseHelper.getExerciseListBySections());
+ exerciseList.scrollToPosition(0);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void onBackPressed() {
+ sendDataBack();
+ super.onBackPressed();
+ }
+
+ private void sendDataBack() {
+ Intent result = new Intent();
+
+ List selectedIdList = exerciseAdapter.getCheckedIds();
+ int[] selectedIds = new int[selectedIdList.size()];
+
+ for(int i = 0; i < selectedIds.length; ++i) {
+ selectedIds[i] = selectedIdList.get(i);
+ }
+
+ result.putExtra(EXTRA_SELECTED_EXERCISES, selectedIds);
+ setResult(RESULT_OK, result);
+ }
+}
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/EditExerciseSetActivity.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/EditExerciseSetActivity.java
index d959f26..41ed9e5 100644
--- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/EditExerciseSetActivity.java
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/EditExerciseSetActivity.java
@@ -23,32 +23,43 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
+import android.widget.Toast;
-import org.secuso.privacyfriendlybreakreminder.ExerciseLocale;
+import org.secuso.privacyfriendlybreakreminder.activities.adapter.ExerciseAdapter;
+import org.secuso.privacyfriendlybreakreminder.database.data.Exercise;
+import org.secuso.privacyfriendlybreakreminder.exercises.ExerciseLocale;
import org.secuso.privacyfriendlybreakreminder.R;
-import org.secuso.privacyfriendlybreakreminder.activities.adapter.ExerciseSetAdapter;
import org.secuso.privacyfriendlybreakreminder.database.SQLiteHelper;
import org.secuso.privacyfriendlybreakreminder.database.data.ExerciseSet;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.secuso.privacyfriendlybreakreminder.activities.adapter.ExerciseAdapter.ID_COMPARATOR;
+
public class EditExerciseSetActivity extends AppCompatActivity implements android.support.v4.app.LoaderManager.LoaderCallbacks {
// extras
public static final String EXTRA_EXERCISE_SET_ID = "EXTRA_EXERCISE_SET_ID";
public static final String EXTRA_EXERCISE_SET_NAME = "EXTRA_EXERCISE_SET_NAME";
+ private static final int PICK_EXERCISE_REQUEST = 1; // The request code
+
// UI
private TextView exerciseSetNameText;
private RecyclerView exerciseList;
private ProgressBar loadingSpinner;
- private ExerciseSetAdapter exerciseSetAdapter;
+ private ExerciseAdapter mAdapter;
private ActionBar actionBar;
private Toolbar toolbar;
// exercise set information
private long exerciseSetId = -1L;
private String exerciseSetName = "";
+ private boolean nameChanged = false;
private boolean modificationsDone = false;
+ private SQLiteHelper mDbHelper;
//methods
@@ -72,13 +83,13 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
}
private void initResources() {
+ mDbHelper = new SQLiteHelper(this);
toolbar = (Toolbar) findViewById(R.id.toolbar);
exerciseSetNameText = (TextView) findViewById(R.id.exercise_set_name);
exerciseList = (RecyclerView) findViewById(R.id.exercise_list);
- exerciseSetAdapter = new ExerciseSetAdapter(this, null);
- exerciseList.setAdapter(exerciseSetAdapter);
- //exerciseList.setLayoutManager(new GridLayoutManager(this, 2));
- exerciseList.setLayoutManager(new LinearLayoutManager(this));
+ mAdapter = new ExerciseAdapter(this, ID_COMPARATOR);
+ exerciseList.setAdapter(mAdapter);
+ exerciseList.setLayoutManager(new GridLayoutManager(this, 3));
loadingSpinner = (ProgressBar) findViewById(R.id.loading_spinner);
exerciseSetNameText.setText(exerciseSetName);
@@ -91,7 +102,7 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
@Override
public void afterTextChanged(Editable editable) {
- modificationsDone = true;
+ nameChanged = true;
}
});
@@ -117,9 +128,7 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
return new AsyncTaskLoader(this) {
@Override
public ExerciseSet loadInBackground() {
- SQLiteHelper helper = new SQLiteHelper(getContext());
-
- return helper.getExerciseListForSet((int)exerciseSetId, ExerciseLocale.getLocale());
+ return mDbHelper.getExerciseListForSet((int)exerciseSetId, ExerciseLocale.getLocale());
}
@Override
@@ -142,7 +151,12 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
}
});
- exerciseSetAdapter.updateData(set);
+ if(set != null) {
+ mAdapter.replaceAll(set.getExercises());
+ }
+
+ // load data only once
+ getSupportLoaderManager().destroyLoader(0);
}
@Override
@@ -159,22 +173,40 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
- if(modificationsDone) {
+ if(modificationsDone()) {
showDiscardDialog();
} else {
super.onBackPressed();
}
return true;
case R.id.save:
- saveChanges();
- super.onBackPressed();
+ if(TextUtils.getTrimmedLength(exerciseSetNameText.getText()) == 0) {
+ Toast.makeText(this, R.string.activity_edit_no_empty_name, Toast.LENGTH_SHORT).show();
+ } else {
+ saveChanges();
+ super.onBackPressed();
+ }
return true;
}
return super.onOptionsItemSelected(item);
}
private void saveChanges() {
- ExerciseSet set = exerciseSetAdapter.getExerciseSet();
+ List set = mAdapter.getExercises();
+
+ if(modificationsDone) {
+ mDbHelper.clearExercisesFromSet((int) exerciseSetId);
+
+ for (Exercise e : set) {
+ mDbHelper.addExerciseToExerciseSet((int) exerciseSetId, e.getId());
+ }
+ }
+ if(nameChanged) {
+ ExerciseSet exerciseSet = new ExerciseSet();
+ exerciseSet.setId(exerciseSetId);
+ exerciseSet.setName(exerciseSetNameText.getText().toString());
+ mDbHelper.updateExerciseSet(exerciseSet);
+ }
// TODO: save changes to database
// man könnte den unterschied, der gespeichert werden muss rausfinden, indem man nur die änderungen speichert..
@@ -191,13 +223,17 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
@Override
public void onBackPressed() {
- if(modificationsDone) {
+ if(modificationsDone()) {
showDiscardDialog();
} else {
super.onBackPressed();
}
}
+ private boolean modificationsDone() {
+ return nameChanged || modificationsDone;
+ }
+
private void showDiscardDialog() {
new AlertDialog.Builder(this)
.setPositiveButton(R.string.keep_editing, new DialogInterface.OnClickListener() {
@@ -215,4 +251,83 @@ public class EditExerciseSetActivity extends AppCompatActivity implements androi
.setMessage(R.string.dialog_discard_confirmation)
.create().show();
}
+
+ public void onClick(View view) {
+ switch(view.getId()) {
+ case R.id.add_button:
+
+ Intent i = new Intent(this, ChooseExerciseActivity.class);
+ i.putExtra(ChooseExerciseActivity.EXTRA_SELECTED_EXERCISES , getSelectedExerciseIds());
+ startActivityForResult(i, PICK_EXERCISE_REQUEST);
+ break;
+ }
+ }
+
+ private int[] getSelectedExerciseIds() {
+ List set = mAdapter.getExercises();
+
+ int[] result = new int[set.size()];
+
+ for(int i = 0; i < set.size(); ++i) {
+ result[i] = set.get(i).getId();
+ }
+ return result;
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ if(requestCode == PICK_EXERCISE_REQUEST) {
+ if(resultCode == RESULT_OK) {
+
+ int[] result = data.getIntArrayExtra(ChooseExerciseActivity.EXTRA_SELECTED_EXERCISES);
+ List oldList = mAdapter.getExercises();
+ // did we make any changes?
+
+ boolean needToUpdate = false;
+
+ if(result.length != oldList.size()) {
+ modificationsDone = true;
+ needToUpdate = true;
+ }
+
+ if(!needToUpdate) {
+ for (int id : result) {
+
+ boolean found = false;
+
+ for (Exercise e : oldList) {
+ if (e.getId() == id) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ modificationsDone = true;
+ needToUpdate = true;
+ break;
+ }
+ }
+ }
+
+ if(needToUpdate) {
+ List allExercises = mDbHelper.getExerciseList(ExerciseLocale.getLocale());
+ List newList = new ArrayList<>();
+
+ for (int id : result) {
+ for (Exercise e : allExercises) {
+ if (e.getId() == id) {
+ newList.add(e);
+ break;
+ }
+ }
+ }
+
+ mAdapter.replaceAll(newList);
+ }
+ }
+ }
+ }
}
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/ManageExerciseSetsActivity.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/ManageExerciseSetsActivity.java
index de04c28..5e02a4a 100644
--- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/ManageExerciseSetsActivity.java
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/ManageExerciseSetsActivity.java
@@ -32,7 +32,7 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
-import org.secuso.privacyfriendlybreakreminder.ExerciseLocale;
+import org.secuso.privacyfriendlybreakreminder.exercises.ExerciseLocale;
import org.secuso.privacyfriendlybreakreminder.R;
import org.secuso.privacyfriendlybreakreminder.activities.adapter.ExerciseSetListAdapter;
import org.secuso.privacyfriendlybreakreminder.activities.helper.BaseActivity;
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/TimerActivity.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/TimerActivity.java
index b75f07d..de34ddf 100644
--- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/TimerActivity.java
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/TimerActivity.java
@@ -14,15 +14,13 @@ import android.graphics.drawable.ColorDrawable;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.ColorRes;
-import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.Loader;
-import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
-import android.widget.ArrayAdapter;
+import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.NumberPicker;
@@ -30,7 +28,7 @@ import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
-import org.secuso.privacyfriendlybreakreminder.ExerciseLocale;
+import org.secuso.privacyfriendlybreakreminder.exercises.ExerciseLocale;
import org.secuso.privacyfriendlybreakreminder.R;
import org.secuso.privacyfriendlybreakreminder.activities.adapter.ExerciseSetSpinnerAdapter;
import org.secuso.privacyfriendlybreakreminder.activities.helper.BaseActivity;
@@ -62,6 +60,7 @@ public class TimerActivity extends BaseActivity implements android.support.v4.ap
// animation
private int mShortAnimationDuration;
+ private boolean currentStatusIsPickerVisible = false;
private static final String[] SECONDS_MINUTES = new String[60];
private static final String[] HOURS = new String[24];
@@ -105,11 +104,9 @@ public class TimerActivity extends BaseActivity implements android.support.v4.ap
boolean isRunning = intent.getBooleanExtra("isRunning", false);
boolean isPaused = intent.getBooleanExtra("isPaused", false);
- if(mTimerService != null) {
- updateUI();
- } else {
- updateUI(isRunning, isPaused, initialDuration, millisUntilDone);
- }
+ Log.d(TAG, millisUntilDone + "/" + initialDuration + " (" + (isRunning ? "Running" : "") + (isPaused ? "Paused" : "") + (!isRunning && !isPaused ? "Stopped" : "") + ")");
+
+ updateUI(isRunning, isPaused, initialDuration, millisUntilDone);
}
};
@@ -175,7 +172,7 @@ public class TimerActivity extends BaseActivity implements android.support.v4.ap
}
private void initResources() {
- SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
+ final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
exerciseSetAdapter = new ExerciseSetSpinnerAdapter(this, R.layout.layout_exercise_set, new LinkedList());
@@ -186,6 +183,14 @@ public class TimerActivity extends BaseActivity implements android.support.v4.ap
resetButton = (ImageButton) findViewById(R.id.button_reset);
exerciseSetSpinner = (Spinner) findViewById(R.id.spinner_choose_exercise_set);
exerciseSetSpinner.setAdapter(exerciseSetAdapter);
+ exerciseSetSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ pref.edit().putLong("DEFAULT_EXERCISE_SET", id).apply();
+ }
+ @Override
+ public void onNothingSelected(AdapterView> parent) {}
+ });
secondsPicker = (NumberPicker) findViewById(R.id.seconds_picker);
minutesPicker = (NumberPicker) findViewById(R.id.minutes_picker);
hoursPicker = (NumberPicker) findViewById(R.id.hours_picker);
@@ -240,14 +245,13 @@ public class TimerActivity extends BaseActivity implements android.support.v4.ap
handlePlayPressed();
break;
case R.id.button_reset:
- mTimerService.stopAndResetTimer();
+ if(mTimerService != null)
+ mTimerService.stopAndResetTimer();
break;
//case R.id.button_chooseExercise:
// startActivity(new Intent(this, ManageExerciseSetsActivity.class));
// break;
}
-
- updateUI();
}
private void handlePlayPressed() {
@@ -262,7 +266,7 @@ public class TimerActivity extends BaseActivity implements android.support.v4.ap
long duration = getCurrentSetDuration();
saveCurrentSetDuration();
mTimerService.startTimer(duration);
- progressBar.setMax((int)duration);
+ progressBar.setMax((int) duration);
}
}
}
@@ -289,68 +293,80 @@ public class TimerActivity extends BaseActivity implements android.support.v4.ap
}
}
- private void updateUI(boolean running, boolean isPaused, long initialDuration, long remainingDuration) {
+ private synchronized void updateUI(boolean running, boolean isPaused, long initialDuration, long remainingDuration) {
updatePlayButton(running);
progressBar.setMax((int) initialDuration);
updateProgress(remainingDuration);
showPicker(!running && !isPaused);
}
- private void showPicker(boolean showPicker) {
- if(showPicker && pickerLayout.getVisibility() != View.VISIBLE) {
- pickerLayout.setAlpha(0f);
- pickerLayout.setVisibility(View.VISIBLE);
- pickerLayout.animate()
- .alpha(1f)
- .setStartDelay(mShortAnimationDuration)
- .setDuration(mShortAnimationDuration)
- .setListener(null);
+ private synchronized void showPicker(final boolean showPicker) {
+ if(showPicker != currentStatusIsPickerVisible) {
- timerText.animate()
- .alpha(0f)
- .setDuration(mShortAnimationDuration)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animator) {
- timerText.setVisibility(View.INVISIBLE);
- }
- });
+ pickerLayout.clearAnimation();
+ timerText.clearAnimation();
+ progressBar.clearAnimation();
- progressBar.animate()
- .alpha(0f)
- .setDuration(mShortAnimationDuration)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animator) {
- progressBar.setVisibility(View.INVISIBLE);
- }
- });
+ currentStatusIsPickerVisible = showPicker;
- } else if(!showPicker && pickerLayout.getVisibility() == View.VISIBLE) {
- pickerLayout.animate()
- .alpha(0f)
- .setDuration(mShortAnimationDuration)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animator) {
- pickerLayout.setVisibility(View.INVISIBLE);
- }
- });
+ if (showPicker) {
+ pickerLayout.setAlpha(0f);
+ pickerLayout.setVisibility(View.VISIBLE);
+ pickerLayout.animate()
+ .alpha(1f)
+ //.setStartDelay(mShortAnimationDuration)
+ .setDuration(mShortAnimationDuration)
+ .setListener(null);
- timerText.setAlpha(0f);
- timerText.setVisibility(View.VISIBLE);
- timerText.animate()
- .alpha(1f)
- .setDuration(mShortAnimationDuration)
- .setListener(null);
+ timerText.animate()
+ .alpha(0f)
+ .setDuration(mShortAnimationDuration)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ if(currentStatusIsPickerVisible)
+ timerText.setVisibility(View.INVISIBLE);
+ }
+ });
- progressBar.setAlpha(0f);
- progressBar.setVisibility(View.VISIBLE);
- progressBar.animate()
- .alpha(1f)
- .setDuration(mShortAnimationDuration)
- .setStartDelay(mShortAnimationDuration)
- .setListener(null);
+ progressBar.animate()
+ .alpha(0f)
+ .setDuration(mShortAnimationDuration)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ if(currentStatusIsPickerVisible)
+ progressBar.setVisibility(View.INVISIBLE);
+ }
+ });
+
+ } else {
+ pickerLayout.animate()
+ .alpha(0f)
+ .setDuration(mShortAnimationDuration)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ if(!currentStatusIsPickerVisible)
+ pickerLayout.setVisibility(View.INVISIBLE);
+ }
+ });
+
+ timerText.setAlpha(0f);
+ timerText.setVisibility(View.VISIBLE);
+ timerText.animate()
+ .alpha(1f)
+ .setDuration(mShortAnimationDuration)
+ .setListener(null);
+
+ progressBar.setAlpha(0f);
+ progressBar.setVisibility(View.VISIBLE);
+ progressBar.animate()
+ .alpha(1f)
+ .setDuration(mShortAnimationDuration)
+ //.setStartDelay(mShortAnimationDuration)
+ .setListener(null);
+ }
}
}
@@ -400,6 +416,18 @@ public class TimerActivity extends BaseActivity implements android.support.v4.ap
@Override
public void onLoadFinished(Loader> loader, List data) {
exerciseSetAdapter.updateData(data);
+
+ long defaultId = PreferenceManager.getDefaultSharedPreferences(this).getLong("DEFAULT_EXERCISE_SET", 0L);
+
+
+ for(int i = 0; i < data.size(); ++i) {
+ ExerciseSet e = data.get(i);
+
+ if(e.getId() == defaultId) {
+ exerciseSetSpinner.setSelection(i);
+ break;
+ }
+ }
}
@Override
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseAdapter.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseAdapter.java
new file mode 100644
index 0000000..f308167
--- /dev/null
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseAdapter.java
@@ -0,0 +1,230 @@
+package org.secuso.privacyfriendlybreakreminder.activities.adapter;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.constraint.ConstraintLayout;
+import android.support.v7.util.SortedList;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.secuso.privacyfriendlybreakreminder.R;
+import org.secuso.privacyfriendlybreakreminder.activities.ChooseExerciseActivity;
+import org.secuso.privacyfriendlybreakreminder.database.data.Exercise;
+import org.secuso.privacyfriendlybreakreminder.database.data.ExerciseSet;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Created by Christopher Beckmann on 06.09.2017.
+ */
+
+public class ExerciseAdapter extends RecyclerView.Adapter {
+
+ private Context mContext;
+ private List checkedIds = new ArrayList<>();
+ private boolean mShowCheckboxes = false;
+
+ public static final Comparator ID_COMPARATOR = new Comparator() {
+ @Override
+ public int compare(Exercise a, Exercise b) {
+ return (a.getId() < b.getId()) ? -1 : ((a.getId() == b.getId()) ? 0 : 1);
+ }
+ };
+
+ private final LayoutInflater mInflater;
+ private final Comparator mComparator;
+ private final SortedList mSortedList = new SortedList<>(Exercise.class, new SortedList.Callback() {
+ @Override
+ public void onInserted(int position, int count) {
+ notifyItemRangeInserted(position, count);
+ }
+
+ @Override
+ public void onRemoved(int position, int count) {
+ notifyItemRangeRemoved(position, count);
+ }
+
+ @Override
+ public void onMoved(int fromPosition, int toPosition) {
+ notifyItemMoved(fromPosition, toPosition);
+ }
+
+ @Override
+ public void onChanged(int position, int count) {
+ notifyItemRangeChanged(position, count);
+ }
+
+ @Override
+ public int compare(Exercise a, Exercise b) {
+ return mComparator.compare(a, b);
+ }
+
+ @Override
+ public boolean areContentsTheSame(Exercise oldItem, Exercise newItem) {
+ return oldItem.equals(newItem);
+ }
+
+ @Override
+ public boolean areItemsTheSame(Exercise item1, Exercise item2) {
+ return item1.getId() == item2.getId();
+ }
+ });
+
+ public ExerciseAdapter(Context context, Comparator comparator) {
+ this.mContext = context;
+ this.mComparator = comparator;
+ this.mInflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View itemView = mInflater.inflate(R.layout.layout_exercise_grid_item, parent, false);
+ return new ExerciseAdapter.ExerciseViewHolder(itemView);
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+
+ final Exercise exercise = mSortedList.get(position);
+
+ final ExerciseViewHolder vh = (ExerciseViewHolder) holder;
+
+ String imageID = exercise.getImageID();
+ String[] imageIDSplit = imageID.split(",");
+
+ if(imageIDSplit.length > 1) {
+ imageID = imageIDSplit[0];
+ }
+
+ final View.OnClickListener infoClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Toast.makeText(mContext, "Show Details Of the Exercise Now.", Toast.LENGTH_SHORT).show();
+ // TODO: show Fragement ? Dialog? Something with the Information of the Exercise!
+ }
+ };
+
+ final View.OnClickListener checkClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(vh.checkbox.isChecked()) {
+ checkedIds.remove(checkedIds.indexOf(exercise.getId()));
+ } else {
+ checkedIds.add(exercise.getId());
+ }
+
+ vh.checkbox.setChecked(!vh.checkbox.isChecked());
+ }
+ };
+
+ int imageResID = mContext.getResources().getIdentifier(
+ "exercise_" + imageID,
+ "drawable",
+ mContext.getPackageName());
+ vh.image.setImageResource(imageResID);
+
+ if(checkedIds != null)
+ vh.checkbox.setChecked(checkedIds.contains(exercise.getId()));
+
+ vh.checkbox.setClickable(false);
+ vh.checkbox.setVisibility(mShowCheckboxes ? View.VISIBLE : View.GONE);
+
+ vh.layout.setOnClickListener(mShowCheckboxes ? checkClick : infoClick);
+ vh.layout.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ infoClick.onClick(v);
+ return true;
+ }
+ });
+
+ vh.infoButton.setOnClickListener(infoClick);
+ }
+
+ @Override
+ public int getItemCount() {
+ return mSortedList.size();
+ }
+
+ public void replaceAll(@NonNull List exercises) {
+ mSortedList.beginBatchedUpdates();
+ for (int i = mSortedList.size() - 1; i >= 0; i--) {
+ final Exercise ex = mSortedList.get(i);
+ if (!exercises.contains(ex)) {
+ mSortedList.remove(ex);
+ }
+ }
+ mSortedList.addAll(exercises);
+ mSortedList.endBatchedUpdates();
+ }
+
+ public List getCheckedIds() {
+ return checkedIds;
+ }
+
+ public void add(Exercise model) {
+ mSortedList.add(model);
+ }
+
+ public void remove(Exercise model) {
+ mSortedList.remove(model);
+ }
+
+ public void add(List models) {
+ mSortedList.addAll(models);
+ }
+
+ public void remove(List models) {
+ mSortedList.beginBatchedUpdates();
+ for (Exercise model : models) {
+ mSortedList.remove(model);
+ }
+ mSortedList.endBatchedUpdates();
+ }
+
+ public void setCheckedItems(@NonNull List checkedItems) {
+ this.checkedIds = checkedItems;
+ }
+
+ public List getExercises() {
+ List result = new LinkedList<>();
+
+ for (int i = 0; i < mSortedList.size(); ++i) {
+ Exercise e = mSortedList.get(i);
+ result.add(e);
+ }
+
+ return result;
+ }
+
+ public class ExerciseViewHolder extends RecyclerView.ViewHolder {
+
+ ImageView image;
+ CheckBox checkbox;
+ ImageButton infoButton;
+ ConstraintLayout layout;
+
+ public ExerciseViewHolder(View itemView) {
+ super(itemView);
+
+ layout = (ConstraintLayout) itemView.findViewById(R.id.exercise_layout);
+ checkbox = (CheckBox) itemView.findViewById(R.id.exercise_checkbox);
+ image = (ImageView) itemView.findViewById(R.id.exercise_image);
+ infoButton = (ImageButton) itemView.findViewById(R.id.exercise_info_button);
+ }
+ }
+
+ public void showCheckboxes(boolean show) {
+ mShowCheckboxes = show;
+ }
+}
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseSetAdapter.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseSetAdapter.java
index 4519337..250dd0a 100644
--- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseSetAdapter.java
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseSetAdapter.java
@@ -11,14 +11,14 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.secuso.privacyfriendlybreakreminder.R;
-import org.secuso.privacyfriendlybreakreminder.activities.ManageExerciseSetsActivity;
-import org.secuso.privacyfriendlybreakreminder.activities.helper.CursorRecyclerViewAdapter;
-import org.secuso.privacyfriendlybreakreminder.database.columns.ExerciseColumns;
import org.secuso.privacyfriendlybreakreminder.database.data.Exercise;
import org.secuso.privacyfriendlybreakreminder.database.data.ExerciseSet;
/**
- * Created by Christopher Beckmann on 30.08.2017.
+ * This adapter provides the {@link Exercise}s of one {@link ExerciseSet}.
+ * Use {@link ExerciseSetAdapter#add(Exercise)} and {@link ExerciseSetAdapter#remove(Exercise)} to manage the {@link Exercise}s.
+ * @author Christopher Beckmann
+ * @see android.support.v7.widget.RecyclerView.Adapter
*/
public class ExerciseSetAdapter extends RecyclerView.Adapter {
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseSetSpinnerAdapter.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseSetSpinnerAdapter.java
index f9b10e4..93a46e6 100644
--- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseSetSpinnerAdapter.java
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/adapter/ExerciseSetSpinnerAdapter.java
@@ -3,6 +3,7 @@ package org.secuso.privacyfriendlybreakreminder.activities.adapter;
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
+import android.support.v4.content.ContextCompat;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
@@ -93,6 +94,7 @@ public class ExerciseSetSpinnerAdapter extends ArrayAdapter {
} else {
noExercisesText.setVisibility(View.GONE);
}
+ noExercisesText.setTextColor(ContextCompat.getColor(getContext(), R.color.black));
//LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE);
//View row = inflater.inflate(resource, parent, false);
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/layout/FlowLayout.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/layout/FlowLayout.java
new file mode 100644
index 0000000..c44a89d
--- /dev/null
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/layout/FlowLayout.java
@@ -0,0 +1,166 @@
+package org.secuso.privacyfriendlybreakreminder.activities.layout;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.secuso.privacyfriendlybreakreminder.R;
+
+public class FlowLayout extends ViewGroup {
+ private int mHorizontalSpacing;
+ private int mVerticalSpacing;
+ private Paint mPaint;
+
+ public FlowLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FlowLayout);
+ try {
+ mHorizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_horizontalSpacing, 0);
+ mVerticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_verticalSpacing, 0);
+ } finally {
+ a.recycle();
+ }
+
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setColor(0xffff0000);
+ mPaint.setStrokeWidth(2.0f);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int widthSize = MeasureSpec.getSize(widthMeasureSpec) - getPaddingRight();
+ int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+
+ boolean growHeight = widthMode != MeasureSpec.UNSPECIFIED;
+
+ int width = 0;
+ int height = getPaddingTop();
+
+ int currentWidth = getPaddingLeft();
+ int currentHeight = 0;
+
+ boolean breakLine = false;
+ boolean newLine = false;
+ int spacing = 0;
+
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ View child = getChildAt(i);
+ measureChild(child, widthMeasureSpec, heightMeasureSpec);
+
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ spacing = mHorizontalSpacing;
+ if (lp.horizontalSpacing >= 0) {
+ spacing = lp.horizontalSpacing;
+ }
+
+ if (growHeight && (breakLine || currentWidth + child.getMeasuredWidth() > widthSize)) {
+ height += currentHeight + mVerticalSpacing;
+ currentHeight = 0;
+ width = Math.max(width, currentWidth - spacing);
+ currentWidth = getPaddingLeft();
+ newLine = true;
+ } else {
+ newLine = false;
+ }
+
+ lp.x = currentWidth;
+ lp.y = height;
+
+ currentWidth += child.getMeasuredWidth() + spacing;
+ currentHeight = Math.max(currentHeight, child.getMeasuredHeight());
+
+ breakLine = lp.breakLine;
+ }
+
+ if (!newLine) {
+ height += currentHeight;
+ width = Math.max(width, currentWidth - spacing);
+ }
+
+ width += getPaddingRight();
+ height += getPaddingBottom();
+
+ setMeasuredDimension(resolveSize(width, widthMeasureSpec),
+ resolveSize(height, heightMeasureSpec));
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ View child = getChildAt(i);
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y + child.getMeasuredHeight());
+ }
+ }
+
+ @Override
+ protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+ boolean more = super.drawChild(canvas, child, drawingTime);
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ if (lp.horizontalSpacing > 0) {
+ float x = child.getRight();
+ float y = child.getTop() + child.getHeight() / 2.0f;
+ canvas.drawLine(x, y - 4.0f, x, y + 4.0f, mPaint);
+ canvas.drawLine(x, y, x + lp.horizontalSpacing, y, mPaint);
+ canvas.drawLine(x + lp.horizontalSpacing, y - 4.0f, x + lp.horizontalSpacing, y + 4.0f, mPaint);
+ }
+ if (lp.breakLine) {
+ float x = child.getRight();
+ float y = child.getTop() + child.getHeight() / 2.0f;
+ canvas.drawLine(x, y, x, y + 6.0f, mPaint);
+ canvas.drawLine(x, y + 6.0f, x + 6.0f, y + 6.0f, mPaint);
+ }
+ return more;
+ }
+
+ @Override
+ protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+ return p instanceof LayoutParams;
+ }
+
+ @Override
+ protected LayoutParams generateDefaultLayoutParams() {
+ return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ }
+
+ @Override
+ public LayoutParams generateLayoutParams(AttributeSet attrs) {
+ return new LayoutParams(getContext(), attrs);
+ }
+
+ @Override
+ protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+ return new LayoutParams(p.width, p.height);
+ }
+
+ public static class LayoutParams extends ViewGroup.LayoutParams {
+ int x;
+ int y;
+
+ public int horizontalSpacing;
+ public boolean breakLine;
+
+ public LayoutParams(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FlowLayout_LayoutParams);
+ try {
+ horizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_LayoutParams_layout_horizontalSpacing, -1);
+ breakLine = a.getBoolean(R.styleable.FlowLayout_LayoutParams_layout_breakLine, false);
+ } finally {
+ a.recycle();
+ }
+ }
+
+ public LayoutParams(int w, int h) {
+ super(w, h);
+ }
+ }
+}
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/database/SQLiteHelper.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/database/SQLiteHelper.java
index fec20cb..e34493e 100644
--- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/database/SQLiteHelper.java
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/database/SQLiteHelper.java
@@ -6,6 +6,7 @@ import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
+import android.support.annotation.NonNull;
import android.util.Log;
import org.secuso.privacyfriendlybreakreminder.database.columns.ExerciseSetColumns;
@@ -72,13 +73,29 @@ public class SQLiteHelper extends SQLiteOpenHelper {
database.close();
}
+ public void updateExerciseSet(ExerciseSet exerciseSet) {
+ SQLiteDatabase database = getReadableDatabase();
+ database.update(ExerciseSetColumns.TABLE_NAME, ExerciseSetColumns.getValues(exerciseSet), ExerciseSetColumns._ID + " = ?", new String[]{String.valueOf(exerciseSet.getId())});
+ database.close();
+ }
+
public synchronized long addExerciseSet(String name) {
SQLiteDatabase database = getReadableDatabase();
ContentValues cv = new ContentValues();
cv.put(ExerciseSetColumns.NAME, name);
- return database.insert(ExerciseSetColumns.TABLE_NAME, null, cv);
+ long id = database.insert(ExerciseSetColumns.TABLE_NAME, null, cv);
+ database.close();
+
+ return id;
+ }
+
+
+ public void clearExercisesFromSet(int exerciseSetId) {
+ SQLiteDatabase database = getReadableDatabase();
+ database.delete("exercise_set_exercises", ExerciseSetColumns._ID + " = ?", new String[]{String.valueOf(exerciseSetId)});
+ database.close();
}
public synchronized void addExerciseToExerciseSet(int exerciseSetId, int exerciseId) {
@@ -131,14 +148,17 @@ public class SQLiteHelper extends SQLiteOpenHelper {
}
c.moveToNext();
}
+ c.close();
}
+ close();
+
return result;
}
public synchronized Cursor getExerciseCursor(String language) {
SQLiteDatabase database = getReadableDatabase();
- return database.rawQuery(buildQuery(false), new String[]{language});
+ return database.rawQuery(buildQuery(0), new String[]{language});
}
public synchronized List getExerciseList(String language) {
@@ -196,6 +216,8 @@ public class SQLiteHelper extends SQLiteOpenHelper {
c.close();
}
+ close();
+
return result;
}
@@ -214,41 +236,45 @@ public class SQLiteHelper extends SQLiteOpenHelper {
c.close();
}
+ close();
+
return result;
}
-
- private String buildQuery(boolean addSectionCheck) {
- return buildQuery(addSectionCheck, "");
- }
-
- public synchronized List getExercisesFromSection(String language, String section) { // TODO: Rename after old activities are deleted
+ public synchronized List getExerciseListBySections(String language, @NonNull List sections) {
SQLiteDatabase database = getReadableDatabase();
- Cursor c = database.rawQuery(buildQuery(true), new String[]{language, "%"+section+"%"});
+ String[] argValues = new String[sections.size() + 1];
+
+ argValues[0] = language;
+
+ for(int i = 1; i < argValues.length; ++i) {
+ argValues[i] = "%"+sections.get(i - 1)+"%";
+ }
+
+ Cursor c = database.rawQuery(buildQuery(sections.size()), argValues);
+
+ return buildExerciseList(c);
+ }
+
+ public synchronized List getExercisesFromSection(String language, String section) { // TODO: REMOVE after old activities are deleted
+ SQLiteDatabase database = getReadableDatabase();
+
+ Cursor c = database.rawQuery(buildQuery(1), new String[]{language, "%"+section+"%"});
return buildExerciseList(c);
}
/**
- * SELECT
- * E._id,
- * E.section,
- * E.image_id,
- * L.local_id,
- * L.language,
- * L.exercise_id,
- * L.name,
- * L.description,
- * L.execution
+ * SELECT *
* FROM exercises E LEFT OUTER JOIN exercises_local L
* ON E._id = L.exercise_id
- * WHERE L.language = "de" [AND E.section LIKE %?%]
+ * WHERE L.language = "de" [AND E.section LIKE ?]
* ORDER BY E._id ASC
*
* @return the sql query without the ; at the end.
*/
- private String buildQuery(boolean addSectionCheck, String customWhereClause) {
+ private String buildQuery(int sectionCheck) {
StringBuilder sqlQuery = new StringBuilder();
sqlQuery.append("SELECT ");
@@ -279,12 +305,23 @@ public class SQLiteHelper extends SQLiteOpenHelper {
sqlQuery.append(ExerciseLocalColumns.LANGUAGE);
sqlQuery.append(" = ? ");
- if(addSectionCheck) {
- sqlQuery.append("AND E.");
+ if(sectionCheck > 0) {
+ sqlQuery.append("AND ( ");
+ }
+
+ for(int i = 0; i < sectionCheck; ++i) {
+ sqlQuery.append("E.");
sqlQuery.append(ExerciseColumns.SECTION);
sqlQuery.append(" LIKE ? ");
+
+ if(i + 1 == sectionCheck) {
+ sqlQuery.append(") ");
+ } else {
+ sqlQuery.append("OR ");
+ }
}
+
sqlQuery.append("ORDER BY E.");
sqlQuery.append(ExerciseColumns._ID);
sqlQuery.append(" ASC");
@@ -364,5 +401,4 @@ public class SQLiteHelper extends SQLiteOpenHelper {
}
}
}
-
}
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/database/data/ExerciseSet.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/database/data/ExerciseSet.java
index 8766078..f09a920 100644
--- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/database/data/ExerciseSet.java
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/database/data/ExerciseSet.java
@@ -56,4 +56,7 @@ public class ExerciseSet {
return exercises.size();
}
+ public List getExercises() {
+ return exercises;
+ }
}
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/ExerciseLocale.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/exercises/ExerciseLocale.java
similarity index 84%
rename from app/src/main/java/org/secuso/privacyfriendlybreakreminder/ExerciseLocale.java
rename to app/src/main/java/org/secuso/privacyfriendlybreakreminder/exercises/ExerciseLocale.java
index 0fdba78..77eafb1 100644
--- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/ExerciseLocale.java
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/exercises/ExerciseLocale.java
@@ -1,4 +1,4 @@
-package org.secuso.privacyfriendlybreakreminder;
+package org.secuso.privacyfriendlybreakreminder.exercises;
import java.util.Arrays;
import java.util.HashSet;
@@ -8,7 +8,9 @@ import java.util.Locale;
* This class saves the available languages for the exercises.
* @author Christopher Beckmann
*/
-public class ExerciseLocale {
+public final class ExerciseLocale {
+
+ private ExerciseLocale() {}
private static final HashSet AVAILABLE_LOCALE = new HashSet<>();
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/exercises/ExerciseSections.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/exercises/ExerciseSections.java
new file mode 100644
index 0000000..c8a58c4
--- /dev/null
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/exercises/ExerciseSections.java
@@ -0,0 +1,36 @@
+package org.secuso.privacyfriendlybreakreminder.exercises;
+
+import android.content.Context;
+import android.support.annotation.StringRes;
+import android.support.v4.content.ContextCompat;
+
+import org.secuso.privacyfriendlybreakreminder.R;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Created by Christopher Beckmann on 06.09.2017.
+ */
+
+public enum ExerciseSections {
+ Head(R.string.exercise_section_head),
+ Neck(R.string.exercise_section_neck),
+ Arms(R.string.exercise_section_arms),
+ Torso(R.string.exercise_section_torso),
+ Spinal(R.string.exercise_section_spinal),
+ Pelvis(R.string.exercise_section_pelvis),
+ Legs(R.string.exercise_section_legs);
+
+ private final @StringRes int nameResId;
+
+ ExerciseSections(@StringRes int resId) {
+ this.nameResId = resId;
+ }
+
+ public String getLocalName(Context context) {
+ return context.getString(nameResId);
+ }
+ public static List getSectionList() { return Arrays.asList( Head, Neck, Arms, Torso, Spinal, Pelvis, Legs ); }
+}
diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/service/TimerService.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/service/TimerService.java
index a7920fb..96123a8 100644
--- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/service/TimerService.java
+++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/service/TimerService.java
@@ -28,12 +28,17 @@ import java.util.Timer;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
public class TimerService extends Service {
+
public static final String TAG = TimerService.class.getSimpleName();
public static final String NOTIFICATION_BROADCAST = TAG + ".NOTIFICATION_BROADCAST";
public static final String TIMER_BROADCAST = TAG + ".TIMER_BROADCAST";
+ private static final int UPDATE_INTERVAL = 25;
+ private static final int NOTIFICATION_ID = 31337;
+
private TimerServiceBinder mBinder = new TimerServiceBinder();
private CountDownTimer mTimer;
+ private NotificationManager notificationManager;
private boolean isRunning = false;
private long remainingDuration = 0;
@@ -43,14 +48,17 @@ public class TimerService extends Service {
int lastTime = 0;
@Override
public void onReceive(Context context, Intent intent) {
- if((int) remainingDuration / 1000 != lastTime) {
- lastTime = (int) remainingDuration / 1000;
- updateNotification();
- }
- if(intent.getBooleanExtra("done" ,false)) {
+ // limit the notification updates
+ int remainingSeconds = intent.getIntExtra("countdown_seconds", 0);
+
+ if(remainingSeconds != lastTime) {
+ lastTime = remainingSeconds;
updateNotification();
+ } else if(intent.getBooleanExtra("done" ,false)) {
+ lastTime = 0;
+ updateNotification();
}
}
};
@@ -72,10 +80,19 @@ public class TimerService extends Service {
public synchronized void startTimer(long duration) {
if(!isRunning) {
initialDuration = duration;
- mTimer = createTimer(duration);
- mTimer.start();
- isRunning = true;
- sendBroadcast(buildBroadcast());
+
+ if(duration > 0) {
+ mTimer = createTimer(duration);
+ mTimer.start();
+ isRunning = true;
+ sendBroadcast(buildBroadcast());
+
+ } else {
+ remainingDuration = initialDuration;
+ Intent broadcast = buildBroadcast();
+ broadcast.putExtra("done", true);
+ sendBroadcast(broadcast);
+ }
}
}
@@ -83,6 +100,7 @@ public class TimerService extends Service {
if(isRunning) {
mTimer.cancel();
isRunning = false;
+
sendBroadcast(buildBroadcast());
}
}
@@ -92,6 +110,7 @@ public class TimerService extends Service {
mTimer = createTimer(remainingDuration);
mTimer.start();
isRunning = true;
+
sendBroadcast(buildBroadcast());
}
}
@@ -103,6 +122,7 @@ public class TimerService extends Service {
mTimer.start();
}
remainingDuration = initialDuration;
+
sendBroadcast(buildBroadcast());
}
@@ -110,10 +130,11 @@ public class TimerService extends Service {
if(isRunning) mTimer.cancel();
isRunning = false;
remainingDuration = initialDuration;
+
sendBroadcast(buildBroadcast());
}
- public synchronized boolean isPaused() { return !isRunning && remainingDuration > 0 && remainingDuration != initialDuration; }
+ public synchronized boolean isPaused() { return !isRunning && initialDuration != 0 && remainingDuration > 0 && remainingDuration != initialDuration; }
public synchronized boolean isRunning() {
return isRunning;
@@ -122,24 +143,29 @@ public class TimerService extends Service {
private CountDownTimer createTimer(long duration) {
remainingDuration = duration;
- return new CountDownTimer(duration, 10) {
+ return new CountDownTimer(duration, UPDATE_INTERVAL) {
@Override
public void onTick(long millisUntilFinished) {
- synchronized (TimerService.this) {
+ if(isRunning) {
remainingDuration = millisUntilFinished;
+ sendBroadcast(buildBroadcast());
}
-
- sendBroadcast(buildBroadcast());
}
@Override
public void onFinish() {
+
+ mTimer.cancel();
+ isRunning = false;
+ remainingDuration = 0;
+
Intent broadcast = buildBroadcast();
broadcast.putExtra("done", true);
- sendBroadcast(buildBroadcast());
+ sendBroadcast(broadcast);
+
+ remainingDuration = initialDuration;
- stopAndResetTimer();
}
};
}
@@ -153,6 +179,7 @@ public class TimerService extends Service {
broadcast.putExtra("countdown_seconds", secondsUntilFinished);
broadcast.putExtra("isRunning", isRunning());
broadcast.putExtra("isPaused", isPaused());
+
return (broadcast);
}
@@ -160,15 +187,11 @@ public class TimerService extends Service {
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
- setAsForegroundService();
+ notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
return START_STICKY;
}
- private void setAsForegroundService() {
- startForeground(31337, buildNotification());
- }
-
private Notification buildNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle(getString(R.string.app_name));
@@ -187,13 +210,18 @@ public class TimerService extends Service {
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
builder.setWhen(0);
builder.setSmallIcon(R.mipmap.ic_launcher);
+ builder.setOngoing(isRunning() || isPaused());
return builder.build();
}
private void updateNotification() {
- NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
- notificationManager.notify(31337, buildNotification());
+ if(isRunning() || isPaused())
+ startForeground(NOTIFICATION_ID, buildNotification());
+ else
+ stopForeground(false);
+
+ notificationManager.notify(NOTIFICATION_ID, buildNotification());
}
@Override
diff --git a/app/src/main/res/drawable/circular.xml b/app/src/main/res/drawable/circular.xml
deleted file mode 100644
index d448196..0000000
--- a/app/src/main/res/drawable/circular.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
- -
-
-
-
-
- -
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_edit_white_24dp.xml b/app/src/main/res/drawable/ic_edit_white_24dp.xml
new file mode 100644
index 0000000..35a774a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_edit_white_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_choose_exercise.xml b/app/src/main/res/layout/activity_choose_exercise.xml
new file mode 100644
index 0000000..d19930c
--- /dev/null
+++ b/app/src/main/res/layout/activity_choose_exercise.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_edit_exercise_set.xml b/app/src/main/res/layout/activity_edit_exercise_set.xml
index 447584b..f231ecb 100644
--- a/app/src/main/res/layout/activity_edit_exercise_set.xml
+++ b/app/src/main/res/layout/activity_edit_exercise_set.xml
@@ -44,39 +44,52 @@
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="org.secuso.privacyfriendlybreakreminder.activities.ManageExerciseSetsActivity">
-
+
-
+
-
+
+
+
diff --git a/app/src/main/res/layout/activity_timer.xml b/app/src/main/res/layout/activity_timer.xml
index faa97f3..98d0e7f 100644
--- a/app/src/main/res/layout/activity_timer.xml
+++ b/app/src/main/res/layout/activity_timer.xml
@@ -48,7 +48,7 @@
android:layout_marginTop="8dp"
app:layout_constraintHorizontal_bias="0.0"
android:layout_marginStart="8dp"
- android:layout_marginEnd="8dp" />
+ android:layout_marginEnd="8dp"/>