Tables set up, JSON implementations deprecated
This commit is contained in:
parent
918b935be0
commit
a1c72f8ef9
@ -33,5 +33,4 @@ dependencies {
|
||||
compile 'com.android.support:support-v4:23.2.1'
|
||||
compile 'com.android.support:recyclerview-v7:23.2.1'
|
||||
compile 'com.jakewharton:butterknife:7.0.1'
|
||||
compile project(':datetimepicker')
|
||||
}
|
||||
|
||||
@ -5,13 +5,10 @@ import android.support.annotation.NonNull;
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.philliphsu.clock2.model.JsonSerializable;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static com.philliphsu.clock2.DaysOfWeek.NUM_DAYS;
|
||||
import static com.philliphsu.clock2.DaysOfWeek.SATURDAY;
|
||||
@ -24,24 +21,13 @@ import static com.philliphsu.clock2.DaysOfWeek.SUNDAY;
|
||||
public abstract class Alarm implements JsonSerializable {
|
||||
private static final int MAX_MINUTES_CAN_SNOOZE = 30;
|
||||
|
||||
// JSON property names
|
||||
private static final String KEY_SNOOZING_UNTIL_MILLIS = "snoozing_until_millis";
|
||||
private static final String KEY_ENABLED = "enabled";
|
||||
private static final String KEY_RECURRING_DAYS = "recurring_days";
|
||||
//private static final String KEY_ID = "id"; // Defined in JsonSerializable
|
||||
private static final String KEY_HOUR = "hour";
|
||||
private static final String KEY_MINUTES = "minutes";
|
||||
private static final String KEY_LABEL = "label";
|
||||
private static final String KEY_RINGTONE = "ringtone";
|
||||
private static final String KEY_VIBRATES = "vibrates";
|
||||
|
||||
// ========= MUTABLE ==============
|
||||
// =================== MUTABLE =======================
|
||||
private long id;
|
||||
private long snoozingUntilMillis;
|
||||
private boolean enabled;
|
||||
private final boolean[] recurringDays = new boolean[NUM_DAYS];
|
||||
// ================================
|
||||
// ====================================================
|
||||
|
||||
//public abstract long id();
|
||||
public abstract int hour();
|
||||
public abstract int minutes();
|
||||
public abstract String label();
|
||||
@ -50,35 +36,15 @@ public abstract class Alarm implements JsonSerializable {
|
||||
/** Initializes a Builder to the same property values as this instance */
|
||||
public abstract Builder toBuilder();
|
||||
|
||||
@Deprecated
|
||||
public static Alarm create(JSONObject jsonObject) {
|
||||
try {
|
||||
Alarm alarm = new AutoValue_Alarm.Builder()
|
||||
.id(jsonObject.getLong(KEY_ID))
|
||||
.hour(jsonObject.getInt(KEY_HOUR))
|
||||
.minutes(jsonObject.getInt(KEY_MINUTES))
|
||||
.label(jsonObject.getString(KEY_LABEL))
|
||||
.ringtone(jsonObject.getString(KEY_RINGTONE))
|
||||
.vibrates(jsonObject.getBoolean(KEY_VIBRATES))
|
||||
.rebuild();
|
||||
alarm.setEnabled(jsonObject.getBoolean(KEY_ENABLED));
|
||||
alarm.snoozingUntilMillis = jsonObject.getLong(KEY_SNOOZING_UNTIL_MILLIS);
|
||||
|
||||
JSONArray a = (JSONArray) jsonObject.get(KEY_RECURRING_DAYS);
|
||||
for (int i = 0; i < a.length(); i++) {
|
||||
alarm.recurringDays[i] = a.getBoolean(i);
|
||||
}
|
||||
|
||||
return alarm;
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
// Unfortunately, default values must be provided for generated Builders.
|
||||
// Fields that were not set when build() is called will throw an exception.
|
||||
return new AutoValue_Alarm.Builder()
|
||||
.id(-1)
|
||||
.hour(0)
|
||||
.minutes(0)
|
||||
.label("")
|
||||
@ -211,59 +177,46 @@ public abstract class Alarm implements JsonSerializable {
|
||||
return ringsIn() <= hours * 3600000;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int intId() {
|
||||
return (int) id();
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public final long id() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
@NonNull
|
||||
public JSONObject toJsonObject() {
|
||||
try {
|
||||
return new JSONObject()
|
||||
.put(KEY_SNOOZING_UNTIL_MILLIS, snoozingUntilMillis)
|
||||
.put(KEY_ENABLED, enabled)
|
||||
.put(KEY_RECURRING_DAYS, new JSONArray(recurringDays))
|
||||
.put(KEY_ID, id())
|
||||
.put(KEY_HOUR, hour())
|
||||
.put(KEY_MINUTES, minutes())
|
||||
.put(KEY_LABEL, label())
|
||||
.put(KEY_RINGTONE, ringtone())
|
||||
.put(KEY_VIBRATES, vibrates());
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
private static final AtomicLong ID_COUNTER = new AtomicLong(0);
|
||||
// By omitting the set- prefix, we reduce the number of changes required to define the Builder
|
||||
// class after copying and pasting the accessor fields here.
|
||||
public abstract Builder id(long id);
|
||||
public abstract Builder hour(int hour);
|
||||
public abstract Builder minutes(int minutes);
|
||||
public abstract Builder label(String label);
|
||||
public abstract Builder ringtone(String ringtone);
|
||||
public abstract Builder vibrates(boolean vibrates);
|
||||
// To enforce preconditions, split the build method into two. autoBuild() is hidden from
|
||||
// callers and is generated. You implement the public build(), which calls the generated
|
||||
// autoBuild() and performs your desired validations.
|
||||
/*not public*/abstract Alarm autoBuild();
|
||||
/* package */ abstract Alarm autoBuild();
|
||||
|
||||
public Alarm build() {
|
||||
this.id(ID_COUNTER.incrementAndGet()); // TOneverDO: change to getAndIncrement() without also adding offset of 1 in rebuild()
|
||||
Alarm alarm = autoBuild();
|
||||
doChecks(alarm);
|
||||
return alarm;
|
||||
}
|
||||
|
||||
/** <b>Should only be called when recreating an instance from JSON</b> */
|
||||
private Alarm rebuild() {
|
||||
Alarm alarm = autoBuild();
|
||||
ID_COUNTER.set(alarm.id()); // prevent future instances from id collision
|
||||
doChecks(alarm);
|
||||
return alarm;
|
||||
}
|
||||
}
|
||||
|
||||
private static void doChecks(Alarm alarm) {
|
||||
|
||||
@ -32,12 +32,6 @@ public class DummyContent {
|
||||
}
|
||||
|
||||
private static Alarm createAlarm(int position) {
|
||||
Alarm.Builder b = Alarm.builder();
|
||||
if (position % 2 == 0) {
|
||||
b.hour(21).minutes(0);
|
||||
}
|
||||
Alarm a = b.id(position).build();
|
||||
a.setEnabled(true);
|
||||
return a;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,11 +28,14 @@ import com.philliphsu.clock2.DaysOfWeek;
|
||||
import com.philliphsu.clock2.R;
|
||||
import com.philliphsu.clock2.SharedPreferencesHelper;
|
||||
import com.philliphsu.clock2.model.AlarmsRepository;
|
||||
import com.philliphsu.clock2.model.DatabaseManager;
|
||||
import com.philliphsu.clock2.ringtone.RingtoneActivity;
|
||||
import com.philliphsu.clock2.util.AlarmUtils;
|
||||
import com.philliphsu.clock2.util.LocalBroadcastHelper;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import butterknife.Bind;
|
||||
import butterknife.OnCheckedChanged;
|
||||
@ -182,7 +185,12 @@ public class EditAlarmActivity extends BaseActivity implements AlarmNumpad.KeyLi
|
||||
|
||||
@OnClick(R.id.save)
|
||||
void save() {
|
||||
mPresenter.save();
|
||||
//mPresenter.save();
|
||||
Calendar calendar = new GregorianCalendar();
|
||||
int hour = calendar.get(Calendar.HOUR_OF_DAY);
|
||||
int minutes = calendar.get(Calendar.MINUTE);
|
||||
Alarm alarm = Alarm.builder().hour(hour).minutes((minutes + 1) % 60).build();
|
||||
DatabaseManager.getInstance(this).insertAlarm(alarm);
|
||||
}
|
||||
|
||||
@OnClick(R.id.delete)
|
||||
|
||||
@ -0,0 +1,115 @@
|
||||
package com.philliphsu.clock2.model;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
import com.philliphsu.clock2.Alarm;
|
||||
import com.philliphsu.clock2.DaysOfWeek;
|
||||
|
||||
/**
|
||||
* Created by Phillip Hsu on 6/24/2016.
|
||||
*
|
||||
* TODO: We can generalize this class to all data models, not just Alarms.
|
||||
*/
|
||||
public class AlarmDatabaseHelper extends SQLiteOpenHelper {
|
||||
private static final String DB_NAME = "alarms.db";
|
||||
private static final int VERSION_1 = 1;
|
||||
|
||||
// TODO: Consider creating an inner class that implements BaseColumns
|
||||
// and defines all the columns.
|
||||
private static final String TABLE_ALARMS = "alarms";
|
||||
private static final String COLUMN_ID = "_id";
|
||||
private static final String COLUMN_HOUR = "hour";
|
||||
private static final String COLUMN_MINUTES = "minutes";
|
||||
private static final String COLUMN_LABEL = "label";
|
||||
private static final String COLUMN_RINGTONE = "ringtone";
|
||||
private static final String COLUMN_VIBRATES = "vibrates";
|
||||
private static final String COLUMN_ENABLED = "enabled";
|
||||
private static final String COLUMN_SNOOZING_UNTIL_MILLIS = "snoozing_until_millis";
|
||||
|
||||
// TODO: Consider creating an inner class that implements BaseColumns
|
||||
// and defines all the columns.
|
||||
private static final String TABLE_ALARM_RECURRING_DAYS = "alarm_recurring_days";
|
||||
private static final String COLUMN_ALARM_ID = "alarm_id";
|
||||
private static final String COLUMN_SUNDAY = "sunday";
|
||||
private static final String COLUMN_MONDAY = "monday";
|
||||
private static final String COLUMN_TUESDAY = "tuesday";
|
||||
private static final String COLUMN_WEDNESDAY = "wednesday";
|
||||
private static final String COLUMN_THURSDAY = "thursday";
|
||||
private static final String COLUMN_FRIDAY = "friday";
|
||||
private static final String COLUMN_SATURDAY = "saturday";
|
||||
|
||||
private static void createAlarmsTable(SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE " + TABLE_ALARMS + " ("
|
||||
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ COLUMN_HOUR + " INTEGER NOT NULL, "
|
||||
+ COLUMN_MINUTES + " INTEGER NOT NULL, "
|
||||
+ COLUMN_LABEL + " TEXT, "
|
||||
+ COLUMN_RINGTONE + " TEXT NOT NULL, "
|
||||
+ COLUMN_VIBRATES + " INTEGER NOT NULL, "
|
||||
+ COLUMN_ENABLED + " INTEGER NOT NULL, "
|
||||
+ COLUMN_SNOOZING_UNTIL_MILLIS + " INTEGER);");
|
||||
}
|
||||
|
||||
private static void createRecurringDaysTable(SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE " + TABLE_ALARM_RECURRING_DAYS + " ("
|
||||
+ COLUMN_ALARM_ID + " INTEGER REFERENCES " + TABLE_ALARMS + "(" + COLUMN_ID + "), "
|
||||
+ COLUMN_SUNDAY + " INTEGER NOT NULL DEFAULT 0, "
|
||||
+ COLUMN_MONDAY + " INTEGER NOT NULL DEFAULT 0, "
|
||||
+ COLUMN_TUESDAY + " INTEGER NOT NULL DEFAULT 0, "
|
||||
+ COLUMN_WEDNESDAY + " INTEGER NOT NULL DEFAULT 0, "
|
||||
+ COLUMN_THURSDAY + " INTEGER NOT NULL DEFAULT 0, "
|
||||
+ COLUMN_FRIDAY + " INTEGER NOT NULL DEFAULT 0, "
|
||||
+ COLUMN_SATURDAY + " INTEGER NOT NULL DEFAULT 0);");
|
||||
}
|
||||
|
||||
public AlarmDatabaseHelper(Context context) {
|
||||
super(context, DB_NAME, null, VERSION_1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
// https://www.sqlite.org/datatype3.html
|
||||
// INTEGER data type is stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude
|
||||
// of the value. As soon as INTEGER values are read off of disk and into memory for processing,
|
||||
// they are converted to the most general datatype (8-byte signed integer).
|
||||
// 8 byte == 64 bits so this means they are read as longs...?
|
||||
createAlarmsTable(db);
|
||||
createRecurringDaysTable(db);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
// I don't think we need to drop current tables unless you make structural changes
|
||||
// to the schema in the new version.
|
||||
}
|
||||
|
||||
// TODO: Consider changing param to Alarm.Builder so the Alarm that will be
|
||||
// built can have its ID set.
|
||||
public long insertAlarm(Alarm alarm) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(COLUMN_HOUR, alarm.hour());
|
||||
values.put(COLUMN_MINUTES, alarm.minutes());
|
||||
values.put(COLUMN_LABEL, alarm.label());
|
||||
values.put(COLUMN_RINGTONE, alarm.ringtone());
|
||||
values.put(COLUMN_VIBRATES, alarm.vibrates());
|
||||
values.put(COLUMN_ENABLED, alarm.isEnabled());
|
||||
values.put(COLUMN_SNOOZING_UNTIL_MILLIS, alarm.snoozingUntil());
|
||||
long id = getWritableDatabase().insert(TABLE_ALARMS, null, values);
|
||||
alarm.setId(id);
|
||||
|
||||
values = new ContentValues();
|
||||
values.put(COLUMN_ALARM_ID, id);
|
||||
values.put(COLUMN_SUNDAY, alarm.isRecurring(DaysOfWeek.SUNDAY));
|
||||
values.put(COLUMN_MONDAY, alarm.isRecurring(DaysOfWeek.MONDAY));
|
||||
values.put(COLUMN_TUESDAY, alarm.isRecurring(DaysOfWeek.TUESDAY));
|
||||
values.put(COLUMN_WEDNESDAY, alarm.isRecurring(DaysOfWeek.WEDNESDAY));
|
||||
values.put(COLUMN_THURSDAY, alarm.isRecurring(DaysOfWeek.THURSDAY));
|
||||
values.put(COLUMN_FRIDAY, alarm.isRecurring(DaysOfWeek.FRIDAY));
|
||||
values.put(COLUMN_SATURDAY, alarm.isRecurring(DaysOfWeek.SATURDAY));
|
||||
getWritableDatabase().insert(TABLE_ALARM_RECURRING_DAYS, null, values);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@ import org.json.JSONObject;
|
||||
/**
|
||||
* Created by Phillip Hsu on 5/31/2016.
|
||||
*/
|
||||
@Deprecated
|
||||
public class AlarmIoHelper extends JsonIoHelper<Alarm> {
|
||||
private static final String FILENAME = "alarms.json";
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import com.philliphsu.clock2.Alarm;
|
||||
/**
|
||||
* Created by Phillip Hsu on 5/31/2016.
|
||||
*/
|
||||
@Deprecated
|
||||
public class AlarmsRepository extends BaseRepository<Alarm> {
|
||||
private static final String TAG = "AlarmsRepository";
|
||||
// Singleton, so this is the sole instance for the lifetime
|
||||
|
||||
@ -13,6 +13,7 @@ import java.util.List;
|
||||
/**
|
||||
* Created by Phillip Hsu on 5/31/2016.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class BaseRepository<T extends JsonSerializable> implements Repository<T> {
|
||||
private static final String TAG = "BaseRepository";
|
||||
// Cannot do this! Multiple classes will extend from this,
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package com.philliphsu.clock2.model;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.philliphsu.clock2.Alarm;
|
||||
|
||||
/**
|
||||
* Created by Phillip Hsu on 6/25/2016.
|
||||
*
|
||||
* TODO: Not sure this class is all that useful? We could make the DbHelper singleton instance in its own class.
|
||||
*/
|
||||
public class DatabaseManager {
|
||||
|
||||
private static DatabaseManager sDatabaseManager;
|
||||
private final Context mContext;
|
||||
private final AlarmDatabaseHelper mHelper;
|
||||
|
||||
private DatabaseManager(Context context) {
|
||||
mContext = context.getApplicationContext();
|
||||
mHelper = new AlarmDatabaseHelper(mContext);
|
||||
}
|
||||
|
||||
public static DatabaseManager getInstance(Context context) {
|
||||
if (sDatabaseManager == null) {
|
||||
sDatabaseManager = new DatabaseManager(context);
|
||||
}
|
||||
return sDatabaseManager;
|
||||
}
|
||||
|
||||
public Alarm insertAlarm(Alarm alarm) {
|
||||
mHelper.insertAlarm(alarm);
|
||||
return alarm;
|
||||
}
|
||||
}
|
||||
@ -19,6 +19,7 @@ import java.util.List;
|
||||
/**
|
||||
* Created by Phillip Hsu on 5/31/2016.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class JsonIoHelper<T extends JsonSerializable> {
|
||||
@NonNull private final Context mContext;
|
||||
@NonNull private final String mFilename;
|
||||
|
||||
@ -8,6 +8,7 @@ import org.json.JSONObject;
|
||||
/**
|
||||
* Created by Phillip Hsu on 5/31/2016.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface JsonSerializable {
|
||||
String KEY_ID = "id";
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user