diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBAlarm.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBAlarm.java index 83dc8cae3..e53b71f23 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBAlarm.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBAlarm.java @@ -6,10 +6,14 @@ import android.os.Parcelable; import android.preference.PreferenceManager; import java.util.Calendar; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; -import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.PREF_MIBAND_ALARM_PREFIX; +import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.PREF_MIBAND_ALARMS; -public class GBAlarm implements Parcelable { + +public class GBAlarm implements Parcelable, Comparable { private int index; private boolean enabled; @@ -27,9 +31,8 @@ public class GBAlarm implements Parcelable { public static final byte ALARM_SAT = 32; public static final byte ALARM_SUN = 64; - public static final String DEFAULT_ALARM1 = "0,false,true,31,7,30"; - public static final String DEFAULT_ALARM2 = "1,false,false,96,8,00"; - public static final String DEFAULT_ALARM3 = "2,false,false,0,15,30"; + public static final String[] DEFAULT_ALARMS = {"2,false,false,0,15,30","1,false,false,96,8,0","0,false,true,31,7,30"}; + public GBAlarm(int index, boolean enabled, boolean smartWakeup, byte repetition, int hour, int minute) { this.index = index; @@ -38,7 +41,6 @@ public class GBAlarm implements Parcelable { this.repetition = repetition; this.hour = hour; this.minute = minute; - store(); } public GBAlarm(String fromPreferences){ @@ -50,7 +52,6 @@ public class GBAlarm implements Parcelable { this.repetition = Integer.parseInt(tokens[3]); this.hour = Integer.parseInt(tokens[4]); this.minute = Integer.parseInt(tokens[5]); - store(); } private static GBAlarm readFromParcel(Parcel pc) { @@ -73,6 +74,11 @@ public class GBAlarm implements Parcelable { } } + @Override + public int hashCode() { + return getIndex(); + } + @Override public int describeContents() { return 0; @@ -88,6 +94,16 @@ public class GBAlarm implements Parcelable { dest.writeInt(this.minute); } + @Override + public int compareTo(Object another) { + if (this.getIndex() < ((GBAlarm)another).getIndex()) { + return -1; + }else if (this.getIndex() > ((GBAlarm)another).getIndex()) { + return 1; + } + return 0; + } + public int getIndex() { return this.index; } @@ -137,7 +153,6 @@ public class GBAlarm implements Parcelable { public void setSmartWakeup(boolean smartWakeup) { this.smartWakeup = smartWakeup; - store(); } public void setRepetition(boolean mon, boolean tue, boolean wed, boolean thu, boolean fri, boolean sat, boolean sun) { @@ -149,29 +164,37 @@ public class GBAlarm implements Parcelable { (fri ? ALARM_FRI : 0) | (sat ? ALARM_SAT : 0) | (sun ? ALARM_SUN : 0); - store(); } public void setHour(int hour) { this.hour = hour; - store(); } public void setMinute(int minute) { this.minute = minute; - store(); } public void setEnabled(boolean enabled) { this.enabled = enabled; - store(); // TODO: if we have many setters, this may become a bottleneck } - private void store() { - //TODO: I don't like to have the alarm index both in the preference name and in the value + public void store() { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(GBApplication.getContext()); - String pref = PREF_MIBAND_ALARM_PREFIX +(this.index+1); - sharedPrefs.edit().putString(pref, this.toPreferences()).apply(); + Set preferencesAlarmListSet = sharedPrefs.getStringSet(PREF_MIBAND_ALARMS, new HashSet()); + //the old Set cannot be updated in place see http://developer.android.com/reference/android/content/SharedPreferences.html#getStringSet%28java.lang.String,%20java.util.Set%3Cjava.lang.String%3E%29 + Set newPrefs = new HashSet(preferencesAlarmListSet); + + Iterator iterator = newPrefs.iterator(); + + while (iterator.hasNext()) { + String alarmString = iterator.next(); + if(this.equals(new GBAlarm(alarmString))) { + iterator.remove(); + } + } + newPrefs.add(this.toPreferences()); + sharedPrefs.edit().putStringSet(PREF_MIBAND_ALARMS, newPrefs).commit(); + return; } public static final Creator CREATOR = new Creator() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java index 41cdc893a..1f689de55 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AlarmDetails.java @@ -1,29 +1,20 @@ package nodomain.freeyourgadget.gadgetbridge.activities; import android.app.Activity; -import android.content.SharedPreferences; import android.os.Bundle; import android.os.Parcelable; -import android.preference.PreferenceManager; import android.text.format.DateFormat; +import android.view.MenuItem; import android.view.View; import android.widget.CheckedTextView; import android.widget.TimePicker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import nodomain.freeyourgadget.gadgetbridge.GBAlarm; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; -import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.PREF_MIBAND_ALARM_PREFIX; - public class AlarmDetails extends Activity { - private static final Logger LOG = LoggerFactory.getLogger(AlarmDetails.class); - - private GBAlarm alarm; private TimePicker timePicker; //using CheckedTextView allows for vertically aligned text @@ -121,13 +112,23 @@ public class AlarmDetails extends Activity { } - @Override - protected void onDestroy() { - super.onDestroy(); + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + // back button + updateAlarm(); + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + private void updateAlarm() { alarm.setSmartWakeup(ctvSmartWakeup.isChecked()); - alarm.setRepetition(ctvMonday.isChecked(),ctvTuesday.isChecked(),ctvWednesday.isChecked(),ctvThursday.isChecked(),ctvFriday.isChecked(),ctvSaturday.isChecked(),ctvSunday.isChecked()); + alarm.setRepetition(ctvMonday.isChecked(), ctvTuesday.isChecked(), ctvWednesday.isChecked(), ctvThursday.isChecked(), ctvFriday.isChecked(), ctvSaturday.isChecked(), ctvSunday.isChecked()); alarm.setHour(timePicker.getCurrentHour()); alarm.setMinute(timePicker.getCurrentMinute()); + alarm.store(); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java index b5a344565..ce3c147bc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java @@ -1,57 +1,86 @@ package nodomain.freeyourgadget.gadgetbridge.activities; +import android.app.ListActivity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; -import android.app.Activity; import android.preference.PreferenceManager; -import android.widget.ListView; +import android.view.MenuItem; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import nodomain.freeyourgadget.gadgetbridge.BluetoothCommunicationService; import nodomain.freeyourgadget.gadgetbridge.GBAlarm; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.adapter.GBAlarmListAdapter; -import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.PREF_MIBAND_ALARM1; -import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.PREF_MIBAND_ALARM2; -import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.PREF_MIBAND_ALARM3; + +import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.PREF_MIBAND_ALARMS; -import java.util.ArrayList; -import java.util.List; +public class ConfigureAlarms extends ListActivity { - -public class ConfigureAlarms extends Activity { - - ListView alarmListView; private GBAlarmListAdapter mGBAlarmListAdapter; - - final ArrayList alarmList = new ArrayList<>(); + private Set preferencesAlarmListSet; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setContentView(R.layout.activity_configure_alarms); getActionBar().setDisplayHomeAsUpEnabled(true); SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); - //The GBAlarm class initializes the sharedPrefs values if they're missing, no need to handle it here - alarmList.add(new GBAlarm(sharedPrefs.getString(PREF_MIBAND_ALARM1, GBAlarm.DEFAULT_ALARM1))); - alarmList.add(new GBAlarm(sharedPrefs.getString(PREF_MIBAND_ALARM2, GBAlarm.DEFAULT_ALARM2))); - alarmList.add(new GBAlarm(sharedPrefs.getString(PREF_MIBAND_ALARM3, GBAlarm.DEFAULT_ALARM3))); + preferencesAlarmListSet = sharedPrefs.getStringSet(PREF_MIBAND_ALARMS, new HashSet()); + if (preferencesAlarmListSet.isEmpty()) { + //initialize the preferences + preferencesAlarmListSet = new HashSet<>(Arrays.asList(GBAlarm.DEFAULT_ALARMS)); + sharedPrefs.edit().putStringSet(PREF_MIBAND_ALARMS, preferencesAlarmListSet).commit(); + } + + mGBAlarmListAdapter = new GBAlarmListAdapter(this, preferencesAlarmListSet); + + setListAdapter(mGBAlarmListAdapter); - alarmListView = (ListView) findViewById(R.id.alarmListView); - mGBAlarmListAdapter = new GBAlarmListAdapter(this, alarmList); - alarmListView.setAdapter(this.mGBAlarmListAdapter); } @Override - protected void onDestroy() { - super.onDestroy(); + protected void onResume() { + super.onResume(); + + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); + preferencesAlarmListSet = sharedPrefs.getStringSet(PREF_MIBAND_ALARMS, new HashSet()); + + mGBAlarmListAdapter.setAlarmList(preferencesAlarmListSet); + mGBAlarmListAdapter.notifyDataSetChanged(); + + sendAlarmsToDevice(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + // back button + sendAlarmsToDevice(); + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + public void configureAlarm(GBAlarm alarm) { + Intent startIntent; + startIntent = new Intent(getApplicationContext(), AlarmDetails.class); + startIntent.putExtra("alarm", alarm); + startActivity(startIntent); + } + + private void sendAlarmsToDevice() { Intent startIntent = new Intent(ConfigureAlarms.this, BluetoothCommunicationService.class); - startIntent.putParcelableArrayListExtra("alarms", alarmList); + startIntent.putParcelableArrayListExtra("alarms", mGBAlarmListAdapter.getAlarmList()); startIntent.setAction(BluetoothCommunicationService.ACTION_SET_ALARMS); startService(startIntent); } - } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java index 78e6c3be1..3952647f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java @@ -1,13 +1,9 @@ package nodomain.freeyourgadget.gadgetbridge.adapter; -import android.app.Activity; import android.content.Context; -import android.content.SharedPreferences; import android.graphics.Color; -import android.preference.PreferenceManager; import android.view.LayoutInflater; -import android.content.Intent; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; @@ -15,30 +11,100 @@ import android.widget.CompoundButton; import android.widget.Switch; import android.widget.TextView; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; + import nodomain.freeyourgadget.gadgetbridge.GBAlarm; import nodomain.freeyourgadget.gadgetbridge.R; -import nodomain.freeyourgadget.gadgetbridge.activities.AlarmDetails; - - -import java.util.List; - -import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.PREF_MIBAND_ALARM1; -import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.PREF_MIBAND_ALARM2; -import static nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst.PREF_MIBAND_ALARM3; +import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms; public class GBAlarmListAdapter extends ArrayAdapter { + + private final Context mContext; + private ArrayList alarmList; - private List alarmList; - - public GBAlarmListAdapter(Context context, List alarmList) { + public GBAlarmListAdapter(Context context, ArrayList alarmList) { super(context, 0, alarmList); this.mContext = context; this.alarmList = alarmList; } + public GBAlarmListAdapter(Context context,Set preferencesAlarmListSet) { + super(context, 0, new ArrayList()); + + this.mContext = context; + alarmList = new ArrayList(); + + if (preferencesAlarmListSet != null) { + Iterator iterator = preferencesAlarmListSet.iterator(); + + while (iterator.hasNext()) { + String alarmString = iterator.next(); + alarmList.add(new GBAlarm(alarmString)); + } + } + + Collections.sort(alarmList); + } + + public void setAlarmList(Set preferencesAlarmListSet) { + alarmList = new ArrayList(); + + if (preferencesAlarmListSet != null) { + Iterator iterator = preferencesAlarmListSet.iterator(); + + while (iterator.hasNext()) { + String alarmString = iterator.next(); + alarmList.add(new GBAlarm(alarmString)); + } + } + + Collections.sort(alarmList); + } + + public ArrayList getAlarmList() { + return alarmList; + } + + + public void update(GBAlarm alarm) { + for (GBAlarm a : alarmList) { + if(alarm.equals(a)) { + a = alarm; + } + } + alarm.store(); + } + + @Override + public int getCount() { + if (alarmList != null) { + return alarmList.size(); + } + return 0; + } + + @Override + public GBAlarm getItem(int position) { + if (alarmList != null) { + return alarmList.get(position); + } + return null; + } + + @Override + public long getItemId(int position) { + if (alarmList != null) { + return alarmList.get(position).getIndex(); + } + return 0; + } + @Override public View getView(int position, View view, ViewGroup parent) { @@ -66,16 +132,14 @@ public class GBAlarmListAdapter extends ArrayAdapter { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { alarm.setEnabled(isChecked); + update(alarm); } }); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent startIntent; - startIntent = new Intent(mContext, AlarmDetails.class); - startIntent.putExtra("alarm", alarm); - mContext.startActivity(startIntent); + ((ConfigureAlarms)mContext).configureAlarm(alarm); } }); alarmTime.setText(alarm.getTime()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java index 7d26e07e1..d85cd5ebd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java @@ -15,10 +15,7 @@ public final class MiBandConst { public static final String PREF_USER_WEIGHT_KG = "mi_user_weight_kg"; public static final String PREF_MIBAND_WEARSIDE = "mi_wearside"; public static final String PREF_MIBAND_ADDRESS = "development_miaddr"; // FIXME: should be prefixed mi_ - public static final String PREF_MIBAND_ALARM_PREFIX = "mi_alarm"; - public static final String PREF_MIBAND_ALARM1 = PREF_MIBAND_ALARM_PREFIX +"1"; - public static final String PREF_MIBAND_ALARM2 = PREF_MIBAND_ALARM_PREFIX +"2"; - public static final String PREF_MIBAND_ALARM3 = PREF_MIBAND_ALARM_PREFIX +"3"; + public static final String PREF_MIBAND_ALARMS = "mi_alarms"; public static final String ORIGIN_SMS = "sms"; public static final String ORIGIN_INCOMING_CALL = "incoming_call"; diff --git a/app/src/main/res/layout/activity_alarm_details.xml b/app/src/main/res/layout/activity_alarm_details.xml index 093755186..fbcc82a88 100644 --- a/app/src/main/res/layout/activity_alarm_details.xml +++ b/app/src/main/res/layout/activity_alarm_details.xml @@ -18,7 +18,9 @@ android:layout_height="wrap_content" android:id="@+id/alarm_time_picker" android:layout_alignParentTop="true" - android:layout_alignParentStart="true" /> + android:layout_alignParentStart="true" + android:timePickerMode="clock" + android:layout_weight="1" /> + android:layout_gravity="center_vertical" + android:gravity="center_horizontal" + android:layout_weight="1" /> + android:drawableTop="@drawable/abc_btn_check_material" + android:layout_weight="1" + android:enabled="true" + android:gravity="center_horizontal" /> + android:drawableTop="@drawable/abc_btn_check_material" + android:layout_weight="1" + android:enabled="true" + android:gravity="center_horizontal" /> + android:drawableTop="@drawable/abc_btn_check_material" + android:layout_weight="1" + android:enabled="true" + android:gravity="center_horizontal" /> + android:drawableTop="@drawable/abc_btn_check_material" + android:layout_weight="1" + android:enabled="true" + android:gravity="center_horizontal" /> + android:drawableTop="@drawable/abc_btn_check_material" + android:layout_weight="1" + android:enabled="true" + android:gravity="center_horizontal" /> + android:drawableTop="@drawable/abc_btn_check_material" + android:layout_weight="1" + android:enabled="true" + android:gravity="center_horizontal" /> + android:drawableTop="@drawable/abc_btn_check_material" + android:layout_weight="1" + android:enabled="true" + android:gravity="center_horizontal" /> diff --git a/app/src/main/res/layout/activity_configure_alarms.xml b/app/src/main/res/layout/activity_configure_alarms.xml index 83e4af074..3dd725a24 100644 --- a/app/src/main/res/layout/activity_configure_alarms.xml +++ b/app/src/main/res/layout/activity_configure_alarms.xml @@ -10,7 +10,7 @@ android:descendantFocusability="blocksDescendants" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:id="@+id/alarmListView" + android:id="@android:id/list" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" />