From ce76a94a0621cd4bf82883e5cfb125b590afc1cf Mon Sep 17 00:00:00 2001 From: wolkenschieber Date: Thu, 6 Apr 2017 19:22:20 +0200 Subject: [PATCH 1/2] * Cancel alarm and reschedule for next week, if data entered because alarm timestamp * Remove notification on data input, if still present --- android_app/android_app.iml | 19 --- android_app/app/app.iml | 122 -------------- .../core/IScaleDatabaseEntryListener.java | 8 + .../com/health/openscale/core/OpenScale.java | 2 + .../health/openscale/core/ScaleDatabase.java | 25 +++ .../java/com/health/openscale/core/Util.java | 16 ++ .../alarm/AlarmDatabaseEntryListener.java | 28 ++++ .../openscale/core/alarm/AlarmEntry.java | 77 +++++++++ .../core/alarm/AlarmEntryReader.java | 91 +++++++++++ .../openscale/core/alarm/AlarmHandler.java | 149 ++++++++++++++++++ .../openscale/gui/ReminderBootReceiver.java | 46 ++---- .../gui/preferences/ReminderPreferences.java | 108 +------------ android_app/build.gradle | 2 +- android_app/openScale.iml | 21 --- 14 files changed, 417 insertions(+), 297 deletions(-) delete mode 100644 android_app/android_app.iml delete mode 100644 android_app/app/app.iml create mode 100644 android_app/app/src/main/java/com/health/openscale/core/IScaleDatabaseEntryListener.java create mode 100644 android_app/app/src/main/java/com/health/openscale/core/Util.java create mode 100644 android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmDatabaseEntryListener.java create mode 100644 android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmEntry.java create mode 100644 android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmEntryReader.java create mode 100644 android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmHandler.java delete mode 100644 android_app/openScale.iml diff --git a/android_app/android_app.iml b/android_app/android_app.iml deleted file mode 100644 index a0a56048..00000000 --- a/android_app/android_app.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android_app/app/app.iml b/android_app/app/app.iml deleted file mode 100644 index 01e031b8..00000000 --- a/android_app/app/app.iml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android_app/app/src/main/java/com/health/openscale/core/IScaleDatabaseEntryListener.java b/android_app/app/src/main/java/com/health/openscale/core/IScaleDatabaseEntryListener.java new file mode 100644 index 00000000..2286f5ca --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/IScaleDatabaseEntryListener.java @@ -0,0 +1,8 @@ +package com.health.openscale.core; + +import android.content.Context; + +public interface IScaleDatabaseEntryListener +{ + void entryChanged(Context context, ScaleData data); +} diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index 0340d085..4530476d 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -23,6 +23,7 @@ import android.preference.PreferenceManager; import android.support.v4.app.Fragment; import android.util.Log; +import com.health.openscale.core.alarm.AlarmDatabaseEntryListener; import com.health.openscale.gui.FragmentUpdateListener; import java.io.BufferedReader; @@ -61,6 +62,7 @@ public class OpenScale { private OpenScale(Context con) { context = con; scaleDB = new ScaleDatabase(context); + scaleDB.addEntryListener(new AlarmDatabaseEntryListener()); scaleUserDB = new ScaleUserDatabase(context); btCom = null; fragmentList = new ArrayList<>(); diff --git a/android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java b/android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java index c1a55819..82ceaa8e 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java +++ b/android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java @@ -28,6 +28,8 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; public class ScaleDatabase extends SQLiteOpenHelper { @@ -84,9 +86,14 @@ public class ScaleDatabase extends SQLiteOpenHelper { private final SQLiteDatabase dbRead = getReadableDatabase(); private SimpleDateFormat formatDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); + + private Context context; + private List entryListeners; public ScaleDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); + this.context = context; + entryListeners = new LinkedList<>(); } @Override @@ -140,6 +147,7 @@ public class ScaleDatabase extends SQLiteOpenHelper { try { db.insertOrThrow(TABLE_NAME, null, values); + notifyEntryListeners(scaleData); } catch (SQLException e) { @@ -167,6 +175,7 @@ public class ScaleDatabase extends SQLiteOpenHelper { values.put(COLUMN_NAME_ENABLE, 1); dbWrite.update(TABLE_NAME, values, COLUMN_NAME_ID + "=" + id, null); + notifyEntryListeners(scaleData); } public ScaleData getDataEntry(long id) @@ -319,4 +328,20 @@ public class ScaleDatabase extends SQLiteOpenHelper { return scaleData; } + + public void addEntryListener(IScaleDatabaseEntryListener listener) + { + if (!entryListeners.contains(listener)) entryListeners.add(listener); + } + + public void removeEntryListener( IScaleDatabaseEntryListener listener) + { + entryListeners.remove(listener); + } + + private void notifyEntryListeners(ScaleData data) + { + for (IScaleDatabaseEntryListener listener : entryListeners) + listener.entryChanged(context, data); + } } diff --git a/android_app/app/src/main/java/com/health/openscale/core/Util.java b/android_app/app/src/main/java/com/health/openscale/core/Util.java new file mode 100644 index 00000000..ef657189 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/Util.java @@ -0,0 +1,16 @@ +package com.health.openscale.core; + +import java.util.Calendar; + +public class Util +{ + public static boolean isSameDate(Calendar c1, Calendar c2) + { + int[] dateFields = {Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH}; + for (int dateField : dateFields) + { + if (c1.get(dateField) != c2.get(dateField)) return false; + } + return true; + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmDatabaseEntryListener.java b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmDatabaseEntryListener.java new file mode 100644 index 00000000..ec6c0d1a --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmDatabaseEntryListener.java @@ -0,0 +1,28 @@ +package com.health.openscale.core.alarm; + +import android.content.Context; + +import com.health.openscale.core.IScaleDatabaseEntryListener; +import com.health.openscale.core.ScaleData; +import com.health.openscale.core.Util; + +import java.util.Calendar; + +public class AlarmDatabaseEntryListener implements IScaleDatabaseEntryListener +{ + @Override + public void entryChanged(Context context, ScaleData data) + { + long dataMillis = data.date_time.getTime(); + + Calendar dataTimestamp = Calendar.getInstance(); + dataTimestamp.setTimeInMillis(dataMillis); + + if(Util.isSameDate(dataTimestamp, Calendar.getInstance())) + { + AlarmHandler alarmHandler = new AlarmHandler(); + alarmHandler.cancelAlarmNotification(context); + alarmHandler.cancelAndRescheduleAlarmForNextWeek( context, dataTimestamp ); + } + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmEntry.java b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmEntry.java new file mode 100644 index 00000000..7656936f --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmEntry.java @@ -0,0 +1,77 @@ +package com.health.openscale.core.alarm; + +import android.support.annotation.NonNull; + +import java.util.Calendar; + +public class AlarmEntry implements Comparable +{ + private final int dayOfWeek; + private final long timeInMillis; + + public AlarmEntry(int dayOfWeek, long timeInMillis) + { + this.dayOfWeek = dayOfWeek; + this.timeInMillis = timeInMillis; + } + + public int getDayOfWeek() + { + return dayOfWeek; + } + + private long getTimeInMillis() + { + return timeInMillis; + } + + public Calendar getNextTimestamp() + { + // We just want the time *not* the date + Calendar nextAlarmTimestamp = Calendar.getInstance(); + nextAlarmTimestamp.setTimeInMillis(getTimeInMillis()); + + Calendar alarmCal = Calendar.getInstance(); + alarmCal.set(Calendar.HOUR_OF_DAY, nextAlarmTimestamp.get(Calendar.HOUR_OF_DAY)); + alarmCal.set(Calendar.MINUTE, nextAlarmTimestamp.get(Calendar.MINUTE)); + alarmCal.set(Calendar.SECOND, 0); + alarmCal.set(Calendar.DAY_OF_WEEK, getDayOfWeek()); + + // Check we aren't setting it in the past which would trigger it to fire instantly + if (alarmCal.before(Calendar.getInstance())) alarmCal.add(Calendar.DAY_OF_YEAR, 7); + return alarmCal; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AlarmEntry that = (AlarmEntry) o; + + if (dayOfWeek != that.dayOfWeek) return false; + return timeInMillis == that.timeInMillis; + } + + @Override + public int hashCode() + { + int result = dayOfWeek; + result = 31 * result + (int) (timeInMillis ^ (timeInMillis >>> 32)); + return result; + } + + @Override + public int compareTo(@NonNull AlarmEntry o) + { + int rc = compare(dayOfWeek, o.dayOfWeek); + if (rc == 0) rc = compare(timeInMillis, o.timeInMillis); + return rc; + } + + private int compare(long x, long y) + { + return (x < y) ? -1 : ((x == y) ? 0 : 1); + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmEntryReader.java b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmEntryReader.java new file mode 100644 index 00000000..8a0197c7 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmEntryReader.java @@ -0,0 +1,91 @@ +package com.health.openscale.core.alarm; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import com.health.openscale.R; + +import java.util.Calendar; +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; + +import static com.health.openscale.gui.preferences.ReminderPreferences.PREFERENCE_KEY_REMINDER_NOTIFY_TEXT; +import static com.health.openscale.gui.preferences.ReminderPreferences.PREFERENCE_KEY_REMINDER_TIME; +import static com.health.openscale.gui.preferences.ReminderPreferences.PREFERENCE_KEY_REMINDER_WEEKDAYS; + +public class AlarmEntryReader +{ + private Set alarmEntries; + private String alarmNotificationText; + + private AlarmEntryReader(Set alarmEntries, String alarmNotificationText) + { + this.alarmEntries = alarmEntries; + this.alarmNotificationText = alarmNotificationText; + } + + public Set getEntries() + { + return alarmEntries; + } + + public String getNotificationText() + { + return alarmNotificationText; + } + + public static AlarmEntryReader construct(Context context) + { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + + Set reminderWeekdays = prefs.getStringSet(PREFERENCE_KEY_REMINDER_WEEKDAYS, new HashSet()); + Long reminderTimeInMillis = prefs.getLong(PREFERENCE_KEY_REMINDER_TIME, System.currentTimeMillis()); + String notifyText = prefs.getString(PREFERENCE_KEY_REMINDER_NOTIFY_TEXT, + context.getResources().getString(R.string.default_value_reminder_notify_text)); + + Set alarms = new TreeSet<>(); + + for (String dayOfWeek : reminderWeekdays) + { + AlarmEntry alarm = getAlarmEntry(dayOfWeek, reminderTimeInMillis); + alarms.add(alarm); + } + + return new AlarmEntryReader(alarms, notifyText); + } + + private static AlarmEntry getAlarmEntry(String dayOfWeek, Long reminderTimeInMillis) + { + AlarmEntry alarmEntry; + switch (dayOfWeek) + { + case "Monday": + alarmEntry = new AlarmEntry(Calendar.MONDAY, reminderTimeInMillis); + break; + case "Tuesday": + alarmEntry = new AlarmEntry(Calendar.TUESDAY, reminderTimeInMillis); + break; + case "Wednesday": + alarmEntry = new AlarmEntry(Calendar.WEDNESDAY, reminderTimeInMillis); + break; + case "Thursday": + alarmEntry = new AlarmEntry(Calendar.THURSDAY, reminderTimeInMillis); + break; + case "Friday": + alarmEntry = new AlarmEntry(Calendar.FRIDAY, reminderTimeInMillis); + break; + case "Saturday": + alarmEntry = new AlarmEntry(Calendar.SATURDAY, reminderTimeInMillis); + break; + default: + case "Sunday": + alarmEntry = new AlarmEntry(Calendar.SUNDAY, reminderTimeInMillis); + break; + } + return alarmEntry; + } + + +} diff --git a/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmHandler.java b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmHandler.java new file mode 100644 index 00000000..5042f82d --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmHandler.java @@ -0,0 +1,149 @@ +package com.health.openscale.core.alarm; + +import android.app.AlarmManager; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.service.notification.StatusBarNotification; +import android.support.v4.app.NotificationCompat; +import android.util.Log; + +import com.health.openscale.R; +import com.health.openscale.core.Util; +import com.health.openscale.gui.MainActivity; +import com.health.openscale.gui.ReminderBootReceiver; + +import java.util.Calendar; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import static android.content.Context.NOTIFICATION_SERVICE; + +public class AlarmHandler +{ + public static final String INTENT_EXTRA_ALARM = "alarmIntent"; + private static final int ALARM_NOTIFICATION_ID = 0x01; + private static final String LOG_TAG = "AlarmBuilder"; + + public void scheduleAlarms(Context context) + { + AlarmEntryReader reader = AlarmEntryReader.construct(context); + Set alarmEntries = reader.getEntries(); + + disableAllAlarms(context); + enableAlarms(context, alarmEntries); + } + + private void enableAlarms(Context context, Set alarmEntries) + { + for (AlarmEntry alarmEntry : alarmEntries) + enableAlarm(context, alarmEntry); + } + + private void enableAlarm(Context context, AlarmEntry alarmEntry) + { + int dayOfWeek = alarmEntry.getDayOfWeek(); + Calendar nextAlarmTimestamp = alarmEntry.getNextTimestamp(); + + setRepeatingAlarm(context, dayOfWeek, nextAlarmTimestamp); + } + + private void setRepeatingAlarm(Context context, int dayOfWeek, Calendar nextAlarmTimestamp) + { + Log.d(LOG_TAG, "Set repeating alarm for " + nextAlarmTimestamp.getTime()); + PendingIntent alarmPendingIntent = getPendingAlarmIntent(context, dayOfWeek); + AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, nextAlarmTimestamp.getTimeInMillis(), + AlarmManager.INTERVAL_DAY * 7, alarmPendingIntent); + } + + private List getWeekdaysPendingAlarmIntent(Context context) + { + final int[] dayOfWeeks = + {Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY, Calendar.FRIDAY, + Calendar.SATURDAY, Calendar.SUNDAY}; + List pendingIntents = new LinkedList<>(); + for (int dayOfWeek : dayOfWeeks) + pendingIntents.add(getPendingAlarmIntent(context, dayOfWeek)); + return pendingIntents; + } + + private PendingIntent getPendingAlarmIntent(Context context, int dayOfWeek) + { + Intent alarmIntent = new Intent(context, ReminderBootReceiver.class); + alarmIntent.putExtra(INTENT_EXTRA_ALARM, true); + + return PendingIntent.getBroadcast(context, dayOfWeek, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } + + public void disableAllAlarms(Context context) + { + AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + List pendingIntents = getWeekdaysPendingAlarmIntent(context); + for (PendingIntent pendingIntent : pendingIntents) + alarmMgr.cancel(pendingIntent); + } + + public void cancelAndRescheduleAlarmForNextWeek(Context context, Calendar timestamp) + { + AlarmEntryReader reader = AlarmEntryReader.construct(context); + Set alarmEntries = reader.getEntries(); + for (AlarmEntry entry : alarmEntries) + { + Calendar nextAlarmTimestamp = entry.getNextTimestamp(); + + if (Util.isSameDate(timestamp, nextAlarmTimestamp)) + { + int dayOfWeek = entry.getDayOfWeek(); + PendingIntent alarmPendingIntent = getPendingAlarmIntent(context, dayOfWeek); + AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + alarmMgr.cancel(alarmPendingIntent); + + nextAlarmTimestamp.add(Calendar.DATE, 7); + setRepeatingAlarm(context, dayOfWeek, nextAlarmTimestamp); + } + } + } + + public void showAlarmNotification(Context context) + { + AlarmEntryReader reader = AlarmEntryReader.construct(context); + String notifyText = reader.getNotificationText(); + + Intent notifyIntent = new Intent(context, MainActivity.class); + + PendingIntent notifyPendingIntent = + PendingIntent.getActivity(context, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT); + + NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context); + Notification notification = mBuilder.setSmallIcon(R.drawable.ic_launcher) + .setContentTitle(context.getString(R.string.app_name)) + .setContentText(notifyText) + .setAutoCancel(true) + .setContentIntent(notifyPendingIntent) + .build(); + + NotificationManager mNotifyMgr = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); + mNotifyMgr.notify(ALARM_NOTIFICATION_ID, notification); + } + + public void cancelAlarmNotification(Context context) + { + NotificationManager mNotifyMgr = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + { + StatusBarNotification[] activeNotifications = mNotifyMgr.getActiveNotifications(); + for (StatusBarNotification notification : activeNotifications) + { + if (notification.getId() == ALARM_NOTIFICATION_ID) mNotifyMgr.cancel(ALARM_NOTIFICATION_ID); + } + } + else mNotifyMgr.cancel(ALARM_NOTIFICATION_ID); + } + + +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/ReminderBootReceiver.java b/android_app/app/src/main/java/com/health/openscale/gui/ReminderBootReceiver.java index 7ac484e8..f43bce46 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/ReminderBootReceiver.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/ReminderBootReceiver.java @@ -16,51 +16,31 @@ package com.health.openscale.gui; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.support.v4.app.NotificationCompat; -import com.health.openscale.R; -import com.health.openscale.gui.preferences.ReminderPreferences; - -import static android.content.Context.NOTIFICATION_SERVICE; +import com.health.openscale.core.alarm.AlarmHandler; public class ReminderBootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - if (intent.hasExtra(ReminderPreferences.INTENT_EXTRA_ALARM)) - { - //Log.d(ReminderBootReceiver.class.getSimpleName(), "Received alarm intent"); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + if (intent.hasExtra(AlarmHandler.INTENT_EXTRA_ALARM)) handleAlarm(context); - String notifyText = prefs.getString(ReminderPreferences.PREFERENCE_KEY_REMINDER_NOTIFY_TEXT, - context.getResources().getString(R.string.default_value_reminder_notify_text)); + if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) scheduleAlarms(context); + } - NotificationCompat.Builder mBuilder = - new NotificationCompat.Builder(context).setSmallIcon(R.drawable.ic_launcher) - .setContentTitle(context.getString(R.string.app_name)) - .setContentText(notifyText) - .setAutoCancel(true); + private void handleAlarm(Context context) + { + AlarmHandler alarmHandler = new AlarmHandler(); + alarmHandler.showAlarmNotification(context); + } - Intent notifyIntent = new Intent(context, MainActivity.class); - - PendingIntent notifyPendingIntent = - PendingIntent.getActivity(context, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT); - - mBuilder.setContentIntent(notifyPendingIntent); - - NotificationManager mNotifyMgr = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); - mNotifyMgr.notify(0x01, mBuilder.build()); - } - - if (intent.getAction() != null && intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) - ReminderPreferences.scheduleAlarms(context); + private void scheduleAlarms(Context context) + { + AlarmHandler alarmHandler = new AlarmHandler(); + alarmHandler.scheduleAlarms(context); } } diff --git a/android_app/app/src/main/java/com/health/openscale/gui/preferences/ReminderPreferences.java b/android_app/app/src/main/java/com/health/openscale/gui/preferences/ReminderPreferences.java index 08f91ce5..eb354c2f 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/preferences/ReminderPreferences.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/preferences/ReminderPreferences.java @@ -15,11 +15,7 @@ */ package com.health.openscale.gui.preferences; -import android.app.AlarmManager; -import android.app.PendingIntent; import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Bundle; @@ -30,120 +26,29 @@ import android.preference.MultiSelectListPreference; import android.preference.Preference; import android.preference.PreferenceFragment; import android.preference.PreferenceGroup; -import android.preference.PreferenceManager; import com.health.openscale.R; +import com.health.openscale.core.alarm.AlarmHandler; import com.health.openscale.gui.ReminderBootReceiver; import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Set; public class ReminderPreferences extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { - public static final String INTENT_EXTRA_ALARM = "alarmIntent"; + public static final String PREFERENCE_KEY_REMINDER_NOTIFY_TEXT = "reminderNotifyText"; - + public static final String PREFERENCE_KEY_REMINDER_WEEKDAYS = "reminderWeekdays"; + public static final String PREFERENCE_KEY_REMINDER_TIME = "reminderTime"; private static final String PREFERENCE_KEY_REMINDER_ENABLE = "reminderEnable"; - private static final String PREFERENCE_KEY_REMINDER_WEEKDAYS = "reminderWeekdays"; - private static final String PREFERENCE_KEY_REMINDER_TIME = "reminderTime"; - - - private static ArrayList pendingAlarms = new ArrayList<>(); private CheckBoxPreference reminderEnable; private MultiSelectListPreference reminderWeekdays; private TimePreferenceDialog reminderTime; private EditTextPreference reminderNotifyText; - public static void scheduleAlarms(Context context) - { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - - Set reminderWeekdays = prefs.getStringSet(PREFERENCE_KEY_REMINDER_WEEKDAYS, new HashSet()); - Long reminderTimeInMillis = prefs.getLong(PREFERENCE_KEY_REMINDER_TIME, System.currentTimeMillis()); - - Iterator iterWeekdays = reminderWeekdays.iterator(); - - disableAllAlarms(context); - - while (iterWeekdays.hasNext()) - { - String strWeekdays = iterWeekdays.next(); - switch (strWeekdays) - { - case "Monday": - pendingAlarms.add(enableAlarm(context, Calendar.MONDAY, reminderTimeInMillis)); - break; - case "Tuesday": - pendingAlarms.add(enableAlarm(context, Calendar.TUESDAY, reminderTimeInMillis)); - break; - case "Wednesday": - pendingAlarms.add(enableAlarm(context, Calendar.WEDNESDAY, reminderTimeInMillis)); - break; - case "Thursday": - pendingAlarms.add(enableAlarm(context, Calendar.THURSDAY, reminderTimeInMillis)); - break; - case "Friday": - pendingAlarms.add(enableAlarm(context, Calendar.FRIDAY, reminderTimeInMillis)); - break; - case "Saturday": - pendingAlarms.add(enableAlarm(context, Calendar.SATURDAY, reminderTimeInMillis)); - break; - case "Sunday": - pendingAlarms.add(enableAlarm(context, Calendar.SUNDAY, reminderTimeInMillis)); - break; - } - } - } - - public static PendingIntent enableAlarm(Context context, int dayOfWeek, long timeInMillis) - { - // We just want the time *not* the date - Calendar timeCal = Calendar.getInstance(); - timeCal.setTimeInMillis(timeInMillis); - - Calendar alarmCal = Calendar.getInstance(); - alarmCal.set(Calendar.HOUR_OF_DAY, timeCal.get(Calendar.HOUR_OF_DAY)); - alarmCal.set(Calendar.MINUTE, timeCal.get(Calendar.MINUTE)); - alarmCal.set(Calendar.DAY_OF_WEEK, dayOfWeek); - - // Check we aren't setting it in the past which would trigger it to fire instantly - if (alarmCal.before(Calendar.getInstance())) - { - alarmCal.add(Calendar.DAY_OF_YEAR, 7); - } - - //Log.d(ReminderPreferences.class.getSimpleName(), "Set " + dayOfWeek + " alarm to " + alarmCal.getTime()); - AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - - Intent alarmIntent = new Intent(context, ReminderBootReceiver.class); - alarmIntent.putExtra(INTENT_EXTRA_ALARM, true); - - PendingIntent alarmPendingIntent = - PendingIntent.getBroadcast(context, dayOfWeek, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT); - - alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, alarmCal.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, - alarmPendingIntent); - - return alarmPendingIntent; - } - - public static void disableAllAlarms(Context context) - { - AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - - for (int i = 0; i < pendingAlarms.size(); i++) - { - alarmMgr.cancel(pendingAlarms.get(i)); - } - - pendingAlarms.clear(); - } @Override public void onCreate(Bundle savedInstanceState) @@ -203,9 +108,10 @@ public class ReminderPreferences extends PreferenceFragment ComponentName receiver = new ComponentName(getActivity().getApplicationContext(), ReminderBootReceiver.class); PackageManager pm = getActivity().getApplicationContext().getPackageManager(); + AlarmHandler alarmHandler = new AlarmHandler(); if (reminderEnable.isChecked()) { - scheduleAlarms(getActivity()); + alarmHandler.scheduleAlarms(getActivity()); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); @@ -216,7 +122,7 @@ public class ReminderPreferences extends PreferenceFragment } else { - disableAllAlarms(getActivity()); + alarmHandler.disableAllAlarms(getActivity()); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); diff --git a/android_app/build.gradle b/android_app/build.gradle index 97e8b8e3..1c2d0680 100644 --- a/android_app/build.gradle +++ b/android_app/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:2.3.1' } } diff --git a/android_app/openScale.iml b/android_app/openScale.iml deleted file mode 100644 index 2a022014..00000000 --- a/android_app/openScale.iml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - From 3003b0a75ffd2a6f12bcd948fc6af9513ba53832 Mon Sep 17 00:00:00 2001 From: OliE Date: Fri, 7 Apr 2017 17:14:16 +0200 Subject: [PATCH 2/2] refactored file structure and alarm handling. --- android_app/app/src/main/AndroidManifest.xml | 8 +- .../core/IScaleDatabaseEntryListener.java | 8 - .../com/health/openscale/core/OpenScale.java | 20 +- .../java/com/health/openscale/core/Util.java | 16 - .../alarm/AlarmDatabaseEntryListener.java | 28 - .../openscale/core/alarm/AlarmHandler.java | 29 +- .../alarm}/ReminderBootReceiver.java | 4 +- .../BluetoothCommunication.java | 6 +- .../BluetoothCustomOpenScale.java | 8 +- .../{ => bluetooth}/BluetoothMiScale.java | 8 +- .../core/{ => database}/ScaleDatabase.java | 29 +- .../{ => database}/ScaleUserDatabase.java | 4 +- .../core/{ => datatypes}/ScaleCalculator.java | 2 +- .../core/{ => datatypes}/ScaleData.java | 2 +- .../core/{ => datatypes}/ScaleUser.java | 2 +- .../{ => evaluation}/EvaluationResult.java | 2 +- .../{ => evaluation}/EvaluationSheet.java | 4 +- .../health/openscale/gui/MainActivity.java | 9 +- .../health/openscale/gui/MeasurementView.java | 679 ------------------ .../{ => activities}/DataEntryActivity.java | 11 +- .../{ => activities}/SettingsActivity.java | 2 +- .../UserSettingsActivity.java | 4 +- .../FragmentUpdateListener.java | 4 +- .../gui/{ => fragments}/GraphFragment.java | 5 +- .../gui/{ => fragments}/OverviewFragment.java | 19 +- .../gui/{ => fragments}/TableFragment.java | 5 +- .../gui/preferences/ReminderPreferences.java | 2 +- .../gui/preferences/UsersPreferences.java | 4 +- .../gui/views/BMIMeasurementView.java | 61 ++ .../gui/views/FatMeasurementView.java | 58 ++ .../gui/views/HipMeasurementView.java | 58 ++ .../gui/{ => views}/LinearGaugeView.java | 2 +- .../openscale/gui/views/MeasurementView.java | 244 +++++++ .../gui/views/MuscleMeasurementView.java | 58 ++ .../gui/views/WHRMeasurementView.java | 62 ++ .../gui/views/WHtRMeasurementView.java | 61 ++ .../gui/views/WaistMeasurementView.java | 58 ++ .../gui/views/WaterMeasurementView.java | 58 ++ .../gui/views/WeightMeasurementView.java | 59 ++ 39 files changed, 895 insertions(+), 808 deletions(-) delete mode 100644 android_app/app/src/main/java/com/health/openscale/core/IScaleDatabaseEntryListener.java delete mode 100644 android_app/app/src/main/java/com/health/openscale/core/Util.java delete mode 100644 android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmDatabaseEntryListener.java rename android_app/app/src/main/java/com/health/openscale/{gui => core/alarm}/ReminderBootReceiver.java (94%) rename android_app/app/src/main/java/com/health/openscale/core/{ => bluetooth}/BluetoothCommunication.java (91%) rename android_app/app/src/main/java/com/health/openscale/core/{ => bluetooth}/BluetoothCustomOpenScale.java (97%) rename android_app/app/src/main/java/com/health/openscale/core/{ => bluetooth}/BluetoothMiScale.java (98%) rename android_app/app/src/main/java/com/health/openscale/core/{ => database}/ScaleDatabase.java (93%) rename android_app/app/src/main/java/com/health/openscale/core/{ => database}/ScaleUserDatabase.java (98%) rename android_app/app/src/main/java/com/health/openscale/core/{ => datatypes}/ScaleCalculator.java (94%) rename android_app/app/src/main/java/com/health/openscale/core/{ => datatypes}/ScaleData.java (97%) rename android_app/app/src/main/java/com/health/openscale/core/{ => datatypes}/ScaleUser.java (97%) rename android_app/app/src/main/java/com/health/openscale/core/{ => evaluation}/EvaluationResult.java (96%) rename android_app/app/src/main/java/com/health/openscale/core/{ => evaluation}/EvaluationSheet.java (99%) delete mode 100644 android_app/app/src/main/java/com/health/openscale/gui/MeasurementView.java rename android_app/app/src/main/java/com/health/openscale/gui/{ => activities}/DataEntryActivity.java (96%) rename android_app/app/src/main/java/com/health/openscale/gui/{ => activities}/SettingsActivity.java (96%) rename android_app/app/src/main/java/com/health/openscale/gui/{ => activities}/UserSettingsActivity.java (99%) rename android_app/app/src/main/java/com/health/openscale/gui/{ => fragments}/FragmentUpdateListener.java (89%) rename android_app/app/src/main/java/com/health/openscale/gui/{ => fragments}/GraphFragment.java (98%) rename android_app/app/src/main/java/com/health/openscale/gui/{ => fragments}/OverviewFragment.java (97%) rename android_app/app/src/main/java/com/health/openscale/gui/{ => fragments}/TableFragment.java (99%) create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/views/BMIMeasurementView.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/views/FatMeasurementView.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/views/HipMeasurementView.java rename android_app/app/src/main/java/com/health/openscale/gui/{ => views}/LinearGaugeView.java (99%) create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/views/MuscleMeasurementView.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/views/WHRMeasurementView.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/views/WHtRMeasurementView.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/views/WaistMeasurementView.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/views/WaterMeasurementView.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/views/WeightMeasurementView.java diff --git a/android_app/app/src/main/AndroidManifest.xml b/android_app/app/src/main/AndroidManifest.xml index fd039283..d053ba54 100644 --- a/android_app/app/src/main/AndroidManifest.xml +++ b/android_app/app/src/main/AndroidManifest.xml @@ -24,12 +24,12 @@ - - - + + - + diff --git a/android_app/app/src/main/java/com/health/openscale/core/IScaleDatabaseEntryListener.java b/android_app/app/src/main/java/com/health/openscale/core/IScaleDatabaseEntryListener.java deleted file mode 100644 index 2286f5ca..00000000 --- a/android_app/app/src/main/java/com/health/openscale/core/IScaleDatabaseEntryListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.health.openscale.core; - -import android.content.Context; - -public interface IScaleDatabaseEntryListener -{ - void entryChanged(Context context, ScaleData data); -} diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index 4530476d..d829df49 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -23,8 +23,15 @@ import android.preference.PreferenceManager; import android.support.v4.app.Fragment; import android.util.Log; -import com.health.openscale.core.alarm.AlarmDatabaseEntryListener; -import com.health.openscale.gui.FragmentUpdateListener; +import com.health.openscale.core.alarm.AlarmHandler; +import com.health.openscale.core.bluetooth.BluetoothCommunication; +import com.health.openscale.core.bluetooth.BluetoothCustomOpenScale; +import com.health.openscale.core.bluetooth.BluetoothMiScale; +import com.health.openscale.core.database.ScaleDatabase; +import com.health.openscale.core.database.ScaleUserDatabase; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.datatypes.ScaleUser; +import com.health.openscale.gui.fragments.FragmentUpdateListener; import java.io.BufferedReader; import java.io.File; @@ -39,8 +46,8 @@ import java.util.ArrayList; import java.util.Map; import java.util.TreeMap; -import static com.health.openscale.core.BluetoothCommunication.BT_MI_SCALE; -import static com.health.openscale.core.BluetoothCommunication.BT_OPEN_SCALE; +import static com.health.openscale.core.bluetooth.BluetoothCommunication.BT_MI_SCALE; +import static com.health.openscale.core.bluetooth.BluetoothCommunication.BT_OPEN_SCALE; public class OpenScale { @@ -52,6 +59,7 @@ public class OpenScale { private BluetoothCommunication btCom; private String btDeviceName; + private AlarmHandler alarmHandler; private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm"); @@ -62,8 +70,8 @@ public class OpenScale { private OpenScale(Context con) { context = con; scaleDB = new ScaleDatabase(context); - scaleDB.addEntryListener(new AlarmDatabaseEntryListener()); scaleUserDB = new ScaleUserDatabase(context); + alarmHandler = new AlarmHandler(); btCom = null; fragmentList = new ArrayList<>(); @@ -196,6 +204,7 @@ public class OpenScale { } if (scaleDB.insertEntry(scaleData)) { + alarmHandler.entryChanged(context, scaleData); updateScaleData(); } @@ -243,6 +252,7 @@ public class OpenScale { } scaleDB.updateEntry(id, scaleData); + alarmHandler.entryChanged(context, scaleData); updateScaleData(); } diff --git a/android_app/app/src/main/java/com/health/openscale/core/Util.java b/android_app/app/src/main/java/com/health/openscale/core/Util.java deleted file mode 100644 index ef657189..00000000 --- a/android_app/app/src/main/java/com/health/openscale/core/Util.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.health.openscale.core; - -import java.util.Calendar; - -public class Util -{ - public static boolean isSameDate(Calendar c1, Calendar c2) - { - int[] dateFields = {Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH}; - for (int dateField : dateFields) - { - if (c1.get(dateField) != c2.get(dateField)) return false; - } - return true; - } -} diff --git a/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmDatabaseEntryListener.java b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmDatabaseEntryListener.java deleted file mode 100644 index ec6c0d1a..00000000 --- a/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmDatabaseEntryListener.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.health.openscale.core.alarm; - -import android.content.Context; - -import com.health.openscale.core.IScaleDatabaseEntryListener; -import com.health.openscale.core.ScaleData; -import com.health.openscale.core.Util; - -import java.util.Calendar; - -public class AlarmDatabaseEntryListener implements IScaleDatabaseEntryListener -{ - @Override - public void entryChanged(Context context, ScaleData data) - { - long dataMillis = data.date_time.getTime(); - - Calendar dataTimestamp = Calendar.getInstance(); - dataTimestamp.setTimeInMillis(dataMillis); - - if(Util.isSameDate(dataTimestamp, Calendar.getInstance())) - { - AlarmHandler alarmHandler = new AlarmHandler(); - alarmHandler.cancelAlarmNotification(context); - alarmHandler.cancelAndRescheduleAlarmForNextWeek( context, dataTimestamp ); - } - } -} diff --git a/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmHandler.java b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmHandler.java index 5042f82d..94c78f30 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmHandler.java +++ b/android_app/app/src/main/java/com/health/openscale/core/alarm/AlarmHandler.java @@ -12,9 +12,8 @@ import android.support.v4.app.NotificationCompat; import android.util.Log; import com.health.openscale.R; -import com.health.openscale.core.Util; +import com.health.openscale.core.datatypes.ScaleData; import com.health.openscale.gui.MainActivity; -import com.health.openscale.gui.ReminderBootReceiver; import java.util.Calendar; import java.util.LinkedList; @@ -38,6 +37,30 @@ public class AlarmHandler enableAlarms(context, alarmEntries); } + public void entryChanged(Context context, ScaleData data) + { + long dataMillis = data.date_time.getTime(); + + Calendar dataTimestamp = Calendar.getInstance(); + dataTimestamp.setTimeInMillis(dataMillis); + + if(AlarmHandler.isSameDate(dataTimestamp, Calendar.getInstance())) + { + cancelAlarmNotification(context); + cancelAndRescheduleAlarmForNextWeek( context, dataTimestamp ); + } + } + + public static boolean isSameDate(Calendar c1, Calendar c2) + { + int[] dateFields = {Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH}; + for (int dateField : dateFields) + { + if (c1.get(dateField) != c2.get(dateField)) return false; + } + return true; + } + private void enableAlarms(Context context, Set alarmEntries) { for (AlarmEntry alarmEntry : alarmEntries) @@ -96,7 +119,7 @@ public class AlarmHandler { Calendar nextAlarmTimestamp = entry.getNextTimestamp(); - if (Util.isSameDate(timestamp, nextAlarmTimestamp)) + if (isSameDate(timestamp, nextAlarmTimestamp)) { int dayOfWeek = entry.getDayOfWeek(); PendingIntent alarmPendingIntent = getPendingAlarmIntent(context, dayOfWeek); diff --git a/android_app/app/src/main/java/com/health/openscale/gui/ReminderBootReceiver.java b/android_app/app/src/main/java/com/health/openscale/core/alarm/ReminderBootReceiver.java similarity index 94% rename from android_app/app/src/main/java/com/health/openscale/gui/ReminderBootReceiver.java rename to android_app/app/src/main/java/com/health/openscale/core/alarm/ReminderBootReceiver.java index f43bce46..7b6f3d51 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/ReminderBootReceiver.java +++ b/android_app/app/src/main/java/com/health/openscale/core/alarm/ReminderBootReceiver.java @@ -14,14 +14,12 @@ * along with this program. If not, see */ -package com.health.openscale.gui; +package com.health.openscale.core.alarm; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import com.health.openscale.core.alarm.AlarmHandler; - public class ReminderBootReceiver extends BroadcastReceiver { @Override diff --git a/android_app/app/src/main/java/com/health/openscale/core/BluetoothCommunication.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCommunication.java similarity index 91% rename from android_app/app/src/main/java/com/health/openscale/core/BluetoothCommunication.java rename to android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCommunication.java index a066444a..f5c502b4 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/BluetoothCommunication.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCommunication.java @@ -14,7 +14,7 @@ * along with this program. If not, see */ -package com.health.openscale.core; +package com.health.openscale.core.bluetooth; import android.bluetooth.BluetoothAdapter; import android.os.Handler; @@ -42,7 +42,7 @@ public abstract class BluetoothCommunication { callbackBtHandler = cbBtHandler; } - abstract void startSearching(String deviceName); - abstract void stopSearching(); + abstract public void startSearching(String deviceName); + abstract public void stopSearching(); } diff --git a/android_app/app/src/main/java/com/health/openscale/core/BluetoothCustomOpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCustomOpenScale.java similarity index 97% rename from android_app/app/src/main/java/com/health/openscale/core/BluetoothCustomOpenScale.java rename to android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCustomOpenScale.java index ff58b6d1..2724c514 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/BluetoothCustomOpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCustomOpenScale.java @@ -13,12 +13,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see */ -package com.health.openscale.core; +package com.health.openscale.core.bluetooth; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.util.Log; +import com.health.openscale.core.datatypes.ScaleData; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -27,7 +29,7 @@ import java.text.SimpleDateFormat; import java.util.Set; import java.util.UUID; -class BluetoothCustomOpenScale extends BluetoothCommunication { +public class BluetoothCustomOpenScale extends BluetoothCommunication { private final UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); // Standard SerialPortService ID private BluetoothSocket btSocket = null; @@ -36,7 +38,7 @@ class BluetoothCustomOpenScale extends BluetoothCommunication { private BluetoothConnectedThread btConnectThread = null; @Override - void startSearching(String deviceName) { + public void startSearching(String deviceName) { if (btAdapter == null) { callbackBtHandler.obtainMessage(BluetoothCommunication.BT_NO_DEVICE_FOUND).sendToTarget(); diff --git a/android_app/app/src/main/java/com/health/openscale/core/BluetoothMiScale.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java similarity index 98% rename from android_app/app/src/main/java/com/health/openscale/core/BluetoothMiScale.java rename to android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java index 43f2fa10..75dfda1d 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/BluetoothMiScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java @@ -14,7 +14,7 @@ * along with this program. If not, see */ -package com.health.openscale.core; +package com.health.openscale.core.bluetooth; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -27,6 +27,8 @@ import android.content.Context; import android.os.Handler; import android.util.Log; +import com.health.openscale.core.datatypes.ScaleData; + import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -59,7 +61,7 @@ public class BluetoothMiScale extends BluetoothCommunication { } @Override - void startSearching(String deviceName) { + public void startSearching(String deviceName) { btDeviceName = deviceName; if (scanCallback == null) @@ -103,7 +105,7 @@ public class BluetoothMiScale extends BluetoothCommunication { } @Override - void stopSearching() { + public void stopSearching() { if (bluetoothGatt != null) { bluetoothGatt.close(); diff --git a/android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java b/android_app/app/src/main/java/com/health/openscale/core/database/ScaleDatabase.java similarity index 93% rename from android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java rename to android_app/app/src/main/java/com/health/openscale/core/database/ScaleDatabase.java index 82ceaa8e..dff0e42b 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java +++ b/android_app/app/src/main/java/com/health/openscale/core/database/ScaleDatabase.java @@ -14,7 +14,7 @@ * along with this program. If not, see */ -package com.health.openscale.core; +package com.health.openscale.core.database; import android.content.ContentValues; import android.content.Context; @@ -24,12 +24,12 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; +import com.health.openscale.core.datatypes.ScaleData; + import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; -import java.util.LinkedList; -import java.util.List; import java.util.Locale; public class ScaleDatabase extends SQLiteOpenHelper { @@ -87,13 +87,8 @@ public class ScaleDatabase extends SQLiteOpenHelper { private SimpleDateFormat formatDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); - private Context context; - private List entryListeners; - public ScaleDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); - this.context = context; - entryListeners = new LinkedList<>(); } @Override @@ -147,7 +142,6 @@ public class ScaleDatabase extends SQLiteOpenHelper { try { db.insertOrThrow(TABLE_NAME, null, values); - notifyEntryListeners(scaleData); } catch (SQLException e) { @@ -175,7 +169,6 @@ public class ScaleDatabase extends SQLiteOpenHelper { values.put(COLUMN_NAME_ENABLE, 1); dbWrite.update(TABLE_NAME, values, COLUMN_NAME_ID + "=" + id, null); - notifyEntryListeners(scaleData); } public ScaleData getDataEntry(long id) @@ -328,20 +321,4 @@ public class ScaleDatabase extends SQLiteOpenHelper { return scaleData; } - - public void addEntryListener(IScaleDatabaseEntryListener listener) - { - if (!entryListeners.contains(listener)) entryListeners.add(listener); - } - - public void removeEntryListener( IScaleDatabaseEntryListener listener) - { - entryListeners.remove(listener); - } - - private void notifyEntryListeners(ScaleData data) - { - for (IScaleDatabaseEntryListener listener : entryListeners) - listener.entryChanged(context, data); - } } diff --git a/android_app/app/src/main/java/com/health/openscale/core/ScaleUserDatabase.java b/android_app/app/src/main/java/com/health/openscale/core/database/ScaleUserDatabase.java similarity index 98% rename from android_app/app/src/main/java/com/health/openscale/core/ScaleUserDatabase.java rename to android_app/app/src/main/java/com/health/openscale/core/database/ScaleUserDatabase.java index a35c6c1a..643dba8b 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/ScaleUserDatabase.java +++ b/android_app/app/src/main/java/com/health/openscale/core/database/ScaleUserDatabase.java @@ -14,7 +14,7 @@ * along with this program. If not, see */ -package com.health.openscale.core; +package com.health.openscale.core.database; import android.content.ContentValues; import android.content.Context; @@ -24,6 +24,8 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; +import com.health.openscale.core.datatypes.ScaleUser; + import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; diff --git a/android_app/app/src/main/java/com/health/openscale/core/ScaleCalculator.java b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleCalculator.java similarity index 94% rename from android_app/app/src/main/java/com/health/openscale/core/ScaleCalculator.java rename to android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleCalculator.java index ecd61f84..5ac08ec3 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/ScaleCalculator.java +++ b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleCalculator.java @@ -1,4 +1,4 @@ -package com.health.openscale.core; +package com.health.openscale.core.datatypes; public class ScaleCalculator { diff --git a/android_app/app/src/main/java/com/health/openscale/core/ScaleData.java b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleData.java similarity index 97% rename from android_app/app/src/main/java/com/health/openscale/core/ScaleData.java rename to android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleData.java index e3f1e96a..def1183c 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/ScaleData.java +++ b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleData.java @@ -14,7 +14,7 @@ * along with this program. If not, see */ -package com.health.openscale.core; +package com.health.openscale.core.datatypes; import java.util.Date; diff --git a/android_app/app/src/main/java/com/health/openscale/core/ScaleUser.java b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java similarity index 97% rename from android_app/app/src/main/java/com/health/openscale/core/ScaleUser.java rename to android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java index 16dadd90..2853509b 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/ScaleUser.java +++ b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java @@ -14,7 +14,7 @@ * along with this program. If not, see */ -package com.health.openscale.core; +package com.health.openscale.core.datatypes; import java.util.Date; diff --git a/android_app/app/src/main/java/com/health/openscale/core/EvaluationResult.java b/android_app/app/src/main/java/com/health/openscale/core/evaluation/EvaluationResult.java similarity index 96% rename from android_app/app/src/main/java/com/health/openscale/core/EvaluationResult.java rename to android_app/app/src/main/java/com/health/openscale/core/evaluation/EvaluationResult.java index f42aa041..1c85a020 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/EvaluationResult.java +++ b/android_app/app/src/main/java/com/health/openscale/core/evaluation/EvaluationResult.java @@ -14,7 +14,7 @@ * along with this program. If not, see */ -package com.health.openscale.core; +package com.health.openscale.core.evaluation; public class EvaluationResult { public static enum EVAL_STATE {LOW, NORMAL, HIGH, UNDEFINED}; diff --git a/android_app/app/src/main/java/com/health/openscale/core/EvaluationSheet.java b/android_app/app/src/main/java/com/health/openscale/core/evaluation/EvaluationSheet.java similarity index 99% rename from android_app/app/src/main/java/com/health/openscale/core/EvaluationSheet.java rename to android_app/app/src/main/java/com/health/openscale/core/evaluation/EvaluationSheet.java index 42435f5b..1f66ff1c 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/EvaluationSheet.java +++ b/android_app/app/src/main/java/com/health/openscale/core/evaluation/EvaluationSheet.java @@ -13,10 +13,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see */ -package com.health.openscale.core; +package com.health.openscale.core.evaluation; import android.util.Log; +import com.health.openscale.core.datatypes.ScaleUser; + import java.util.ArrayList; import java.util.Calendar; import java.util.Date; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java index dd0efbd6..cf4ed885 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java @@ -39,9 +39,14 @@ import android.view.MenuItem; import android.widget.Toast; import com.health.openscale.R; -import com.health.openscale.core.BluetoothCommunication; +import com.health.openscale.core.bluetooth.BluetoothCommunication; import com.health.openscale.core.OpenScale; -import com.health.openscale.core.ScaleData; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.gui.activities.SettingsActivity; +import com.health.openscale.gui.activities.UserSettingsActivity; +import com.health.openscale.gui.fragments.GraphFragment; +import com.health.openscale.gui.fragments.OverviewFragment; +import com.health.openscale.gui.fragments.TableFragment; import java.util.Locale; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/MeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/MeasurementView.java deleted file mode 100644 index 76c6145c..00000000 --- a/android_app/app/src/main/java/com/health/openscale/gui/MeasurementView.java +++ /dev/null @@ -1,679 +0,0 @@ -package com.health.openscale.gui; - -import android.content.Context; -import android.content.SharedPreferences; -import android.graphics.Color; -import android.graphics.drawable.Drawable; -import android.support.v4.content.ContextCompat; -import android.text.Html; -import android.text.InputType; -import android.util.TypedValue; -import android.view.View; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.Space; -import android.widget.TableLayout; -import android.widget.TableRow; -import android.widget.TextView; - -import com.health.openscale.R; -import com.health.openscale.core.EvaluationResult; -import com.health.openscale.core.EvaluationSheet; -import com.health.openscale.core.OpenScale; -import com.health.openscale.core.ScaleCalculator; -import com.health.openscale.core.ScaleData; -import com.health.openscale.core.ScaleUser; - -import lecho.lib.hellocharts.util.ChartUtils; - -abstract class MeasurementView extends TableLayout { - private static String SYMBOL_UP = "↗"; - private static String SYMBOL_DOWN = "↘"; - - private TableRow measurementRow; - private ImageView iconView; - private TextView nameView; - private TextView valueView; - private ImageView indicatorView; - - private TableRow evaluatorRow; - private LinearGaugeView evaluatorView; - - private String nameText; - - private boolean editMode; - - public MeasurementView(Context context, String text, Drawable icon) { - super(context); - initView(context); - - editMode = false; - nameText = text; - nameView.setText(text); - iconView.setImageDrawable(icon); - } - - private void initView(Context context) { - measurementRow = new TableRow(context); - - iconView = new ImageView(context); - nameView = new TextView(context); - valueView = new TextView(context); - indicatorView = new ImageView(context); - - evaluatorRow = new TableRow(context); - evaluatorView = new LinearGaugeView(context); - - - measurementRow.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT, 1.0f)); - measurementRow.addView(iconView); - measurementRow.addView(nameView); - measurementRow.addView(valueView); - measurementRow.addView(indicatorView); - - addView(measurementRow); - addView(evaluatorRow); - - iconView.getLayoutParams().height = pxImageDp(30); - iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); - - nameView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); - nameView.setTextColor(Color.BLACK); - nameView.setLines(2); - nameView.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.90f)); - - valueView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); - valueView.setTextColor(Color.BLACK); - valueView.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, 0.01f)); - - indicatorView.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.MATCH_PARENT, 0.01f)); - indicatorView.setBackgroundColor(Color.GRAY); - - evaluatorRow.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT, 1.0f)); - evaluatorRow.addView(new Space(context)); - evaluatorRow.addView(evaluatorView); - Space spaceAfterEvaluatorView = new Space(context); - evaluatorRow.addView(spaceAfterEvaluatorView); - evaluatorRow.setVisibility(View.GONE); - - evaluatorView.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 0.99f)); - spaceAfterEvaluatorView.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 0.01f)); - - measurementRow.setOnClickListener(new onClickListenerEvaluation()); - } - - abstract void updateValue(ScaleData updateData); - abstract void updateDiff(ScaleData updateData, ScaleData lastData); - abstract void updatePreferences(SharedPreferences preferences); - abstract String getUnit(); - abstract EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value); - abstract float getMinValue(); - abstract float getMaxValue(); - - abstract int getInputType(); - - public float getValue() { - if (valueView.getText().length() == 0) { - return -1; - } - - return Float.valueOf(valueView.getText().toString()); - } - - public void setEditMode(boolean mode) { - editMode = mode; - - if (editMode) { - valueView = new EditText(getContext()); - valueView.setInputType(getInputType()); - valueView.setHint(getContext().getResources().getString(R.string.info_enter_value_unit) + " " + getUnit()); - measurementRow.addView(valueView); - indicatorView.setVisibility(View.GONE); - } - } - - protected boolean isEditModeOn() { - return editMode; - } - - protected void setValueOnView(float value) { - if (isEditModeOn()) { - valueView.setText(String.valueOf(value)); - } else { - valueView.setText(String.format("%.2f ", value) + getUnit()); - evaluate(value); - } - } - - protected void setDiffOnView(float value, float lastValue) { - float diffValue = value - lastValue; - - String symbol; - - if (diffValue > 0.0) { - symbol = SYMBOL_UP; - } else { - symbol = SYMBOL_DOWN; - } - - nameView.setText( - Html.fromHtml( - nameText + - "
" + - symbol + - " " + - String.format("%.2f ", diffValue) + getUnit() + - "" - ) - ); - } - - protected void setVisible(boolean isVisible){ - if(isVisible) { - measurementRow.setVisibility(View.VISIBLE); - } else { - measurementRow.setVisibility(View.GONE); - } - } - - private int pxImageDp(float dp) { - return (int)(dp * getResources().getDisplayMetrics().density + 0.5f); - } - - public boolean validateInput() { - if (measurementRow.getVisibility() == View.VISIBLE) { - if (valueView.getText().toString().length() == 0) { - valueView.setError(getResources().getString(R.string.error_value_required)); - return false; - } - - float value = Float.valueOf(valueView.getText().toString()); - - if (!(value >= 0 && value <= getMaxValue())) { - valueView.setError(getResources().getString(R.string.error_value_range)); - return false; - } - } - - return true; - } - - private void evaluate(float value) { - EvaluationSheet evalSheet = new EvaluationSheet(getScaleUser()); - EvaluationResult evalResult = evaluateSheet(evalSheet, value); - - evaluatorView.setMinMaxValue(getMinValue(), getMaxValue()); - evaluatorView.setLimits(evalResult.lowLimit, evalResult.highLimit); - evaluatorView.setValue(value); - - switch(evalResult.eval_state) - { - case LOW: - indicatorView.setBackgroundColor(ChartUtils.COLOR_BLUE); - break; - case NORMAL: - indicatorView.setBackgroundColor(ChartUtils.COLOR_GREEN); - break; - case HIGH: - indicatorView.setBackgroundColor(ChartUtils.COLOR_RED); - break; - case UNDEFINED: - indicatorView.setBackgroundColor(Color.GRAY); - break; - } - } - - protected ScaleUser getScaleUser() { - OpenScale openScale = OpenScale.getInstance(getContext()); - - return openScale.getSelectedScaleUser(); - } - - private class onClickListenerEvaluation implements View.OnClickListener { - @Override - public void onClick(View v) { - if (isEditModeOn()) { - return; - } - - if (evaluatorRow.getVisibility() == View.VISIBLE) { - evaluatorRow.setVisibility(View.GONE); - } else { - evaluatorRow.setVisibility(View.VISIBLE); - } - } - } -} - -class WeightMeasurementView extends MeasurementView { - - public WeightMeasurementView(Context context) { - super(context, context.getResources().getString(R.string.label_weight), ContextCompat.getDrawable(context, R.drawable.weight)); - } - - @Override - void updateValue(ScaleData updateData) { - setValueOnView(updateData.weight); - } - - @Override - void updateDiff(ScaleData updateData, ScaleData lastData) { - setDiffOnView(updateData.weight, lastData.weight); - } - - @Override - String getUnit() { - return ScaleUser.UNIT_STRING[getScaleUser().scale_unit]; - } - - @Override - void updatePreferences(SharedPreferences preferences) { - setVisible(preferences.getBoolean("weightEnable", true)); - } - - @Override - EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { - return evalSheet.evaluateWeight(value); - } - - @Override - float getMinValue() { - return 30; - } - - @Override - float getMaxValue() { - return 300; - } - - @Override - int getInputType() { - return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; - } -} - -class BMIMeasurementView extends MeasurementView { - - public BMIMeasurementView(Context context) { - super(context, context.getResources().getString(R.string.label_bmi), ContextCompat.getDrawable(context, R.drawable.bmi)); - } - - @Override - void updateValue(ScaleData updateData) { - ScaleCalculator updateCalculator = new ScaleCalculator(updateData); - setValueOnView(updateCalculator.getBMI(getScaleUser().body_height)); - } - - @Override - void updateDiff(ScaleData updateData, ScaleData lastData) { - ScaleCalculator updateCalculator = new ScaleCalculator(updateData); - ScaleCalculator lastCalculator = new ScaleCalculator(lastData); - setDiffOnView(updateCalculator.getBMI(getScaleUser().body_height), lastCalculator.getBMI(getScaleUser().body_height)); - } - - @Override - String getUnit() { - return ""; - } - - @Override - EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { - return evalSheet.evaluateBMI(value); - } - - @Override - float getMinValue() { - return 10; - } - - @Override - float getMaxValue() { - return 50; - } - - @Override - int getInputType() { - return 0; - } - - @Override - void updatePreferences(SharedPreferences preferences) { - setVisible(preferences.getBoolean("weightEnable", true)); - } -} - -class WaterMeasurementView extends MeasurementView { - - public WaterMeasurementView(Context context) { - super(context, context.getResources().getString(R.string.label_water), ContextCompat.getDrawable(context, R.drawable.water)); - } - - @Override - void updateValue(ScaleData updateData) { - setValueOnView(updateData.water); - } - - @Override - void updateDiff(ScaleData updateData, ScaleData lastData) { - setDiffOnView(updateData.water, lastData.water); - } - - @Override - String getUnit() { - return "%"; - } - - @Override - void updatePreferences(SharedPreferences preferences) { - setVisible(preferences.getBoolean("waterEnable", true)); - } - - @Override - EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { - return evalSheet.evaluateBodyWater(value); - } - - @Override - float getMinValue() { - return 30; - } - - @Override - float getMaxValue() { - return 80; - } - - @Override - int getInputType() { - return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; - } -} - -class MuscleMeasurementView extends MeasurementView { - - public MuscleMeasurementView(Context context) { - super(context, context.getResources().getString(R.string.label_muscle), ContextCompat.getDrawable(context, R.drawable.muscle)); - } - - @Override - void updateValue(ScaleData updateData) { - setValueOnView(updateData.muscle); - } - - @Override - void updateDiff(ScaleData updateData, ScaleData lastData) { - setDiffOnView(updateData.muscle, lastData.muscle); - } - - @Override - String getUnit() { - return "%"; - } - - @Override - void updatePreferences(SharedPreferences preferences) { - setVisible(preferences.getBoolean("muscleEnable", true)); - } - - @Override - EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { - return evalSheet.evaluateBodyMuscle(value); - } - - @Override - float getMinValue() { - return 10; - } - - @Override - float getMaxValue() { - return 80; - } - - @Override - int getInputType() { - return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; - } -} - -class FatMeasurementView extends MeasurementView { - - public FatMeasurementView(Context context) { - super(context, context.getResources().getString(R.string.label_fat), ContextCompat.getDrawable(context, R.drawable.fat)); - } - - @Override - void updateValue(ScaleData updateData) { - setValueOnView(updateData.fat); - } - - @Override - void updateDiff(ScaleData updateData, ScaleData lastData) { - setDiffOnView(updateData.fat, lastData.fat); - } - - @Override - String getUnit() { - return "%"; - } - - @Override - void updatePreferences(SharedPreferences preferences) { - setVisible(preferences.getBoolean("fatEnable", true)); - } - - @Override - EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { - return evalSheet.evaluateBodyFat(value); - } - - @Override - float getMinValue() { - return 10; - } - - @Override - float getMaxValue() { - return 40; - } - - @Override - int getInputType() { - return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; - } -} - -class WaistMeasurementView extends MeasurementView { - - public WaistMeasurementView(Context context) { - super(context, context.getResources().getString(R.string.label_waist), ContextCompat.getDrawable(context, R.drawable.waist)); - } - - @Override - void updateValue(ScaleData updateData) { - setValueOnView(updateData.waist); - } - - @Override - void updateDiff(ScaleData updateData, ScaleData lastData) { - setDiffOnView(updateData.waist, lastData.waist); - } - - @Override - String getUnit() { - return "cm"; - } - - @Override - void updatePreferences(SharedPreferences preferences) { - setVisible(preferences.getBoolean("waistEnable", true)); - } - - @Override - EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { - return evalSheet.evaluateWaist(value); - } - - @Override - float getMinValue() { - return 30; - } - - @Override - float getMaxValue() { - return 200; - } - - @Override - int getInputType() { - return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; - } -} - -class WHtRMeasurementView extends MeasurementView { - - public WHtRMeasurementView(Context context) { - super(context, context.getResources().getString(R.string.label_whtr), ContextCompat.getDrawable(context, R.drawable.whtr)); - } - - @Override - void updateValue(ScaleData updateData) { - ScaleCalculator updateCalculator = new ScaleCalculator(updateData); - setValueOnView(updateCalculator.getWHtR(getScaleUser().body_height)); - } - - @Override - void updateDiff(ScaleData updateData, ScaleData lastData) { - ScaleCalculator updateCalculator = new ScaleCalculator(updateData); - ScaleCalculator lastCalculator = new ScaleCalculator(lastData); - setDiffOnView(updateCalculator.getWHtR(getScaleUser().body_height), lastCalculator.getWHtR(getScaleUser().body_height)); - } - - @Override - String getUnit() { - return ""; - } - - @Override - void updatePreferences(SharedPreferences preferences) { - setVisible(preferences.getBoolean("waistEnable", true)); - } - - @Override - EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { - return evalSheet.evaluateWHtR(value); - } - - @Override - float getMinValue() { - return 0; - } - - @Override - float getMaxValue() { - return 1; - } - - @Override - int getInputType() { - return 0; - } -} - -class HipMeasurementView extends MeasurementView { - - public HipMeasurementView(Context context) { - super(context, context.getResources().getString(R.string.label_hip), ContextCompat.getDrawable(context, R.drawable.hip)); - } - - @Override - void updateValue(ScaleData updateData) { - setValueOnView(updateData.hip); - } - - @Override - void updateDiff(ScaleData updateData, ScaleData lastData) { - setDiffOnView(updateData.hip, lastData.hip); - } - - @Override - String getUnit() { - return "cm"; - } - - @Override - void updatePreferences(SharedPreferences preferences) { - setVisible(preferences.getBoolean("hipEnable", true)); - } - - @Override - EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { - return evalSheet.evaluateHip(value); - } - - @Override - float getMinValue() { - return 30; - } - - @Override - float getMaxValue() { - return 200; - } - - @Override - int getInputType() { - return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; - } -} - -class WHRMeasurementView extends MeasurementView { - - public WHRMeasurementView(Context context) { - super(context, context.getResources().getString(R.string.label_whr), ContextCompat.getDrawable(context, R.drawable.whr)); - } - - @Override - void updateValue(ScaleData updateData) { - ScaleCalculator updateCalculator = new ScaleCalculator(updateData); - setValueOnView(updateCalculator.getWHR()); - } - - @Override - void updateDiff(ScaleData updateData, ScaleData lastData) { - ScaleCalculator updateCalculator = new ScaleCalculator(updateData); - ScaleCalculator lastCalculator = new ScaleCalculator(lastData); - setDiffOnView(updateCalculator.getWHR(), lastCalculator.getWHR()); - } - - @Override - String getUnit() { - return ""; - } - - @Override - void updatePreferences(SharedPreferences preferences) { - setVisible(preferences.getBoolean("hipEnable", true) && preferences.getBoolean("waistEnable", true)); - } - - @Override - EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { - return evalSheet.evaluateWHR(value); - } - - @Override - float getMinValue() { - return 0.5f; - } - - @Override - float getMaxValue() { - return 1.5f; - } - - @Override - int getInputType() { - return 0; - } - -} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/DataEntryActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java similarity index 96% rename from android_app/app/src/main/java/com/health/openscale/gui/DataEntryActivity.java rename to android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java index 90d0419d..f5781315 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/DataEntryActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see */ -package com.health.openscale.gui; +package com.health.openscale.gui.activities; import android.app.Activity; import android.app.AlertDialog; @@ -36,7 +36,14 @@ import android.widget.Toast; import com.health.openscale.R; import com.health.openscale.core.OpenScale; -import com.health.openscale.core.ScaleData; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.gui.views.FatMeasurementView; +import com.health.openscale.gui.views.HipMeasurementView; +import com.health.openscale.gui.views.MeasurementView; +import com.health.openscale.gui.views.MuscleMeasurementView; +import com.health.openscale.gui.views.WaistMeasurementView; +import com.health.openscale.gui.views.WaterMeasurementView; +import com.health.openscale.gui.views.WeightMeasurementView; import java.text.DateFormat; import java.text.SimpleDateFormat; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/SettingsActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/activities/SettingsActivity.java similarity index 96% rename from android_app/app/src/main/java/com/health/openscale/gui/SettingsActivity.java rename to android_app/app/src/main/java/com/health/openscale/gui/activities/SettingsActivity.java index a582241b..e8e103bd 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/SettingsActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/activities/SettingsActivity.java @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see */ -package com.health.openscale.gui; +package com.health.openscale.gui.activities; import android.preference.PreferenceActivity; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/UserSettingsActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java similarity index 99% rename from android_app/app/src/main/java/com/health/openscale/gui/UserSettingsActivity.java rename to android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java index 99fce8a5..6c668e15 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/UserSettingsActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/activities/UserSettingsActivity.java @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see */ -package com.health.openscale.gui; +package com.health.openscale.gui.activities; import android.app.Activity; import android.app.AlertDialog; @@ -32,7 +32,7 @@ import android.widget.RadioGroup; import com.health.openscale.R; import com.health.openscale.core.OpenScale; -import com.health.openscale.core.ScaleUser; +import com.health.openscale.core.datatypes.ScaleUser; import java.text.SimpleDateFormat; import java.util.ArrayList; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/FragmentUpdateListener.java b/android_app/app/src/main/java/com/health/openscale/gui/fragments/FragmentUpdateListener.java similarity index 89% rename from android_app/app/src/main/java/com/health/openscale/gui/FragmentUpdateListener.java rename to android_app/app/src/main/java/com/health/openscale/gui/fragments/FragmentUpdateListener.java index 3061e4b4..75fbd5a1 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/FragmentUpdateListener.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/fragments/FragmentUpdateListener.java @@ -14,9 +14,9 @@ * along with this program. If not, see */ -package com.health.openscale.gui; +package com.health.openscale.gui.fragments; -import com.health.openscale.core.ScaleData; +import com.health.openscale.core.datatypes.ScaleData; import java.util.ArrayList; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/GraphFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/fragments/GraphFragment.java similarity index 98% rename from android_app/app/src/main/java/com/health/openscale/gui/GraphFragment.java rename to android_app/app/src/main/java/com/health/openscale/gui/fragments/GraphFragment.java index d6127db1..a7c635b7 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/GraphFragment.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/fragments/GraphFragment.java @@ -14,7 +14,7 @@ * along with this program. If not, see */ -package com.health.openscale.gui; +package com.health.openscale.gui.fragments; import android.app.Activity; import android.content.Intent; @@ -33,7 +33,8 @@ import android.widget.TextView; import com.health.openscale.R; import com.health.openscale.core.OpenScale; -import com.health.openscale.core.ScaleData; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.gui.activities.DataEntryActivity; import java.text.SimpleDateFormat; import java.util.ArrayList; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/OverviewFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java similarity index 97% rename from android_app/app/src/main/java/com/health/openscale/gui/OverviewFragment.java rename to android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java index 92ac0876..5f0dca6e 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/OverviewFragment.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see */ -package com.health.openscale.gui; +package com.health.openscale.gui.fragments; import android.content.Context; import android.content.Intent; @@ -36,9 +36,20 @@ import android.widget.Toast; import com.health.openscale.R; import com.health.openscale.core.OpenScale; -import com.health.openscale.core.ScaleCalculator; -import com.health.openscale.core.ScaleData; -import com.health.openscale.core.ScaleUser; +import com.health.openscale.core.datatypes.ScaleCalculator; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.datatypes.ScaleUser; +import com.health.openscale.gui.activities.DataEntryActivity; +import com.health.openscale.gui.views.BMIMeasurementView; +import com.health.openscale.gui.views.FatMeasurementView; +import com.health.openscale.gui.views.HipMeasurementView; +import com.health.openscale.gui.views.MeasurementView; +import com.health.openscale.gui.views.MuscleMeasurementView; +import com.health.openscale.gui.views.WHRMeasurementView; +import com.health.openscale.gui.views.WHtRMeasurementView; +import com.health.openscale.gui.views.WaistMeasurementView; +import com.health.openscale.gui.views.WaterMeasurementView; +import com.health.openscale.gui.views.WeightMeasurementView; import java.text.DateFormat; import java.util.ArrayList; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/TableFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java similarity index 99% rename from android_app/app/src/main/java/com/health/openscale/gui/TableFragment.java rename to android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java index 59d247f1..ea15e77b 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/TableFragment.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see */ -package com.health.openscale.gui; +package com.health.openscale.gui.fragments; import android.app.Activity; import android.app.AlertDialog; @@ -42,7 +42,8 @@ import android.widget.Toast; import com.health.openscale.R; import com.health.openscale.core.OpenScale; -import com.health.openscale.core.ScaleData; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.gui.activities.DataEntryActivity; import java.io.IOException; import java.text.DateFormat; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/preferences/ReminderPreferences.java b/android_app/app/src/main/java/com/health/openscale/gui/preferences/ReminderPreferences.java index eb354c2f..6670f6db 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/preferences/ReminderPreferences.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/preferences/ReminderPreferences.java @@ -29,7 +29,7 @@ import android.preference.PreferenceGroup; import com.health.openscale.R; import com.health.openscale.core.alarm.AlarmHandler; -import com.health.openscale.gui.ReminderBootReceiver; +import com.health.openscale.core.alarm.ReminderBootReceiver; import java.util.ArrayList; import java.util.List; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/preferences/UsersPreferences.java b/android_app/app/src/main/java/com/health/openscale/gui/preferences/UsersPreferences.java index a6b99a63..1eb83f97 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/preferences/UsersPreferences.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/preferences/UsersPreferences.java @@ -24,8 +24,8 @@ import android.preference.PreferenceManager; import com.health.openscale.R; import com.health.openscale.core.OpenScale; -import com.health.openscale.core.ScaleUser; -import com.health.openscale.gui.UserSettingsActivity; +import com.health.openscale.core.datatypes.ScaleUser; +import com.health.openscale.gui.activities.UserSettingsActivity; import java.util.ArrayList; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/BMIMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/BMIMeasurementView.java new file mode 100644 index 00000000..9b6c4c28 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/BMIMeasurementView.java @@ -0,0 +1,61 @@ +package com.health.openscale.gui.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.v4.content.ContextCompat; + +import com.health.openscale.R; +import com.health.openscale.core.datatypes.ScaleCalculator; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.evaluation.EvaluationResult; +import com.health.openscale.core.evaluation.EvaluationSheet; + +public class BMIMeasurementView extends MeasurementView { + + public BMIMeasurementView(Context context) { + super(context, context.getResources().getString(R.string.label_bmi), ContextCompat.getDrawable(context, R.drawable.bmi)); + } + + @Override + public void updateValue(ScaleData updateData) { + ScaleCalculator updateCalculator = new ScaleCalculator(updateData); + setValueOnView(updateCalculator.getBMI(getScaleUser().body_height)); + } + + @Override + public void updateDiff(ScaleData updateData, ScaleData lastData) { + ScaleCalculator updateCalculator = new ScaleCalculator(updateData); + ScaleCalculator lastCalculator = new ScaleCalculator(lastData); + setDiffOnView(updateCalculator.getBMI(getScaleUser().body_height), lastCalculator.getBMI(getScaleUser().body_height)); + } + + @Override + public String getUnit() { + return ""; + } + + @Override + public EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { + return evalSheet.evaluateBMI(value); + } + + @Override + public float getMinValue() { + return 10; + } + + @Override + public float getMaxValue() { + return 50; + } + + @Override + int getInputType() { + return 0; + } + + @Override + public void updatePreferences(SharedPreferences preferences) { + setVisible(preferences.getBoolean("weightEnable", true)); + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/FatMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/FatMeasurementView.java new file mode 100644 index 00000000..58208ce8 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/FatMeasurementView.java @@ -0,0 +1,58 @@ +package com.health.openscale.gui.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.v4.content.ContextCompat; +import android.text.InputType; + +import com.health.openscale.R; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.evaluation.EvaluationResult; +import com.health.openscale.core.evaluation.EvaluationSheet; + +public class FatMeasurementView extends MeasurementView { + + public FatMeasurementView(Context context) { + super(context, context.getResources().getString(R.string.label_fat), ContextCompat.getDrawable(context, R.drawable.fat)); + } + + @Override + public void updateValue(ScaleData updateData) { + setValueOnView(updateData.fat); + } + + @Override + public void updateDiff(ScaleData updateData, ScaleData lastData) { + setDiffOnView(updateData.fat, lastData.fat); + } + + @Override + public String getUnit() { + return "%"; + } + + @Override + public void updatePreferences(SharedPreferences preferences) { + setVisible(preferences.getBoolean("fatEnable", true)); + } + + @Override + public EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { + return evalSheet.evaluateBodyFat(value); + } + + @Override + public float getMinValue() { + return 10; + } + + @Override + public float getMaxValue() { + return 40; + } + + @Override + int getInputType() { + return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/HipMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/HipMeasurementView.java new file mode 100644 index 00000000..5ebfade4 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/HipMeasurementView.java @@ -0,0 +1,58 @@ +package com.health.openscale.gui.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.v4.content.ContextCompat; +import android.text.InputType; + +import com.health.openscale.R; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.evaluation.EvaluationResult; +import com.health.openscale.core.evaluation.EvaluationSheet; + +public class HipMeasurementView extends MeasurementView { + + public HipMeasurementView(Context context) { + super(context, context.getResources().getString(R.string.label_hip), ContextCompat.getDrawable(context, R.drawable.hip)); + } + + @Override + public void updateValue(ScaleData updateData) { + setValueOnView(updateData.hip); + } + + @Override + public void updateDiff(ScaleData updateData, ScaleData lastData) { + setDiffOnView(updateData.hip, lastData.hip); + } + + @Override + public String getUnit() { + return "cm"; + } + + @Override + public void updatePreferences(SharedPreferences preferences) { + setVisible(preferences.getBoolean("hipEnable", true)); + } + + @Override + public EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { + return evalSheet.evaluateHip(value); + } + + @Override + public float getMinValue() { + return 30; + } + + @Override + public float getMaxValue() { + return 200; + } + + @Override + int getInputType() { + return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/LinearGaugeView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/LinearGaugeView.java similarity index 99% rename from android_app/app/src/main/java/com/health/openscale/gui/LinearGaugeView.java rename to android_app/app/src/main/java/com/health/openscale/gui/views/LinearGaugeView.java index c780152d..e56f6d5c 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/LinearGaugeView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/LinearGaugeView.java @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see */ -package com.health.openscale.gui; +package com.health.openscale.gui.views; import android.content.Context; import android.graphics.Canvas; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java new file mode 100644 index 00000000..d2880b99 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java @@ -0,0 +1,244 @@ +package com.health.openscale.gui.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.text.Html; +import android.util.TypedValue; +import android.view.View; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.Space; +import android.widget.TableLayout; +import android.widget.TableRow; +import android.widget.TextView; + +import com.health.openscale.R; +import com.health.openscale.core.evaluation.EvaluationResult; +import com.health.openscale.core.evaluation.EvaluationSheet; +import com.health.openscale.core.OpenScale; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.datatypes.ScaleUser; + +import lecho.lib.hellocharts.util.ChartUtils; + +public abstract class MeasurementView extends TableLayout { + private static String SYMBOL_UP = "↗"; + private static String SYMBOL_DOWN = "↘"; + + private TableRow measurementRow; + private ImageView iconView; + private TextView nameView; + private TextView valueView; + private ImageView indicatorView; + + private TableRow evaluatorRow; + private LinearGaugeView evaluatorView; + + private String nameText; + + private boolean editMode; + + public MeasurementView(Context context, String text, Drawable icon) { + super(context); + initView(context); + + editMode = false; + nameText = text; + nameView.setText(text); + iconView.setImageDrawable(icon); + } + + private void initView(Context context) { + measurementRow = new TableRow(context); + + iconView = new ImageView(context); + nameView = new TextView(context); + valueView = new TextView(context); + indicatorView = new ImageView(context); + + evaluatorRow = new TableRow(context); + evaluatorView = new LinearGaugeView(context); + + + measurementRow.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT, 1.0f)); + measurementRow.addView(iconView); + measurementRow.addView(nameView); + measurementRow.addView(valueView); + measurementRow.addView(indicatorView); + + addView(measurementRow); + addView(evaluatorRow); + + iconView.getLayoutParams().height = pxImageDp(30); + iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + + nameView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); + nameView.setTextColor(Color.BLACK); + nameView.setLines(2); + nameView.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0.90f)); + + valueView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); + valueView.setTextColor(Color.BLACK); + valueView.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, 0.01f)); + + indicatorView.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.MATCH_PARENT, 0.01f)); + indicatorView.setBackgroundColor(Color.GRAY); + + evaluatorRow.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT, 1.0f)); + evaluatorRow.addView(new Space(context)); + evaluatorRow.addView(evaluatorView); + Space spaceAfterEvaluatorView = new Space(context); + evaluatorRow.addView(spaceAfterEvaluatorView); + evaluatorRow.setVisibility(View.GONE); + + evaluatorView.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 0.99f)); + spaceAfterEvaluatorView.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.WRAP_CONTENT, 0.01f)); + + measurementRow.setOnClickListener(new onClickListenerEvaluation()); + } + + public abstract void updateValue(ScaleData updateData); + public abstract void updateDiff(ScaleData updateData, ScaleData lastData); + public abstract void updatePreferences(SharedPreferences preferences); + public abstract String getUnit(); + public abstract EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value); + public abstract float getMinValue(); + public abstract float getMaxValue(); + + abstract int getInputType(); + + public float getValue() { + if (valueView.getText().length() == 0) { + return -1; + } + + return Float.valueOf(valueView.getText().toString()); + } + + public void setEditMode(boolean mode) { + editMode = mode; + + if (editMode) { + valueView = new EditText(getContext()); + valueView.setInputType(getInputType()); + valueView.setHint(getContext().getResources().getString(R.string.info_enter_value_unit) + " " + getUnit()); + measurementRow.addView(valueView); + indicatorView.setVisibility(View.GONE); + } + } + + protected boolean isEditModeOn() { + return editMode; + } + + protected void setValueOnView(float value) { + if (isEditModeOn()) { + valueView.setText(String.valueOf(value)); + } else { + valueView.setText(String.format("%.2f ", value) + getUnit()); + evaluate(value); + } + } + + protected void setDiffOnView(float value, float lastValue) { + float diffValue = value - lastValue; + + String symbol; + + if (diffValue > 0.0) { + symbol = SYMBOL_UP; + } else { + symbol = SYMBOL_DOWN; + } + + nameView.setText( + Html.fromHtml( + nameText + + "
" + + symbol + + " " + + String.format("%.2f ", diffValue) + getUnit() + + "" + ) + ); + } + + protected void setVisible(boolean isVisible){ + if(isVisible) { + measurementRow.setVisibility(View.VISIBLE); + } else { + measurementRow.setVisibility(View.GONE); + } + } + + private int pxImageDp(float dp) { + return (int)(dp * getResources().getDisplayMetrics().density + 0.5f); + } + + public boolean validateInput() { + if (measurementRow.getVisibility() == View.VISIBLE) { + if (valueView.getText().toString().length() == 0) { + valueView.setError(getResources().getString(R.string.error_value_required)); + return false; + } + + float value = Float.valueOf(valueView.getText().toString()); + + if (!(value >= 0 && value <= getMaxValue())) { + valueView.setError(getResources().getString(R.string.error_value_range)); + return false; + } + } + + return true; + } + + private void evaluate(float value) { + EvaluationSheet evalSheet = new EvaluationSheet(getScaleUser()); + EvaluationResult evalResult = evaluateSheet(evalSheet, value); + + evaluatorView.setMinMaxValue(getMinValue(), getMaxValue()); + evaluatorView.setLimits(evalResult.lowLimit, evalResult.highLimit); + evaluatorView.setValue(value); + + switch(evalResult.eval_state) + { + case LOW: + indicatorView.setBackgroundColor(ChartUtils.COLOR_BLUE); + break; + case NORMAL: + indicatorView.setBackgroundColor(ChartUtils.COLOR_GREEN); + break; + case HIGH: + indicatorView.setBackgroundColor(ChartUtils.COLOR_RED); + break; + case UNDEFINED: + indicatorView.setBackgroundColor(Color.GRAY); + break; + } + } + + protected ScaleUser getScaleUser() { + OpenScale openScale = OpenScale.getInstance(getContext()); + + return openScale.getSelectedScaleUser(); + } + + private class onClickListenerEvaluation implements View.OnClickListener { + @Override + public void onClick(View v) { + if (isEditModeOn()) { + return; + } + + if (evaluatorRow.getVisibility() == View.VISIBLE) { + evaluatorRow.setVisibility(View.GONE); + } else { + evaluatorRow.setVisibility(View.VISIBLE); + } + } + } +} + diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/MuscleMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/MuscleMeasurementView.java new file mode 100644 index 00000000..7defcd48 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/MuscleMeasurementView.java @@ -0,0 +1,58 @@ +package com.health.openscale.gui.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.v4.content.ContextCompat; +import android.text.InputType; + +import com.health.openscale.R; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.evaluation.EvaluationResult; +import com.health.openscale.core.evaluation.EvaluationSheet; + +public class MuscleMeasurementView extends MeasurementView { + + public MuscleMeasurementView(Context context) { + super(context, context.getResources().getString(R.string.label_muscle), ContextCompat.getDrawable(context, R.drawable.muscle)); + } + + @Override + public void updateValue(ScaleData updateData) { + setValueOnView(updateData.muscle); + } + + @Override + public void updateDiff(ScaleData updateData, ScaleData lastData) { + setDiffOnView(updateData.muscle, lastData.muscle); + } + + @Override + public String getUnit() { + return "%"; + } + + @Override + public void updatePreferences(SharedPreferences preferences) { + setVisible(preferences.getBoolean("muscleEnable", true)); + } + + @Override + public EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { + return evalSheet.evaluateBodyMuscle(value); + } + + @Override + public float getMinValue() { + return 10; + } + + @Override + public float getMaxValue() { + return 80; + } + + @Override + int getInputType() { + return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/WHRMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/WHRMeasurementView.java new file mode 100644 index 00000000..dd8911f2 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/WHRMeasurementView.java @@ -0,0 +1,62 @@ +package com.health.openscale.gui.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.v4.content.ContextCompat; + +import com.health.openscale.R; +import com.health.openscale.core.datatypes.ScaleCalculator; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.evaluation.EvaluationResult; +import com.health.openscale.core.evaluation.EvaluationSheet; + +public class WHRMeasurementView extends MeasurementView { + + public WHRMeasurementView(Context context) { + super(context, context.getResources().getString(R.string.label_whr), ContextCompat.getDrawable(context, R.drawable.whr)); + } + + @Override + public void updateValue(ScaleData updateData) { + ScaleCalculator updateCalculator = new ScaleCalculator(updateData); + setValueOnView(updateCalculator.getWHR()); + } + + @Override + public void updateDiff(ScaleData updateData, ScaleData lastData) { + ScaleCalculator updateCalculator = new ScaleCalculator(updateData); + ScaleCalculator lastCalculator = new ScaleCalculator(lastData); + setDiffOnView(updateCalculator.getWHR(), lastCalculator.getWHR()); + } + + @Override + public String getUnit() { + return ""; + } + + @Override + public void updatePreferences(SharedPreferences preferences) { + setVisible(preferences.getBoolean("hipEnable", true) && preferences.getBoolean("waistEnable", true)); + } + + @Override + public EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { + return evalSheet.evaluateWHR(value); + } + + @Override + public float getMinValue() { + return 0.5f; + } + + @Override + public float getMaxValue() { + return 1.5f; + } + + @Override + int getInputType() { + return 0; + } + +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/WHtRMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/WHtRMeasurementView.java new file mode 100644 index 00000000..5cdb8941 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/WHtRMeasurementView.java @@ -0,0 +1,61 @@ +package com.health.openscale.gui.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.v4.content.ContextCompat; + +import com.health.openscale.R; +import com.health.openscale.core.datatypes.ScaleCalculator; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.evaluation.EvaluationResult; +import com.health.openscale.core.evaluation.EvaluationSheet; + +public class WHtRMeasurementView extends MeasurementView { + + public WHtRMeasurementView(Context context) { + super(context, context.getResources().getString(R.string.label_whtr), ContextCompat.getDrawable(context, R.drawable.whtr)); + } + + @Override + public void updateValue(ScaleData updateData) { + ScaleCalculator updateCalculator = new ScaleCalculator(updateData); + setValueOnView(updateCalculator.getWHtR(getScaleUser().body_height)); + } + + @Override + public void updateDiff(ScaleData updateData, ScaleData lastData) { + ScaleCalculator updateCalculator = new ScaleCalculator(updateData); + ScaleCalculator lastCalculator = new ScaleCalculator(lastData); + setDiffOnView(updateCalculator.getWHtR(getScaleUser().body_height), lastCalculator.getWHtR(getScaleUser().body_height)); + } + + @Override + public String getUnit() { + return ""; + } + + @Override + public void updatePreferences(SharedPreferences preferences) { + setVisible(preferences.getBoolean("waistEnable", true)); + } + + @Override + public EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { + return evalSheet.evaluateWHtR(value); + } + + @Override + public float getMinValue() { + return 0; + } + + @Override + public float getMaxValue() { + return 1; + } + + @Override + int getInputType() { + return 0; + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/WaistMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/WaistMeasurementView.java new file mode 100644 index 00000000..0f9043dd --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/WaistMeasurementView.java @@ -0,0 +1,58 @@ +package com.health.openscale.gui.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.v4.content.ContextCompat; +import android.text.InputType; + +import com.health.openscale.R; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.evaluation.EvaluationResult; +import com.health.openscale.core.evaluation.EvaluationSheet; + +public class WaistMeasurementView extends MeasurementView { + + public WaistMeasurementView(Context context) { + super(context, context.getResources().getString(R.string.label_waist), ContextCompat.getDrawable(context, R.drawable.waist)); + } + + @Override + public void updateValue(ScaleData updateData) { + setValueOnView(updateData.waist); + } + + @Override + public void updateDiff(ScaleData updateData, ScaleData lastData) { + setDiffOnView(updateData.waist, lastData.waist); + } + + @Override + public String getUnit() { + return "cm"; + } + + @Override + public void updatePreferences(SharedPreferences preferences) { + setVisible(preferences.getBoolean("waistEnable", true)); + } + + @Override + public EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { + return evalSheet.evaluateWaist(value); + } + + @Override + public float getMinValue() { + return 30; + } + + @Override + public float getMaxValue() { + return 200; + } + + @Override + int getInputType() { + return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/WaterMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/WaterMeasurementView.java new file mode 100644 index 00000000..1fbf801e --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/WaterMeasurementView.java @@ -0,0 +1,58 @@ +package com.health.openscale.gui.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.v4.content.ContextCompat; +import android.text.InputType; + +import com.health.openscale.R; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.evaluation.EvaluationResult; +import com.health.openscale.core.evaluation.EvaluationSheet; + +public class WaterMeasurementView extends MeasurementView { + + public WaterMeasurementView(Context context) { + super(context, context.getResources().getString(R.string.label_water), ContextCompat.getDrawable(context, R.drawable.water)); + } + + @Override + public void updateValue(ScaleData updateData) { + setValueOnView(updateData.water); + } + + @Override + public void updateDiff(ScaleData updateData, ScaleData lastData) { + setDiffOnView(updateData.water, lastData.water); + } + + @Override + public String getUnit() { + return "%"; + } + + @Override + public void updatePreferences(SharedPreferences preferences) { + setVisible(preferences.getBoolean("waterEnable", true)); + } + + @Override + public EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { + return evalSheet.evaluateBodyWater(value); + } + + @Override + public float getMinValue() { + return 30; + } + + @Override + public float getMaxValue() { + return 80; + } + + @Override + int getInputType() { + return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/WeightMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/WeightMeasurementView.java new file mode 100644 index 00000000..5461a81f --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/WeightMeasurementView.java @@ -0,0 +1,59 @@ +package com.health.openscale.gui.views; + +import android.content.Context; +import android.content.SharedPreferences; +import android.support.v4.content.ContextCompat; +import android.text.InputType; + +import com.health.openscale.R; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.datatypes.ScaleUser; +import com.health.openscale.core.evaluation.EvaluationResult; +import com.health.openscale.core.evaluation.EvaluationSheet; + +public class WeightMeasurementView extends MeasurementView { + + public WeightMeasurementView(Context context) { + super(context, context.getResources().getString(R.string.label_weight), ContextCompat.getDrawable(context, R.drawable.weight)); + } + + @Override + public void updateValue(ScaleData updateData) { + setValueOnView(updateData.weight); + } + + @Override + public void updateDiff(ScaleData updateData, ScaleData lastData) { + setDiffOnView(updateData.weight, lastData.weight); + } + + @Override + public String getUnit() { + return ScaleUser.UNIT_STRING[getScaleUser().scale_unit]; + } + + @Override + public void updatePreferences(SharedPreferences preferences) { + setVisible(preferences.getBoolean("weightEnable", true)); + } + + @Override + public EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value) { + return evalSheet.evaluateWeight(value); + } + + @Override + public float getMinValue() { + return 30; + } + + @Override + public float getMaxValue() { + return 300; + } + + @Override + int getInputType() { + return InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED; + } +}