diff --git a/.idea/misc.xml b/.idea/misc.xml index c299bad..c2f4918 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,8 +1,5 @@ - - - - + diff --git a/.idea/modules.xml b/.idea/modules.xml index 6f9f70f..4b79afc 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,7 @@ - + diff --git a/app/build.gradle b/app/build.gradle index 17f2084..f6e9017 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 25 - buildToolsVersion "25.0.3" + buildToolsVersion '26.0.2' defaultConfig { applicationId "org.secuso.privacyfriendlybreakreminder" @@ -24,22 +24,24 @@ android { } } -repositories{ +repositories { mavenCentral() mavenLocal() + google() } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') - compile 'com.android.support:appcompat-v7:25.3.1' - compile 'com.android.support:design:25.3.1' + compile 'com.android.support:appcompat-v7:25.4.0' + //compile 'com.android.support:preference-v7:25.4.0' + compile 'com.android.support:design:25.4.0' compile 'com.github.bumptech.glide:glide:3.7.0' - compile 'com.android.support:support-v4:25.3.1' - compile 'com.android.support:support-annotations:25.3.1' - compile 'com.android.support:cardview-v7:25.3.1' + compile 'com.android.support:support-v4:25.4.0' + compile 'com.android.support:support-annotations:27.0.0' + compile 'com.android.support:cardview-v7:25.4.0' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.nex3z:flow-layout:1.0.0' compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:2.0.1' testCompile 'junit:junit:4.12' - compile 'com.shawnlin:number-picker:2.4.4' + compile 'com.shawnlin:number-picker:2.4.4' // https://github.com/ShawnLin013/NumberPicker } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 03f1855..dfd900f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,67 +2,60 @@ - + - - + android:screenOrientation="portrait" + android:theme="@style/SplashTheme"> - + android:screenOrientation="portrait" + android:theme="@style/AppTheme.NoActionBar"> - - + android:screenOrientation="portrait" + android:theme="@style/AppTheme.NoActionBar" /> + android:windowSoftInputMode="adjustResize"> - - + android:windowSoftInputMode="adjustResize"> - > + android:value="org.secuso.privacyfriendlybreakreminder.activities.EditExerciseSetActivity" /> + > - - + android:screenOrientation="portrait" + android:theme="@style/AppTheme.NoActionBar"> @@ -121,6 +111,9 @@ android:enabled="true" android:exported="false" /> + \ No newline at end of file diff --git a/app/src/main/assets/databases/exercises.sqlite b/app/src/main/assets/databases/exercises.sqlite index 974576c..bc0011c 100644 Binary files a/app/src/main/assets/databases/exercises.sqlite and b/app/src/main/assets/databases/exercises.sqlite differ diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/HelpActivity.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/HelpActivity.java index 3d65e47..d9c024f 100644 --- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/HelpActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/HelpActivity.java @@ -5,9 +5,17 @@ import android.preference.PreferenceFragment; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.view.MenuItem; +import android.widget.ExpandableListView; import org.secuso.privacyfriendlybreakreminder.R; import org.secuso.privacyfriendlybreakreminder.activities.helper.BaseActivity; +import org.secuso.privacyfriendlybreakreminder.activities.helper.ExpandableListAdapter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; /** * @author Christopher Beckmann @@ -20,6 +28,27 @@ public class HelpActivity extends BaseActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_help); + + LinkedHashMap> expandableListDetail = buildData(); + List expandableListTitleGeneral = new ArrayList(expandableListDetail.keySet()); + + ExpandableListView generalExpandableListView = (ExpandableListView) findViewById(R.id.generalExpandableListView); + generalExpandableListView.setAdapter(new ExpandableListAdapter(this, expandableListTitleGeneral, expandableListDetail)); + + } + + private LinkedHashMap> buildData() { + LinkedHashMap> expandableListDetail = new LinkedHashMap<>(); + + expandableListDetail.put(getString(R.string.help_whatis), Collections.singletonList(getString(R.string.help_whatis_answer))); + + //expandableListDetail.put(getString(R.string.help_feature_one), Collections.singletonList(getString(R.string.help_feature_one_answer))); + + //expandableListDetail.put(getString(R.string.help_privacy), Collections.singletonList(getString(R.string.help_privacy_answer))); + + expandableListDetail.put(getString(R.string.help_permission), Collections.singletonList(getString(R.string.help_permission_answer))); + + return expandableListDetail; } @Override @@ -27,14 +56,4 @@ public class HelpActivity extends BaseActivity { return R.id.nav_help; } - public static class HelpFragment extends PreferenceFragment { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - //addPreferencesFromResource(R.xml.pref_help); - } - } - } 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 0b7c8fe..d78e617 100644 --- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/ManageExerciseSetsActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/ManageExerciseSetsActivity.java @@ -181,7 +181,6 @@ public class ManageExerciseSetsActivity extends BaseActivity implements android. ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.setDisplayHomeAsUpEnabled(!enabled); - actionBar.setDefaultDisplayHomeAsUpEnabled(!enabled); actionBar.setDisplayShowHomeEnabled(enabled); actionBar.setHomeButtonEnabled(enabled); } diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/SettingsActivity.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/SettingsActivity.java index f1c1300..63265d8 100644 --- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/SettingsActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/SettingsActivity.java @@ -2,35 +2,334 @@ package org.secuso.privacyfriendlybreakreminder.activities; +import android.annotation.TargetApi; +import android.app.Fragment; +import android.app.FragmentTransaction; +import android.content.Context; import android.content.Intent; -import android.media.Ringtone; -import android.media.RingtoneManager; -import android.net.Uri; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.os.Build; import android.os.Bundle; -import android.os.PersistableBundle; +import android.os.Handler; import android.preference.ListPreference; import android.preference.Preference; +import android.preference.PreferenceActivity; +import android.support.annotation.LayoutRes; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.StringRes; +import android.support.design.widget.NavigationView; +import android.support.v4.app.TaskStackBuilder; +import android.support.v4.view.GravityCompat; +import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBar; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; -import android.preference.RingtonePreference; -import android.text.TextUtils; +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AppCompatDelegate; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.MenuInflater; import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; -import org.secuso.privacyfriendlybreakreminder.activities.helper.BaseActivity; import org.secuso.privacyfriendlybreakreminder.R; +import org.secuso.privacyfriendlybreakreminder.activities.helper.AppCompatPreferenceActivity; +import org.secuso.privacyfriendlybreakreminder.activities.tutorial.TutorialActivity; + +import java.util.List; + +import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; /** * @author Christopher Beckmann * @version 2.0 */ -public class SettingsActivity extends BaseActivity { +public class SettingsActivity extends AppCompatPreferenceActivity implements NavigationView.OnNavigationItemSelectedListener{ + + // delay to launch nav drawer item, to allow close animation to play + protected static final int NAVDRAWER_LAUNCH_DELAY = 250; + // fade in and fade out durations for the main content when switching between + // different Activities of the app through the Nav Drawer + protected static final int MAIN_CONTENT_FADEOUT_DURATION = 150; + protected static final int MAIN_CONTENT_FADEIN_DURATION = 250; + + // Navigation drawer: + protected DrawerLayout mDrawerLayout; + private NavigationView mNavigationView; + protected Toolbar toolbar; + protected ActionBarDrawerToggle mDrawerToggle; + + // Helper + private Handler mHandler; + protected SharedPreferences mSharedPreferences; + + private boolean mDrawerEnabled; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + mHandler = new Handler(); + + overridePendingTransition(0, 0); + } + + @Override + public void onBackPressed() { + if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.START)) { + mDrawerLayout.closeDrawer(GravityCompat.START); + } else { + super.onBackPressed(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean onIsMultiPane() { + return isXLargeTablet(this); + } + + /** + * Helper method to determine if the device has an extra-large screen. For + * example, 10" tablets are extra-large. + */ + private static boolean isXLargeTablet(Context context) { + return (context.getResources().getConfiguration().screenLayout + & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE; + } + + /** + * {@inheritDoc} + */ + @Override + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public void onBuildHeaders(List
target) { + loadHeadersFromResource(R.xml.pref_headers, target); + } + + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + return goToNavigationItem(item.getItemId()); + } + + protected boolean goToNavigationItem(final int itemId) { + + if(itemId == getNavigationDrawerID()) { + // just close drawer because we are already in this activity + mDrawerLayout.closeDrawer(GravityCompat.START); + return true; + } + + // delay transition so the drawer can close + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + callDrawerItem(itemId); + } + }, NAVDRAWER_LAUNCH_DELAY); + + mDrawerLayout.closeDrawer(GravityCompat.START); + + selectNavigationItem(itemId); + + // fade out the active activity + View mainContent = findViewById(R.id.main_content); + if (mainContent != null) { + mainContent.animate().alpha(0).setDuration(MAIN_CONTENT_FADEOUT_DURATION); + } + return true; + } + + // set active navigation item + private void selectNavigationItem(int itemId) { + for(int i = 0 ; i < mNavigationView.getMenu().size(); i++) { + boolean b = itemId == mNavigationView.getMenu().getItem(i).getItemId(); + mNavigationView.getMenu().getItem(i).setChecked(b); + } + } + + /** + * Enables back navigation for activities that are launched from the NavBar. See + * {@code AndroidManifest.xml} to find out the parent activity names for each activity. + * @param intent + */ + private void createBackStack(Intent intent) { + TaskStackBuilder builder = TaskStackBuilder.create(this); + builder.addNextIntentWithParentStack(intent); + builder.startActivities(); + } + + /** + * This method manages the behaviour of the navigation drawer + * Add your menu items (ids) to res/menu/activity_main_drawer.xml + * @param itemId Item that has been clicked by the user + */ + private void callDrawerItem(final int itemId) { + + Intent intent; + + switch(itemId) { + case R.id.nav_timer: + intent = new Intent(this, TimerActivity.class); + intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + break; + case R.id.nav_manage_exercise_sets: + intent = new Intent(this, ManageExerciseSetsActivity.class); + createBackStack(intent); + break; + case R.id.nav_tutorial: + intent = new Intent(this, TutorialActivity.class); + createBackStack(intent); + break; + case R.id.nav_about: + intent = new Intent(this, AboutActivity.class); + createBackStack(intent); + break; + case R.id.nav_help: + intent = new Intent(this, HelpActivity.class); + createBackStack(intent); + break; + case R.id.nav_settings: + intent = new Intent(this, SettingsActivity.class); + //intent.putExtra( PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.ExercisePreferenceFragment.class.getName() ); + //intent.putExtra( PreferenceActivity.EXTRA_NO_HEADERS, true ); + createBackStack(intent); + break; + default: + } + overridePendingTransition(0,0); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + setContentView(R.layout.activity_settings); + + toolbar = (Toolbar) findViewById(R.id.toolbar); + if(getSupportActionBar() == null) { + setSupportActionBar(toolbar); + } + +// mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); +// mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); +// mDrawerLayout.addDrawerListener(mDrawerToggle); +// mDrawerToggle.syncState(); +// +// mNavigationView = (NavigationView) findViewById(R.id.nav_view); +// mNavigationView.setNavigationItemSelectedListener(this); +// +// showContent(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + public void setDrawerEnabled(final boolean enabled) { + + int lockMode = enabled ? + DrawerLayout.LOCK_MODE_UNLOCKED : + DrawerLayout.LOCK_MODE_LOCKED_CLOSED; + + mDrawerEnabled = enabled; + + if(mDrawerLayout == null) return; + + mDrawerLayout.setDrawerLockMode(lockMode); + mDrawerToggle.setDrawerIndicatorEnabled(enabled); + + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(!enabled); + actionBar.setDisplayShowHomeEnabled(enabled); + actionBar.setHomeButtonEnabled(enabled); + } + + mDrawerToggle.syncState(); + } + + @Override + protected boolean isValidFragment(String fragmentName) { + return ExercisePreferenceFragment.class.getName().equals(fragmentName) + || TimerPreferenceFragment.class.getName().equals(fragmentName); + } + + private void showContent() { + selectNavigationItem(getNavigationDrawerID()); + + View mainContent = findViewById(R.id.main_content); + if (mainContent != null) { + mainContent.setAlpha(0); + mainContent.animate().alpha(1).setDuration(MAIN_CONTENT_FADEIN_DURATION); + } + } + + @Override + protected void onResume() { + super.onResume(); + + //showContent(); + } + + /** + * Start a new fragment. + * + * @param fragment The fragment to start + * @param push If true, the current fragment will be pushed onto the back stack. If false, + * the current fragment will be replaced. + */ + @Override + public void startPreferenceFragment(Fragment fragment, boolean push) { + FragmentTransaction transaction = getFragmentManager().beginTransaction(); + transaction.replace(R.id.prefs, fragment); + if (push) { + transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); + transaction.addToBackStack(":android:prefs"); + } else { + transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); + } + transaction.commitAllowingStateLoss(); + } + + /** + * Start a new fragment containing a preference panel. If the preferences + * are being displayed in multi-pane mode, the given fragment class will + * be instantiated and placed in the appropriate pane. If running in + * single-pane mode, a new activity will be launched in which to show the + * fragment. + * + * @param fragmentClass Full name of the class implementing the fragment. + * @param args Any desired arguments to supply to the fragment. + * @param titleRes Optional resource identifier of the title of this + * fragment. + * @param titleText Optional text of the title of this fragment. + * @param resultTo Optional fragment that result data should be sent to. + * If non-null, resultTo.onActivityResult() will be called when this + * preference panel is done. The launched panel must use + * {@link #finishPreferencePanel(Fragment, int, Intent)} when done. + * @param resultRequestCode If resultTo is non-null, this is the caller's + * request code to be received with the result. + */ + public void startPreferencePanel(String fragmentClass, Bundle args, @StringRes int titleRes, + CharSequence titleText, Fragment resultTo, int resultRequestCode) { + startWithFragment(fragmentClass, args, resultTo, resultRequestCode, titleRes, 0); } /** @@ -84,13 +383,12 @@ public class SettingsActivity extends BaseActivity { .getString(preference.getKey(), "")); } - @Override protected int getNavigationDrawerID() { return R.id.nav_settings; } + public static class ExercisePreferenceFragment extends PreferenceFragment { - public static class GeneralPreferenceFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -105,13 +403,48 @@ public class SettingsActivity extends BaseActivity { } @Override - public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); - if (id == android.R.id.home) { - startActivity(new Intent(getActivity(), SettingsActivity.class)); - return true; - } - return super.onOptionsItemSelected(item); + public void onResume() { + super.onResume(); + + SettingsActivity settingsActivity = (SettingsActivity)getActivity(); + if(settingsActivity != null) settingsActivity.setDrawerEnabled(false); } + +// @Override +// public boolean onOptionsItemSelected(MenuItem item) { +// int id = item.getItemId(); +// if (id == android.R.id.home) { +// Log.d("Fragment", "clicked"); +// onBackPressed(); +// return true; +// } +// return super.onOptionsItemSelected(item); +// } + } + + public static class TimerPreferenceFragment extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.pref_scheduler); + setHasOptionsMenu(true); + } + + @Override + public void onDestroy() { + super.onDestroy(); + Log.d("WTF", "destroy?"); + } + + // @Override +// public boolean onOptionsItemSelected(MenuItem item) { +// int id = item.getItemId(); +// if (id == android.R.id.home) { +// //startActivity(new Intent(getActivity(), SettingsActivity.class)); +// return true; +// } +// return super.onOptionsItemSelected(item); +// } + } } \ No newline at end of file diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/helper/AppCompatPreferenceActivity.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/helper/AppCompatPreferenceActivity.java new file mode 100644 index 0000000..2f7948b --- /dev/null +++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/helper/AppCompatPreferenceActivity.java @@ -0,0 +1,109 @@ +package org.secuso.privacyfriendlybreakreminder.activities.helper; + +import android.content.res.Configuration; +import android.os.Bundle; +import android.preference.PreferenceActivity; +import android.support.annotation.LayoutRes; +import android.support.annotation.Nullable; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatDelegate; +import android.support.v7.widget.Toolbar; +import android.view.MenuInflater; +import android.view.View; +import android.view.ViewGroup; + +/** + * A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls + * to be used with AppCompat. + */ +public abstract class AppCompatPreferenceActivity extends PreferenceActivity { + + private AppCompatDelegate mDelegate; + + @Override + protected void onCreate(Bundle savedInstanceState) { + getDelegate().installViewFactory(); + getDelegate().onCreate(savedInstanceState); + super.onCreate(savedInstanceState); + } + + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); + getDelegate().onPostCreate(savedInstanceState); + } + + public ActionBar getSupportActionBar() { + return getDelegate().getSupportActionBar(); + } + + public void setSupportActionBar(@Nullable Toolbar toolbar) { + getDelegate().setSupportActionBar(toolbar); + } + + @Override + public MenuInflater getMenuInflater() { + return getDelegate().getMenuInflater(); + } + + @Override + public void setContentView(@LayoutRes int layoutResID) { + getDelegate().setContentView(layoutResID); + } + + @Override + public void setContentView(View view) { + getDelegate().setContentView(view); + } + + @Override + public void setContentView(View view, ViewGroup.LayoutParams params) { + getDelegate().setContentView(view, params); + } + + @Override + public void addContentView(View view, ViewGroup.LayoutParams params) { + getDelegate().addContentView(view, params); + } + + @Override + protected void onPostResume() { + super.onPostResume(); + getDelegate().onPostResume(); + } + + @Override + protected void onTitleChanged(CharSequence title, int color) { + super.onTitleChanged(title, color); + getDelegate().setTitle(title); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + getDelegate().onConfigurationChanged(newConfig); + } + + @Override + protected void onStop() { + super.onStop(); + getDelegate().onStop(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + getDelegate().onDestroy(); + } + + public void invalidateOptionsMenu() { + getDelegate().invalidateOptionsMenu(); + } + + private AppCompatDelegate getDelegate() { + if (mDelegate == null) { + mDelegate = AppCompatDelegate.create(this, null); + } + return mDelegate; + } +} diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/helper/BaseActivity.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/helper/BaseActivity.java index 9014bd0..2b971cb 100644 --- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/helper/BaseActivity.java +++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/helper/BaseActivity.java @@ -162,7 +162,7 @@ public abstract class BaseActivity extends AppCompatActivity implements OnNaviga break; case R.id.nav_settings: intent = new Intent(this, SettingsActivity.class); - //intent.putExtra( PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.GeneralPreferenceFragment.class.getName() ); + //intent.putExtra( PreferenceActivity.EXTRA_SHOW_FRAGMENT, SettingsActivity.ExercisePreferenceFragment.class.getName() ); //intent.putExtra( PreferenceActivity.EXTRA_NO_HEADERS, true ); createBackStack(intent); break; diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/helper/ExpandableListAdapter.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/helper/ExpandableListAdapter.java new file mode 100644 index 0000000..f4012ef --- /dev/null +++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/activities/helper/ExpandableListAdapter.java @@ -0,0 +1,101 @@ +package org.secuso.privacyfriendlybreakreminder.activities.helper; + +import android.content.Context; +import android.graphics.Typeface; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseExpandableListAdapter; +import android.widget.TextView; + +import org.secuso.privacyfriendlybreakreminder.R; + +import java.util.HashMap; +import java.util.List; + +/** + * @author Christopher Beckmann + * @version 2.0 + * @since 26.10.2017 + * created 26.10.2017 + */ + +public class ExpandableListAdapter extends BaseExpandableListAdapter { + + private Context context; + private List expandableListTitle; + private HashMap> expandableListDetail; + + public ExpandableListAdapter(Context context, List expandableListTitle, + HashMap> expandableListDetail) { + this.context = context; + this.expandableListTitle = expandableListTitle; + this.expandableListDetail = expandableListDetail; + } + + @Override + public Object getChild(int listPosition, int expandedListPosition) { + return this.expandableListDetail.get(this.expandableListTitle.get(listPosition)).get(expandedListPosition); + } + + @Override + public long getChildId(int listPosition, int expandedListPosition) { + return expandedListPosition; + } + + @Override + public View getChildView(int listPosition, final int expandedListPosition, boolean isLastChild, View convertView, ViewGroup parent) { + + final String expandedListText = (String) getChild(listPosition, expandedListPosition); + if (convertView == null) { + LayoutInflater layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + convertView = layoutInflater.inflate(R.layout.help_list_item, parent); + } + TextView expandedListTextView = (TextView) convertView.findViewById(R.id.expandedListItem); + expandedListTextView.setText(expandedListText); + return convertView; + } + + @Override + public int getChildrenCount(int listPosition) { + return this.expandableListDetail.get(this.expandableListTitle.get(listPosition)).size(); + } + + @Override + public Object getGroup(int listPosition) { + return this.expandableListTitle.get(listPosition); + } + + @Override + public int getGroupCount() { + return this.expandableListTitle.size(); + } + + @Override + public long getGroupId(int listPosition) { + return listPosition; + } + + @Override + public View getGroupView(int listPosition, boolean isExpanded, View convertView, ViewGroup parent) { + String listTitle = (String) getGroup(listPosition); + if (convertView == null) { + LayoutInflater layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + convertView = layoutInflater.inflate(R.layout.help_list_group, null); + } + TextView listTitleTextView = (TextView) convertView.findViewById(R.id.listTitle); + listTitleTextView.setTypeface(null, Typeface.BOLD); + listTitleTextView.setText(listTitle); + return convertView; + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public boolean isChildSelectable(int listPosition, int expandedListPosition) { + return true; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/service/NotificationDeletedReceiver.java b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/service/NotificationDeletedReceiver.java new file mode 100644 index 0000000..e264683 --- /dev/null +++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/service/NotificationDeletedReceiver.java @@ -0,0 +1,25 @@ +package org.secuso.privacyfriendlybreakreminder.service; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +/** + * @author Christopher Beckmann + * @version 2.0 + * @since 26.10.2017 + * created 26.10.2017 + */ +public class NotificationDeletedReceiver extends BroadcastReceiver { + + private static final String TAG = NotificationDeletedReceiver.class.getSimpleName(); + + @Override + public void onReceive(Context context, Intent intent) { + + // TODO: Notification was swiped away. + Log.d(TAG, "Notification swiped away"); + + } +} 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 264f978..419b674 100644 --- a/app/src/main/java/org/secuso/privacyfriendlybreakreminder/service/TimerService.java +++ b/app/src/main/java/org/secuso/privacyfriendlybreakreminder/service/TimerService.java @@ -103,10 +103,9 @@ public class TimerService extends Service { .setDefaults(Notification.DEFAULT_LIGHTS) .setVibrate(new long[] { 0, 1000, 1000, 1000, 1000, 1000, 1000 }) .setSound(Settings.System.DEFAULT_NOTIFICATION_URI) - .setOnlyAlertOnce(false); + .setOnlyAlertOnce(false) + .setDeleteIntent(PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(this, NotificationDeletedReceiver.class), 0)); notificationManager.notify(NOTIFICATION_ID, builder.build()); - - // TODO: show decider activity?! } @Override diff --git a/app/src/main/res/drawable/BreakReminder_23.png b/app/src/main/res/drawable/BreakReminder_23.png index f0abd6f..352c299 100644 Binary files a/app/src/main/res/drawable/BreakReminder_23.png and b/app/src/main/res/drawable/BreakReminder_23.png differ diff --git a/app/src/main/res/drawable/BreakReminder_56.png b/app/src/main/res/drawable/BreakReminder_56.png index aaf53af..f1774d6 100644 Binary files a/app/src/main/res/drawable/BreakReminder_56.png and b/app/src/main/res/drawable/BreakReminder_56.png differ diff --git a/app/src/main/res/drawable/ic_notifications_black_24dp.xml b/app/src/main/res/drawable/ic_notifications_black_24dp.xml new file mode 100644 index 0000000..e3400cf --- /dev/null +++ b/app/src/main/res/drawable/ic_notifications_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_sync_black_24dp.xml b/app/src/main/res/drawable/ic_sync_black_24dp.xml new file mode 100644 index 0000000..5a283aa --- /dev/null +++ b/app/src/main/res/drawable/ic_sync_black_24dp.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_help.xml b/app/src/main/res/layout/activity_help.xml index b43ba00..985f85a 100644 --- a/app/src/main/res/layout/activity_help.xml +++ b/app/src/main/res/layout/activity_help.xml @@ -26,10 +26,14 @@ android:orientation="vertical" tools:context=".activities.HelpActivity" android:weightSum="1"> - + + diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 8931963..2596181 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -21,13 +21,51 @@ android:id="@+id/main_content" android:layout_height="match_parent"> - + android:layout_height="0px" + android:layout_weight="1"> + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/help_list_group.xml b/app/src/main/res/layout/help_list_group.xml new file mode 100644 index 0000000..a68ee28 --- /dev/null +++ b/app/src/main/res/layout/help_list_group.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/help_list_item.xml b/app/src/main/res/layout/help_list_item.xml new file mode 100644 index 0000000..c7932af --- /dev/null +++ b/app/src/main/res/layout/help_list_item.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index fa284f6..28388fd 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -42,7 +42,7 @@ Auswahl der Übungen Auswahl des Profils Zufall - Profile bearbeiten + Profile bearbeiten Benachrichtigungen Lautlos Profil Name diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index e53ece4..21319d2 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -32,7 +32,7 @@ Choisissez des exercices Choisissez un profil Hasard - Modifier les profils + Modifier les profils Notifications Silencieux Nom du profil diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 9393e7b..729b57b 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -36,7 +36,7 @@ Запустить/Остановить часы Случайный Уведомления - Редактирование профилей + Редактирование профилей Случайный,90,5,false,Руки.Ноги.Голова.Шея.Таз.Позвоночник.Туловище.;Талия вверх,90,15,true,Руки.Шея.Голова.;Корпус,30,5,true,Позвоночник.Туловище.;Нижний Корпус,30,5,true,Ноги.Таз.; Без звука Имя профиля diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index add0afd..3d7587a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -156,6 +156,81 @@ %02d Exercise time (in Seconds) Keep screen on during exercise + exercise settings + schedule an exercise + enable exercise schedule + Schedule Time + What is Privacy Friendly Break Reminder? + Privacy Friendly Break Reminder is an app, that reminds you to take breaks during your work sessions. It allows you to select exercises, that are then shown during your break time. + Which permissions does the app require? + The app only requests permission to control the vibration of the device to make the break alarm more distinct. + Schedule Times + Exercise Settings + Settings + + + + + General + + Enable social recommendations + Recommendations for people to contact + based on your message history + + + Display name + John Smith + + Add friends to messages + + Always + When possible + Never + + + 1 + 0 + -1 + + + + Data & sync + + Sync frequency + + 15 minutes + 30 minutes + 1 hour + 3 hours + 6 hours + Never + + + 15 + 30 + 60 + 180 + 360 + -1 + + + + Entry 1 + Entry 2 + Entry 3 + + + + 1 + 2 + 3 + + + + + System sync settings + + New message notifications diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index 43af0cc..3c7cefe 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -1,16 +1,20 @@ - + - + + + + + diff --git a/app/src/main/res/xml/pref_headers.xml b/app/src/main/res/xml/pref_headers.xml index 54d52fd..1e18289 100644 --- a/app/src/main/res/xml/pref_headers.xml +++ b/app/src/main/res/xml/pref_headers.xml @@ -3,8 +3,13 @@
+ android:title="@string/pref_header_exercises" /> + +
diff --git a/app/src/main/res/xml/pref_scheduler.xml b/app/src/main/res/xml/pref_scheduler.xml new file mode 100644 index 0000000..d174040 --- /dev/null +++ b/app/src/main/res/xml/pref_scheduler.xml @@ -0,0 +1,20 @@ + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index c2eea8e..63f0f00 100644 --- a/build.gradle +++ b/build.gradle @@ -3,9 +3,13 @@ buildscript { repositories { jcenter() + maven { + url 'https://maven.google.com/' + name 'Google' + } } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'com.android.tools.build:gradle:3.0.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 59ff6e8..0730a83 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Aug 12 14:48:24 CEST 2017 +#Fri Oct 27 05:33:03 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip