--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/list/OnListItemInteractionListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.list;
21 |
22 | /**
23 | * Created by Phillip Hsu on 5/31/2016.
24 | */
25 | public interface OnListItemInteractionListener {
26 | void onListItemClick(T item, int position);
27 | void onListItemDeleted(T item);
28 | void onListItemUpdate(T item, int position);
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_start_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_stop_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_stop_40dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_stop_48dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_settings.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/util/Preconditions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.util;
21 |
22 | /**
23 | * Created by Phillip Hsu on 5/28/2016.
24 | */
25 | public final class Preconditions {
26 | private Preconditions() {}
27 |
28 | public static T checkNotNull(T obj) {
29 | if (null == obj)
30 | throw new NullPointerException();
31 | return obj;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/res/color/fab_icon_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/color/on_enabled_change_fab.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add_48dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_pause_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_header_timesup_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_collapse_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_done_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/test/java/com/philliphsu/clock2/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2;
21 |
22 | import org.junit.Test;
23 |
24 | import static org.junit.Assert.*;
25 |
26 | /**
27 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
28 | */
29 | public class ExampleUnitTest {
30 | @Test
31 | public void addition_isCorrect() throws Exception {
32 | assertEquals(4, 2 + 2);
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
24 | 64dp
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
23 | 328dp
24 | 56dp
25 | 16dp
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/color/tab_icon_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
23 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/util/ConfigurationUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.util;
21 |
22 | import android.content.res.Resources;
23 |
24 | /**
25 | * Created by Phillip Hsu on 8/30/2016.
26 | */
27 | public final class ConfigurationUtils {
28 |
29 | public static int getOrientation(Resources res) {
30 | return res.getConfiguration().orientation;
31 | }
32 |
33 | private ConfigurationUtils() {}
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/philliphsu/clock2/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2;
21 |
22 | import android.app.Application;
23 | import android.test.ApplicationTestCase;
24 |
25 | /**
26 | * Testing Fundamentals
27 | */
28 | public class ApplicationTest extends ApplicationTestCase {
29 | public ApplicationTest() {
30 | super(Application.class);
31 | }
32 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_header_alarm_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_minus_circle_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_ringtone_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add_circle_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_snooze_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_snooze_48dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_error_outline_96dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/test/java/com/philliphsu/clock2/RingtoneServiceTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2;
21 |
22 | import org.junit.runner.RunWith;
23 | import org.robolectric.RobolectricGradleTestRunner;
24 | import org.robolectric.annotation.Config;
25 |
26 | /**
27 | * Created by Phillip Hsu on 5/28/2016.
28 | *
29 | * TODO: Write unit tests...
30 | */
31 | @RunWith(RobolectricGradleTestRunner.class)
32 | @Config(constants = BuildConfig.class)
33 | public class RingtoneServiceTest {
34 |
35 |
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/list/ScrollHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.list;
21 |
22 | /**
23 | * Created by Phillip Hsu on 7/6/2016.
24 | */
25 | public interface ScrollHandler {
26 | /**
27 | * Specifies the stable id of the item we should scroll to in the list.
28 | * This does not scroll the list. This is useful for preparing to scroll
29 | * to the item when it does not yet exist in the list.
30 | */
31 | void setScrollToStableId(long id);
32 |
33 | void scrollToPosition(int position);
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/data/ObjectWithId.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.data;
21 |
22 | /**
23 | * Created by Phillip Hsu on 7/29/2016.
24 | *
25 | * Superclass for objects that can be persisted in SQLite.
26 | */
27 | public abstract class ObjectWithId {
28 | private long id;
29 |
30 | public final long getId() {
31 | return id;
32 | }
33 |
34 | public final void setId(long id) {
35 | this.id = id;
36 | }
37 |
38 | public final int getIntId() {
39 | return (int) id;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_cancel_snooze.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add_lap_40dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
26 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_overflow_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_clock_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add_lap_24dp.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_vibrate_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_backspace_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/values/prefs_timers.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 | Timers
23 |
24 | key_timer_ringtone
25 | Ringtone
26 |
27 | key_timer_vibrate
28 | Vibrate
29 |
30 | key_timer_silence_after
31 | @string/title_silence_after
32 |
--------------------------------------------------------------------------------
/app/src/main/res/values/prefs_world_clock.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 | World Clock
23 |
24 | key_show_time_offsets_from
25 | Show time offsets from
26 | Local time
27 | GMT
28 |
29 | @string/local_time
30 | @string/gmt
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_stopwatch_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_alarm_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/test/java/com/philliphsu/clock2/DurationUtilsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2;
21 |
22 | import com.philliphsu.clock2.util.DurationUtils;
23 |
24 | import org.junit.Test;
25 |
26 | import java.util.Arrays;
27 | import java.util.concurrent.TimeUnit;
28 |
29 | /**
30 | * Created by Phillip Hsu on 6/10/2016.
31 | */
32 | public class DurationUtilsTest {
33 |
34 | @Test
35 | public void testBreakdown() {
36 | long duration = TimeUnit.HOURS.toMillis(45)
37 | + TimeUnit.MINUTES.toMillis(97);
38 | long[] l = DurationUtils.breakdown(duration);
39 | System.out.println(Arrays.toString(l));
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_alarm_96dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/alarms/background/OnBootUpReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.alarms.background;
21 |
22 | import android.content.BroadcastReceiver;
23 | import android.content.Context;
24 | import android.content.Intent;
25 |
26 | public class OnBootUpReceiver extends BroadcastReceiver {
27 | @Override
28 | public void onReceive(Context context, Intent intent) {
29 | // Note that this will be called when the device boots up, not when the app first launches.
30 | // We may have a lot of alarms to reschedule, so do this in the background using an IntentService.
31 | context.startService(new Intent(context, OnBootUpAlarmScheduler.class));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/res/values/aosp_datetimepicker_styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 | false
19 |
20 |
24 |
25 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/util/FragmentTagUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.util;
21 |
22 | import android.support.annotation.IdRes;
23 |
24 | /**
25 | * Created by Phillip Hsu on 9/7/2016.
26 | */
27 | public final class FragmentTagUtils {
28 |
29 | /**
30 | * For general use.
31 | */
32 | public static String makeTag(Class> cls, @IdRes int viewId) {
33 | return cls.getName() + ":" + viewId;
34 | }
35 |
36 | /**
37 | * A version suitable for our ViewHolders.
38 | */
39 | public static String makeTag(Class> cls, @IdRes int viewId, long itemId) {
40 | return makeTag(cls, viewId) + ":" + itemId;
41 | }
42 |
43 | private FragmentTagUtils() {}
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
26 |
27 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles_alarm.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
28 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_timer_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/values/prefs_general.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 | General
23 | System date \u0026 time settings
24 |
25 | key_theme
26 | Theme
27 |
28 | Light
29 | Dark
30 | Black
31 |
32 | @string/theme_light
33 | @string/theme_dark
34 | @string/theme_black
35 |
36 |
37 | last_tab
38 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_timer_96dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/util/TimeFormatUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.util;
21 |
22 | import android.content.Context;
23 |
24 | import java.util.Calendar;
25 | import java.util.Date;
26 |
27 | import static android.text.format.DateFormat.getTimeFormat;
28 |
29 | /**
30 | * Created by Phillip Hsu on 6/3/2016.
31 | */
32 | public final class TimeFormatUtils {
33 |
34 | private TimeFormatUtils() {}
35 |
36 | public static String formatTime(Context context, long millis) {
37 | return getTimeFormat(context).format(new Date(millis));
38 | }
39 |
40 | public static String formatTime(Context context, int hourOfDay, int minute) {
41 | Calendar cal = Calendar.getInstance();
42 | cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
43 | cal.set(Calendar.MINUTE, minute);
44 | return formatTime(context, cal.getTimeInMillis());
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/UntouchableSeekBar.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2;
21 |
22 | import android.content.Context;
23 | import android.support.v7.widget.AppCompatSeekBar;
24 | import android.util.AttributeSet;
25 | import android.view.MotionEvent;
26 |
27 | /**
28 | * A SeekBar that cannot be touch controlled.
29 | */
30 | public class UntouchableSeekBar extends AppCompatSeekBar {
31 |
32 | public UntouchableSeekBar(Context context) {
33 | super(context);
34 | }
35 |
36 | public UntouchableSeekBar(Context context, AttributeSet attrs) {
37 | super(context, attrs);
38 | }
39 |
40 | public UntouchableSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
41 | super(context, attrs, defStyleAttr);
42 | }
43 |
44 | @Override
45 | public final boolean onTouchEvent(MotionEvent event) {
46 | return true;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # https://guides.codepath.com/android/Publishing-to-the-Play-Store
20 | -assumenosideeffects class android.util.Log {
21 | public static boolean isLoggable(java.lang.String, int);
22 | public static int v(...);
23 | public static int i(...);
24 | public static int w(...);
25 | public static int d(...);
26 | public static int e(...);
27 | }
28 |
29 | # https://github.com/JakeWharton/butterknife/issues/409
30 | # https://github.com/JakeWharton/butterknife/blob/master/butterknife/proguard-rules.txt
31 | # Retain generated class which implement Unbinder.
32 | -keep public class * implements butterknife.Unbinder { public (...); }
33 |
34 | # Prevent obfuscation of types which use ButterKnife annotations since the simple name
35 | # is used to reflectively look up the generated ViewBinding.
36 | -keep class butterknife.*
37 | -keepclasseswithmembernames class * { @butterknife.* ; }
38 | -keepclasseswithmembernames class * { @butterknife.* ; }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2017 Phillip Hsu
3 | #
4 | # This file is part of ClockPlus.
5 | #
6 | # ClockPlus is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # ClockPlus is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with ClockPlus. If not, see .
18 | #
19 |
20 | # Project-wide Gradle settings.
21 |
22 | # IDE (e.g. Android Studio) users:
23 | # Gradle settings configured through the IDE *will override*
24 | # any settings specified in this file.
25 |
26 | # For more details on how to configure your build environment visit
27 | # http://www.gradle.org/docs/current/userguide/build_environment.html
28 |
29 | # Specifies the JVM arguments used for the daemon process.
30 | # The setting is particularly useful for tweaking memory settings.
31 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
32 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
33 |
34 | # When configured, Gradle will run in incubating parallel mode.
35 | # This option should only be used with decoupled projects. More details, visit
36 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
37 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/stopwatch/data/LapsCursorLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.stopwatch.data;
21 |
22 | import android.content.Context;
23 |
24 | import com.philliphsu.clock2.data.SQLiteCursorLoader;
25 | import com.philliphsu.clock2.stopwatch.Lap;
26 |
27 | /**
28 | * Created by Phillip Hsu on 8/9/2016.
29 | */
30 | public class LapsCursorLoader extends SQLiteCursorLoader {
31 | public static final String ACTION_CHANGE_CONTENT
32 | = "com.philliphsu.clock2.stopwatch.data.action.CHANGE_CONTENT";
33 |
34 | public LapsCursorLoader(Context context) {
35 | super(context);
36 | }
37 |
38 | @Override
39 | protected LapCursor loadCursor() {
40 | return new LapsTableManager(getContext()).queryItems();
41 | }
42 |
43 | @Override
44 | protected String getOnContentChangeAction() {
45 | return ACTION_CHANGE_CONTENT;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_dismiss_alarm_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_dismiss_alarm_48dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/alarms/data/AlarmsListCursorLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.alarms.data;
21 |
22 | import android.content.Context;
23 |
24 | import com.philliphsu.clock2.alarms.Alarm;
25 | import com.philliphsu.clock2.data.SQLiteCursorLoader;
26 |
27 | /**
28 | * Created by Phillip Hsu on 6/28/2016.
29 | */
30 | public class AlarmsListCursorLoader extends SQLiteCursorLoader {
31 | public static final String ACTION_CHANGE_CONTENT
32 | = "com.philliphsu.clock2.alarms.data.action.CHANGE_CONTENT";
33 |
34 | public AlarmsListCursorLoader(Context context) {
35 | super(context);
36 | }
37 |
38 | @Override
39 | protected AlarmCursor loadCursor() {
40 | return new AlarmsTableManager(getContext()).queryItems();
41 | }
42 |
43 | @Override
44 | protected String getOnContentChangeAction() {
45 | return ACTION_CHANGE_CONTENT;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/timers/data/TimersListCursorLoader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.timers.data;
21 |
22 | import android.content.Context;
23 |
24 | import com.philliphsu.clock2.timers.Timer;
25 | import com.philliphsu.clock2.data.SQLiteCursorLoader;
26 |
27 | /**
28 | * Created by Phillip Hsu on 7/29/2016.
29 | */
30 | public class TimersListCursorLoader extends SQLiteCursorLoader {
31 | public static final String ACTION_CHANGE_CONTENT
32 | = "com.philliphsu.clock2.timers.data.action.CHANGE_CONTENT";
33 |
34 | public TimersListCursorLoader(Context context) {
35 | super(context);
36 | }
37 |
38 | @Override
39 | protected TimerCursor loadCursor() {
40 | return new TimersTableManager(getContext()).queryItems();
41 | }
42 |
43 | @Override
44 | protected String getOnContentChangeAction() {
45 | return ACTION_CHANGE_CONTENT;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/stopwatch/data/LapCursor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.stopwatch.data;
21 |
22 | import android.database.Cursor;
23 |
24 | import com.philliphsu.clock2.data.BaseItemCursor;
25 | import com.philliphsu.clock2.stopwatch.Lap;
26 |
27 | /**
28 | * Created by Phillip Hsu on 8/8/2016.
29 | */
30 | public class LapCursor extends BaseItemCursor {
31 |
32 | public LapCursor(Cursor cursor) {
33 | super(cursor);
34 | }
35 |
36 | @Override
37 | public Lap getItem() {
38 | Lap lap = new Lap();
39 | lap.setId(getLong(getColumnIndexOrThrow(LapsTable.COLUMN_ID)));
40 | lap.setT1(getLong(getColumnIndexOrThrow(LapsTable.COLUMN_T1)));
41 | lap.setT2(getLong(getColumnIndexOrThrow(LapsTable.COLUMN_T2)));
42 | lap.setPauseTime(getLong(getColumnIndexOrThrow(LapsTable.COLUMN_PAUSE_TIME)));
43 | lap.setTotalTimeText(getString(getColumnIndexOrThrow(LapsTable.COLUMN_TOTAL_TIME_TEXT)));
44 | return lap;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles_stopwatch.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 |
27 |
34 |
37 |
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/util/ParcelableUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.util;
21 |
22 | import android.os.Parcel;
23 | import android.os.Parcelable;
24 |
25 | /**
26 | * Utilities to marshall and unmarshall a {@code Parcelable} to and from a byte array.
27 | */
28 | public final class ParcelableUtil {
29 | public static byte[] marshall(Parcelable parcelable) {
30 | Parcel parcel = Parcel.obtain();
31 | parcelable.writeToParcel(parcel, 0);
32 | byte[] bytes = parcel.marshall();
33 | parcel.recycle();
34 | return bytes;
35 | }
36 |
37 | public static Parcel unmarshall(byte[] bytes) {
38 | Parcel parcel = Parcel.obtain();
39 | parcel.unmarshall(bytes, 0, bytes.length);
40 | parcel.setDataPosition(0); // This is extremely important!
41 | return parcel;
42 | }
43 |
44 | public static T unmarshall(byte[] bytes, Parcelable.Creator creator) {
45 | Parcel parcel = unmarshall(bytes);
46 | T result = creator.createFromParcel(parcel);
47 | parcel.recycle();
48 | return result;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/util/KeyboardUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.util;
21 |
22 | import android.app.Activity;
23 | import android.content.Context;
24 | import android.view.View;
25 | import android.view.inputmethod.InputMethodManager;
26 |
27 | /**
28 | * Created by Phillip Hsu on 6/5/2016.
29 | */
30 | public class KeyboardUtils {
31 |
32 | public static void hideKeyboard(Activity a) {
33 | View view = a.getCurrentFocus();
34 | if (view != null) {
35 | InputMethodManager imm = (InputMethodManager)
36 | a.getSystemService(Context.INPUT_METHOD_SERVICE);
37 | imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
38 | }
39 | }
40 |
41 | /**
42 | * @param c The Context to retrieve the system's input method service
43 | * @param v The currently focused view, which would like to receive soft keyboard input.
44 | */
45 | public static void showKeyboard(Context c, View v) {
46 | InputMethodManager imm = (InputMethodManager) c.getSystemService(Context.INPUT_METHOD_SERVICE);
47 | imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/dialogs/AddLabelDialogController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.dialogs;
21 |
22 | import android.support.v4.app.FragmentManager;
23 | import android.util.Log;
24 |
25 | /**
26 | * Created by Phillip Hsu on 9/6/2016.
27 | */
28 | public final class AddLabelDialogController extends DialogFragmentController {
29 | private static final String TAG = "AddLabelController";
30 |
31 | private final AddLabelDialog.OnLabelSetListener mListener;
32 |
33 | public AddLabelDialogController(FragmentManager fragmentManager, AddLabelDialog.OnLabelSetListener listener) {
34 | super(fragmentManager);
35 | mListener = listener;
36 | }
37 |
38 | public void show(CharSequence initialText, String tag) {
39 | AddLabelDialog dialog = AddLabelDialog.newInstance(mListener, initialText);
40 | show(dialog, tag);
41 | }
42 |
43 | @Override
44 | public void tryRestoreCallback(String tag) {
45 | AddLabelDialog labelDialog = findDialog(tag);
46 | if (labelDialog != null) {
47 | Log.i(TAG, "Restoring add label callback");
48 | labelDialog.setOnLabelSetListener(mListener);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_settings_24dp.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/stopwatch/ui/ChronometerWithMillis.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.philliphsu.clock2.stopwatch.ui;
18 |
19 | import android.annotation.TargetApi;
20 | import android.content.Context;
21 | import android.util.AttributeSet;
22 |
23 | import com.philliphsu.clock2.chronometer.BaseChronometer;
24 |
25 | /**
26 | * Created by Phillip Hsu on 8/9/2016.
27 | *
28 | * A modified version of the framework's Chronometer widget that shows
29 | * up to hundredths of a second.
30 | */
31 | public class ChronometerWithMillis extends BaseChronometer {
32 | private static final String TAG = "ChronometerWithMillis";
33 |
34 | public ChronometerWithMillis(Context context) {
35 | this(context, null, 0);
36 | }
37 |
38 | public ChronometerWithMillis(Context context, AttributeSet attrs) {
39 | this(context, attrs, 0);
40 | }
41 |
42 | public ChronometerWithMillis(Context context, AttributeSet attrs, int defStyleAttr) {
43 | super(context, attrs, defStyleAttr);
44 | init();
45 | }
46 |
47 | @TargetApi(21)
48 | public ChronometerWithMillis(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
49 | super(context, attrs, defStyleAttr, defStyleRes);
50 | init();
51 | }
52 |
53 | private void init() {
54 | setShowCentiseconds(true, false);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/timers/ui/TimersCursorAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.timers.ui;
21 |
22 | import android.view.ViewGroup;
23 |
24 | import com.philliphsu.clock2.timers.data.AsyncTimersTableUpdateHandler;
25 | import com.philliphsu.clock2.list.BaseCursorAdapter;
26 | import com.philliphsu.clock2.list.OnListItemInteractionListener;
27 | import com.philliphsu.clock2.timers.Timer;
28 | import com.philliphsu.clock2.timers.data.TimerCursor;
29 |
30 | /**
31 | * Created by Phillip Hsu on 7/29/2016.
32 | */
33 | public class TimersCursorAdapter extends BaseCursorAdapter {
34 |
35 | private final AsyncTimersTableUpdateHandler mAsyncTimersTableUpdateHandler;
36 |
37 | public TimersCursorAdapter(OnListItemInteractionListener listener,
38 | AsyncTimersTableUpdateHandler asyncTimersTableUpdateHandler) {
39 | super(listener);
40 | mAsyncTimersTableUpdateHandler = asyncTimersTableUpdateHandler;
41 | }
42 |
43 | @Override
44 | protected TimerViewHolder onCreateViewHolder(ViewGroup parent, OnListItemInteractionListener listener, int viewType) {
45 | return new TimerViewHolder(parent, listener, mAsyncTimersTableUpdateHandler);
46 | }
47 |
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/timers/ui/CountdownChronometer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2008 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.philliphsu.clock2.timers.ui;
18 |
19 | import android.annotation.TargetApi;
20 | import android.content.Context;
21 | import android.util.AttributeSet;
22 |
23 | import com.philliphsu.clock2.chronometer.BaseChronometer;
24 |
25 | /**
26 | * Created by Phillip Hsu on 7/25/2016.
27 | *
28 | * A modified version of the framework's Chronometer widget to count down
29 | * towards the base time. The ability to count down was added to Chronometer
30 | * in API 24.
31 | */
32 | public class CountdownChronometer extends BaseChronometer {
33 | private static final String TAG = "CountdownChronometer";
34 |
35 | public CountdownChronometer(Context context) {
36 | this(context, null, 0);
37 | }
38 |
39 | public CountdownChronometer(Context context, AttributeSet attrs) {
40 | this(context, attrs, 0);
41 | }
42 |
43 | public CountdownChronometer(Context context, AttributeSet attrs, int defStyleAttr) {
44 | super(context, attrs, defStyleAttr);
45 | init();
46 | }
47 |
48 | @TargetApi(21)
49 | public CountdownChronometer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
50 | super(context, attrs, defStyleAttr, defStyleRes);
51 | init();
52 | }
53 |
54 | private void init() {
55 | setCountDown(true);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/data/BaseItemCursor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.data;
21 |
22 | import android.database.Cursor;
23 | import android.database.CursorWrapper;
24 | import android.util.Log;
25 |
26 | /**
27 | * Created by Phillip Hsu on 7/29/2016.
28 | */
29 | public abstract class BaseItemCursor extends CursorWrapper {
30 | private static final String TAG = "BaseItemCursor";
31 |
32 | public BaseItemCursor(Cursor cursor) {
33 | super(cursor);
34 | }
35 |
36 | /**
37 | * @return an item instance configured for the current row,
38 | * or null if the current row is invalid
39 | */
40 | public abstract T getItem();
41 |
42 | public long getId() {
43 | if (isBeforeFirst() || isAfterLast()) {
44 | Log.e(TAG, "Failed to retrieve id, cursor out of range");
45 | return -1;
46 | }
47 | return getLong(getColumnIndexOrThrow("_id")); // TODO: Refer to a constant instead of a hardcoded value
48 | }
49 |
50 | /**
51 | * Helper method to determine boolean-valued columns.
52 | * SQLite does not support a BOOLEAN data type.
53 | */
54 | protected boolean isTrue(String columnName) {
55 | return getInt(getColumnIndexOrThrow(columnName)) == 1;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/util/ContentIntentUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.util;
21 |
22 | import android.app.PendingIntent;
23 | import android.content.Context;
24 | import android.content.Intent;
25 | import android.support.annotation.NonNull;
26 |
27 | import com.philliphsu.clock2.MainActivity;
28 | import com.philliphsu.clock2.list.RecyclerViewFragment;
29 |
30 | import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
31 |
32 | /**
33 | * Created by Phillip Hsu on 9/28/2016.
34 | *
35 | * Helper to create content intents for e.g. notifications that should
36 | * open the app, scroll to the specified page, and then scroll to the
37 | * item with the specified stable id.
38 | */
39 | public final class ContentIntentUtils {
40 |
41 | public static PendingIntent create(@NonNull Context context, int targetPage, long stableId) {
42 | Intent intent = new Intent(context, MainActivity.class)
43 | .setAction(RecyclerViewFragment.ACTION_SCROLL_TO_STABLE_ID)
44 | .putExtra(MainActivity.EXTRA_SHOW_PAGE, targetPage)
45 | .putExtra(RecyclerViewFragment.EXTRA_SCROLL_TO_STABLE_ID, stableId);
46 | return PendingIntent.getActivity(context, (int) stableId, intent, FLAG_CANCEL_CURRENT);
47 | }
48 |
49 | private ContentIntentUtils() {}
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_lap.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
26 |
27 |
34 |
35 |
42 |
43 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/values-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 | 24sp
22 |
23 |
24 | 42dp
25 |
26 |
27 |
28 |
29 |
30 |
31 | 55dp
32 | 44dp
33 |
34 | 72dp
35 | 26sp
36 | 20sp
37 |
38 |
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Clock+
2 | Clock+ is a simple alarm clock, timer, and stopwatch app that offers a delightful user experience
3 | for all your timing needs.
4 |
5 | Highlights:
6 |
7 | - **Clean, minimalistic design:** Features Material Design throughout.
8 | - **New time pickers:** Enjoy setting alarms with two new time pickers! Beautifully crafted and
9 | intuitively designed for ease of use.
10 | - **List of timers:** See all of your timers in one scrollable list, and control each one individually.
11 | - **Themes:** Choose between light, dark, and black themes.
12 |
13 | [](https://play.google.com/store/apps/details?id=com.philliphsu.clock2)
16 | [](https://f-droid.org/app/com.philliphsu.clock2)
19 |
20 |
21 |
22 |
23 |
24 | ## License
25 | ```
26 | Copyright 2017 Phillip Hsu
27 |
28 | This file is part of ClockPlus.
29 |
30 | ClockPlus is free software: you can redistribute it and/or modify
31 | it under the terms of the GNU General Public License as published by
32 | the Free Software Foundation, either version 3 of the License, or
33 | (at your option) any later version.
34 |
35 | ClockPlus is distributed in the hope that it will be useful,
36 | but WITHOUT ANY WARRANTY; without even the implied warranty of
37 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 | GNU General Public License for more details.
39 |
40 | You should have received a copy of the GNU General Public License
41 | along with ClockPlus. If not, see .
42 | ```
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/util/TimeTextUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.util;
21 |
22 | import android.text.SpannableString;
23 | import android.text.Spanned;
24 | import android.text.style.RelativeSizeSpan;
25 | import android.widget.TextView;
26 |
27 | /**
28 | * Created by Phillip Hsu on 7/16/2016.
29 | */
30 | public class TimeTextUtils {
31 |
32 | private TimeTextUtils() {}
33 |
34 | private static final RelativeSizeSpan AMPM_SIZE_SPAN = new RelativeSizeSpan(0.5f);
35 |
36 | /**
37 | * Sets the given String on the TextView.
38 | * If the given String contains the "AM" or "PM" label,
39 | * this first applies a size span on the label.
40 | * @param textTime the time String that may contain "AM" or "PM"
41 | * @param textView the TextView to display {@code textTime}
42 | */
43 | public static void setText(String textTime, TextView textView) {
44 | if (textTime.contains("AM") || textTime.contains("PM")) {
45 | SpannableString s = new SpannableString(textTime);
46 | s.setSpan(AMPM_SIZE_SPAN, textTime.indexOf(" "), textTime.length(),
47 | Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
48 | textView.setText(s, TextView.BufferType.SPANNABLE);
49 | } else {
50 | textView.setText(textTime);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
22 | #1C46A0
23 | #143782
24 | #FF5252
25 | #2355BE
26 |
27 | #212121
28 | @android:color/black
29 |
30 | #FF5252
31 | #303030
32 |
33 | #FF5252
34 |
35 | @color/alert_dialog_background_color
36 | @color/alert_dialog_background_color_inverse
37 | @color/alert_dialog_background_color_black
38 |
39 | @color/colorPrimaryFallback
40 | @color/colorPrimaryFallbackInverse
41 | @android:color/black
42 |
43 | #4dffffff
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/dialogs/RingtonePickerDialogController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.dialogs;
21 |
22 | import android.net.Uri;
23 | import android.support.v4.app.FragmentManager;
24 | import android.util.Log;
25 |
26 | import com.philliphsu.clock2.dialogs.DialogFragmentController;
27 | import com.philliphsu.clock2.dialogs.RingtonePickerDialog;
28 |
29 | /**
30 | * Created by Phillip Hsu on 9/20/2016.
31 | */
32 | public class RingtonePickerDialogController extends DialogFragmentController {
33 | private static final String TAG = "RingtonePickerCtrller";
34 |
35 | private final RingtonePickerDialog.OnRingtoneSelectedListener mListener;
36 |
37 | public RingtonePickerDialogController(FragmentManager fragmentManager, RingtonePickerDialog.OnRingtoneSelectedListener l) {
38 | super(fragmentManager);
39 | mListener = l;
40 | }
41 |
42 | public void show(Uri initialUri, String tag) {
43 | RingtonePickerDialog dialog = RingtonePickerDialog.newInstance(mListener, initialUri);
44 | show(dialog, tag);
45 | }
46 |
47 | @Override
48 | public void tryRestoreCallback(String tag) {
49 | RingtonePickerDialog dialog = findDialog(tag);
50 | if (dialog != null) {
51 | Log.i(TAG, "Restoring on ringtone selected callback");
52 | dialog.setOnRingtoneSelectedListener(mListener);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/timers/data/TimerCursor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.timers.data;
21 |
22 | import android.database.Cursor;
23 |
24 | import com.philliphsu.clock2.timers.Timer;
25 | import com.philliphsu.clock2.data.BaseItemCursor;
26 |
27 | /**
28 | * Created by Phillip Hsu on 7/30/2016.
29 | */
30 | public class TimerCursor extends BaseItemCursor {
31 |
32 | public TimerCursor(Cursor cursor) {
33 | super(cursor);
34 | }
35 |
36 | @Override
37 | public Timer getItem() {
38 | if (isBeforeFirst() || isAfterLast())
39 | return null;
40 | int hour = getInt(getColumnIndexOrThrow(TimersTable.COLUMN_HOUR));
41 | int minute = getInt(getColumnIndexOrThrow(TimersTable.COLUMN_MINUTE));
42 | int second = getInt(getColumnIndexOrThrow(TimersTable.COLUMN_SECOND));
43 | String label = getString(getColumnIndexOrThrow(TimersTable.COLUMN_LABEL));
44 | // String group = getString(getColumnIndexOrThrow(COLUMN_GROUP));
45 | Timer t = Timer.create(hour, minute, second, ""/*group*/, label);
46 | t.setId(getLong(getColumnIndexOrThrow(TimersTable.COLUMN_ID)));
47 | t.setEndTime(getLong(getColumnIndexOrThrow(TimersTable.COLUMN_END_TIME)));
48 | t.setPauseTime(getLong(getColumnIndexOrThrow(TimersTable.COLUMN_PAUSE_TIME)));
49 | t.setDuration(getLong(getColumnIndexOrThrow(TimersTable.COLUMN_DURATION)));
50 | return t;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/alarms/misc/AlarmPreferences.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.alarms.misc;
21 |
22 | import android.content.Context;
23 | import android.preference.PreferenceManager;
24 | import android.support.annotation.StringRes;
25 |
26 | import com.philliphsu.clock2.R;
27 |
28 | /**
29 | * Created by Phillip Hsu on 6/3/2016.
30 | *
31 | * Utilities for reading alarm preferences.
32 | */
33 | public final class AlarmPreferences {
34 | private static final String TAG = "AlarmPreferences";
35 |
36 | private AlarmPreferences() {}
37 |
38 | public static int snoozeDuration(Context c) {
39 | return readPreference(c, R.string.key_snooze_duration, 10);
40 | }
41 |
42 | // TODO: Consider renaming to hoursToNotifyInAdvance()
43 | public static int hoursBeforeUpcoming(Context c) {
44 | return readPreference(c, R.string.key_notify_me_of_upcoming_alarms, 2);
45 | }
46 |
47 | public static int minutesToSilenceAfter(Context c) {
48 | return readPreference(c, R.string.key_silence_after, 15);
49 | }
50 |
51 | public static int firstDayOfWeek(Context c) {
52 | return readPreference(c, R.string.key_first_day_of_week, 0 /* Sunday */);
53 | }
54 |
55 | public static int readPreference(Context c, @StringRes int key, int defaultValue) {
56 | String value = PreferenceManager.getDefaultSharedPreferences(c).getString(c.getString(key), null);
57 | return null == value ? defaultValue : Integer.parseInt(value);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/alarm_time_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
27 |
28 |
36 |
37 |
41 |
42 |
47 |
48 |
50 |
55 |
56 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_grid_layout_numpad.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
23 |
27 |
28 |
32 |
33 |
37 |
38 |
42 |
43 |
47 |
48 |
52 |
53 |
57 |
58 |
62 |
63 |
67 |
68 |
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/stopwatch/ui/LapsAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.stopwatch.ui;
21 |
22 | import android.view.ViewGroup;
23 |
24 | import com.philliphsu.clock2.list.BaseCursorAdapter;
25 | import com.philliphsu.clock2.list.OnListItemInteractionListener;
26 | import com.philliphsu.clock2.stopwatch.Lap;
27 | import com.philliphsu.clock2.stopwatch.data.LapCursor;
28 |
29 | /**
30 | * Created by Phillip Hsu on 8/9/2016.
31 | */
32 | public class LapsAdapter extends BaseCursorAdapter {
33 | public static final int VIEW_TYPE_FIRST_LAP = 1; // TOneverDO: 0, that's the default view type
34 |
35 | public LapsAdapter() {
36 | super(null/*OnListItemInteractionListener*/);
37 | }
38 |
39 | @Override
40 | protected LapViewHolder onCreateViewHolder(ViewGroup parent, OnListItemInteractionListener listener, int viewType) {
41 | // TODO: Consider defining a view type for the lone first lap. We should persist this first lap
42 | // when is is created, but this view type will tell us it should not be visible until there
43 | // are at least two laps.
44 | // Or could we return null? Probably not because that will get passed into onBindVH, unless
45 | // you check for null before accessing it.
46 | // RecyclerView.ViewHolder has an internal field that holds viewType for us,
47 | // and can be retrieved by the instance via getItemViewType().
48 | return new LapViewHolder(parent);
49 | }
50 |
51 | @Override
52 | public int getItemViewType(int position) {
53 | return getItemCount() == 1 ? VIEW_TYPE_FIRST_LAP : super.getItemViewType(position);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_grid_layout_numpad_dark.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
23 |
27 |
28 |
32 |
33 |
37 |
38 |
42 |
43 |
47 |
48 |
52 |
53 |
57 |
58 |
62 |
63 |
67 |
68 |
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/dialogs/DialogFragmentController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.dialogs;
21 |
22 | import android.support.annotation.Nullable;
23 | import android.support.v4.app.DialogFragment;
24 | import android.support.v4.app.FragmentManager;
25 | import android.util.Log;
26 |
27 | /**
28 | * Created by Phillip Hsu on 9/6/2016.
29 | */
30 | public abstract class DialogFragmentController {
31 | private static final String TAG = "DialogController";
32 |
33 | private final FragmentManager mFragmentManager;
34 |
35 | // TODO: Rename to onConfigurationChange()?
36 | public abstract void tryRestoreCallback(String tag);
37 |
38 | public DialogFragmentController(FragmentManager fragmentManager) {
39 | mFragmentManager = fragmentManager;
40 | }
41 |
42 | /**
43 | * Shows the dialog with the given tag.
44 | */
45 | protected final void show(T dialog, String tag) {
46 | Log.d(TAG, "Showing dialog " + dialog + "with tag " + tag);
47 | dialog.show(mFragmentManager, tag);
48 | }
49 |
50 | /**
51 | * Tries to find the dialog in our {@code FragmentManager} with the provided tag.
52 | */
53 | @Nullable
54 | @SuppressWarnings("unchecked")
55 | protected final T findDialog(String tag) {
56 | // https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCast
57 | // Typically, we can't cast to a generic type. However, I've written non-generic code that
58 | // blindly casts the result to an arbitrary type that I expect is correct, so this is
59 | // pretty much the same thing.
60 | Log.d(TAG, "Finding dialog by tag " + tag);
61 | return (T) mFragmentManager.findFragmentByTag(tag);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/util/LocalBroadcastHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.util;
21 |
22 | import android.content.BroadcastReceiver;
23 | import android.content.Context;
24 | import android.content.Intent;
25 | import android.content.IntentFilter;
26 | import android.os.Bundle;
27 | import android.support.v4.content.LocalBroadcastManager;
28 |
29 | /**
30 | * Created by Phillip Hsu on 6/14/2016.
31 | */
32 | public final class LocalBroadcastHelper {
33 |
34 | /** Sends a local broadcast using an intent with the action specified */
35 | public static void sendBroadcast(Context context, String action) {
36 | sendBroadcast(context, action, null);
37 | }
38 |
39 | /** Sends a local broadcast using an intent with the action and the extras specified */
40 | public static void sendBroadcast(Context context, String action, Bundle extras) {
41 | Intent intent = new Intent(action);
42 | if (extras != null) {
43 | intent.putExtras(extras);
44 | }
45 | LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
46 | }
47 |
48 | /** Registers a BroadcastReceiver that filters intents by the actions specified */
49 | public static void registerReceiver(Context context, BroadcastReceiver receiver, String... actions) {
50 | IntentFilter filter = new IntentFilter();
51 | for (String action : actions)
52 | filter.addAction(action);
53 | LocalBroadcastManager.getInstance(context).registerReceiver(receiver, filter);
54 | }
55 |
56 | public static void unregisterReceiver(Context context, BroadcastReceiver receiver) {
57 | LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver);
58 | }
59 |
60 | private LocalBroadcastHelper() {}
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_recycler_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
24 |
25 |
36 |
44 |
45 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/androi,android,intellij
3 |
4 | #!! ERROR: androi is undefined. Use list command to see defined gitignore types !!#
5 |
6 | ### Out with .idea dir, out right ###
7 | .idea/
8 |
9 | ### Android ###
10 | # Built application files
11 | *.apk
12 | *.ap_
13 |
14 | # Files for the ART/Dalvik VM
15 | *.dex
16 |
17 | # Java class files
18 | *.class
19 |
20 | # Generated files
21 | bin/
22 | gen/
23 | out/
24 |
25 | # Gradle files
26 | .gradle/
27 | build/
28 |
29 | # Local configuration file (sdk path, etc)
30 | local.properties
31 |
32 | # Proguard folder generated by Eclipse
33 | proguard/
34 |
35 | # Log Files
36 | *.log
37 |
38 | # Android Studio Navigation editor temp files
39 | .navigation/
40 |
41 | # Android Studio captures folder
42 | captures/
43 |
44 | # Intellij
45 | *.iml
46 | .idea/workspace.xml
47 | .idea/libraries
48 |
49 | # Keystore files
50 | *.jks
51 |
52 | ### Android Patch ###
53 | gen-external-apklibs
54 |
55 |
56 | ### Intellij ###
57 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
58 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
59 |
60 | # User-specific stuff:
61 | .idea/workspace.xml
62 | .idea/tasks.xml
63 | .idea/dictionaries
64 | .idea/vcs.xml
65 | .idea/jsLibraryMappings.xml
66 |
67 | # Sensitive or high-churn files:
68 | .idea/dataSources.ids
69 | .idea/dataSources.xml
70 | .idea/dataSources.local.xml
71 | .idea/sqlDataSources.xml
72 | .idea/dynamic.xml
73 | .idea/uiDesigner.xml
74 |
75 | # Gradle:
76 | .idea/gradle.xml
77 | .idea/libraries
78 |
79 | # Mongo Explorer plugin:
80 | .idea/mongoSettings.xml
81 |
82 | ## File-based project format:
83 | *.iws
84 |
85 | ## Plugin-specific files:
86 |
87 | # IntelliJ
88 | /out/
89 |
90 | # mpeltonen/sbt-idea plugin
91 | .idea_modules/
92 |
93 | # JIRA plugin
94 | atlassian-ide-plugin.xml
95 |
96 | # Crashlytics plugin (for Android Studio and IntelliJ)
97 | com_crashlytics_export_strings.xml
98 | crashlytics.properties
99 | crashlytics-build.properties
100 | fabric.properties
101 |
102 | ### Intellij Patch ###
103 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
104 |
105 | # *.iml
106 | # modules.xml
107 | # .idea/misc.xml
108 | # *.ipr
109 |
110 | *.iml
111 | .gradle
112 | /local.properties
113 | /.idea/workspace.xml
114 | /.idea/libraries
115 | .DS_Store
116 | /build
117 | /captures
118 | #
119 | keystore.properties
120 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/data/ClockAppDatabaseHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.data;
21 |
22 | import android.content.Context;
23 | import android.database.sqlite.SQLiteDatabase;
24 | import android.database.sqlite.SQLiteOpenHelper;
25 |
26 | import com.philliphsu.clock2.alarms.data.AlarmsTable;
27 | import com.philliphsu.clock2.stopwatch.data.LapsTable;
28 | import com.philliphsu.clock2.timers.data.TimersTable;
29 |
30 | /**
31 | * Created by Phillip Hsu on 7/30/2016.
32 | */
33 | public class ClockAppDatabaseHelper extends SQLiteOpenHelper {
34 | private static final String TAG = "ClockAppDatabaseHelper";
35 | private static final String DB_NAME = "clock_app.db";
36 | private static final int VERSION_1 = 1;
37 |
38 | private static ClockAppDatabaseHelper sDatabaseHelper;
39 |
40 | public static ClockAppDatabaseHelper getInstance(Context context) {
41 | if (sDatabaseHelper == null)
42 | sDatabaseHelper = new ClockAppDatabaseHelper(context);
43 | return sDatabaseHelper;
44 | }
45 |
46 | /**
47 | * @param context the Context with which the application context will be retrieved
48 | */
49 | private ClockAppDatabaseHelper(Context context) {
50 | super(context.getApplicationContext(), DB_NAME, null, VERSION_1);
51 | }
52 |
53 | @Override
54 | public void onCreate(SQLiteDatabase db) {
55 | AlarmsTable.onCreate(db);
56 | TimersTable.onCreate(db);
57 | LapsTable.onCreate(db);
58 | }
59 |
60 | @Override
61 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
62 | AlarmsTable.onUpgrade(db, oldVersion, newVersion);
63 | TimersTable.onUpgrade(db, oldVersion, newVersion);
64 | LapsTable.onUpgrade(db, oldVersion, newVersion);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/list/BaseViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.list;
21 |
22 | import android.content.Context;
23 | import android.support.annotation.CallSuper;
24 | import android.support.annotation.LayoutRes;
25 | import android.support.v7.widget.RecyclerView;
26 | import android.view.LayoutInflater;
27 | import android.view.View;
28 | import android.view.ViewGroup;
29 |
30 | import butterknife.ButterKnife;
31 |
32 | /**
33 | * Created by Phillip Hsu on 5/31/2016.
34 | */
35 | public abstract class BaseViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
36 |
37 | private final Context mContext;
38 | private final OnListItemInteractionListener mListener;
39 | private T mItem;
40 |
41 | public BaseViewHolder(ViewGroup parent, @LayoutRes int layoutRes, OnListItemInteractionListener listener) {
42 | super(LayoutInflater.from(parent.getContext())
43 | .inflate(layoutRes, parent, false));
44 | ButterKnife.bind(this, itemView);
45 | mContext = parent.getContext();
46 | mListener = listener;
47 | itemView.setOnClickListener(this);
48 | }
49 |
50 | /**
51 | * Call to super must be the first line in the overridden implementation,
52 | * so that the base class can keep a reference to the item parameter.
53 | */
54 | @CallSuper
55 | public void onBind(T item) {
56 | mItem = item;
57 | }
58 |
59 | public final Context getContext() {
60 | return mContext;
61 | }
62 |
63 | public final T getItem() {
64 | return mItem;
65 | }
66 |
67 | @Override
68 | public final void onClick(View v) {
69 | if (mListener != null) {
70 | mListener.onListItemClick(mItem, getAdapterPosition());
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/stopwatch/data/AsyncLapsTableUpdateHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.stopwatch.data;
21 |
22 | import android.content.Context;
23 | import android.content.Intent;
24 |
25 | import com.philliphsu.clock2.data.AsyncDatabaseTableUpdateHandler;
26 | import com.philliphsu.clock2.list.ScrollHandler;
27 | import com.philliphsu.clock2.stopwatch.Lap;
28 | import com.philliphsu.clock2.stopwatch.StopwatchNotificationService;
29 |
30 | /**
31 | * Created by Phillip Hsu on 8/9/2016.
32 | */
33 | public class AsyncLapsTableUpdateHandler extends AsyncDatabaseTableUpdateHandler {
34 |
35 | public AsyncLapsTableUpdateHandler(Context context, ScrollHandler scrollHandler) {
36 | super(context, scrollHandler);
37 | }
38 |
39 | @Override
40 | protected LapsTableManager onCreateTableManager(Context context) {
41 | return new LapsTableManager(context);
42 | }
43 |
44 | @Override
45 | protected void onPostAsyncInsert(Long result, Lap item) {
46 | if (result > 1) {
47 | // Update the notification's title with this lap number
48 | Intent intent = new Intent(getContext(), StopwatchNotificationService.class)
49 | .setAction(StopwatchNotificationService.ACTION_UPDATE_LAP_TITLE)
50 | .putExtra(StopwatchNotificationService.EXTRA_LAP_NUMBER, result.intValue());
51 | getContext().startService(intent);
52 | }
53 | }
54 |
55 | // ===================== DO NOT IMPLEMENT =========================
56 |
57 | @Override
58 | protected void onPostAsyncDelete(Integer result, Lap item) {
59 | // Leave blank.
60 | }
61 |
62 | @Override
63 | protected void onPostAsyncUpdate(Long result, Lap item) {
64 | // Leave blank.
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/dialogs/BaseAlertDialogFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.dialogs;
21 |
22 | import android.app.Dialog;
23 | import android.content.DialogInterface;
24 | import android.os.Bundle;
25 | import android.support.v7.app.AlertDialog;
26 | import android.support.v7.app.AppCompatDialogFragment;
27 |
28 | /**
29 | * Created by Phillip Hsu on 9/3/2016.
30 | *
31 | * Base class for creating AlertDialogs with 'cancel' and 'ok' actions.
32 | */
33 | public abstract class BaseAlertDialogFragment extends AppCompatDialogFragment {
34 |
35 | protected abstract void onOk();
36 |
37 | @Override
38 | public final Dialog onCreateDialog(Bundle savedInstanceState) {
39 | AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
40 | .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
41 | @Override
42 | public void onClick(DialogInterface dialog, int which) {
43 | dismiss();
44 | }
45 | })
46 | .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
47 | @Override
48 | public void onClick(DialogInterface dialog, int which) {
49 | onOk();
50 | }
51 | });
52 | return createFrom(builder);
53 | }
54 |
55 | /**
56 | * Subclasses can override this to make any modifications to the given Builder instance,
57 | * which already has its negative and positive buttons set.
58 | *
59 | * The default implementation creates and returns the {@code AlertDialog} as is.
60 | */
61 | protected AlertDialog createFrom(AlertDialog.Builder builder) {
62 | return builder.create();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/BaseFragment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2;
21 |
22 | import android.os.Bundle;
23 | import android.support.annotation.LayoutRes;
24 | import android.support.annotation.Nullable;
25 | import android.support.v4.app.Fragment;
26 | import android.view.LayoutInflater;
27 | import android.view.View;
28 | import android.view.ViewGroup;
29 |
30 | import butterknife.ButterKnife;
31 |
32 | /**
33 | * Created by Phillip Hsu on 6/30/2016.
34 | */
35 | public abstract class BaseFragment extends Fragment {
36 | /**
37 | * Required empty public constructor. Subclasses do not
38 | * need to implement their own.
39 | */
40 | public BaseFragment() {}
41 |
42 | /**
43 | * @return the layout resource for this Fragment
44 | */
45 | @LayoutRes
46 | protected abstract int contentLayout();
47 |
48 | @Nullable
49 | @Override
50 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
51 | View view = inflater.inflate(contentLayout(), container, false);
52 | ButterKnife.bind(this, view);
53 | return view;
54 | }
55 |
56 | @Override
57 | public void onDestroyView() {
58 | super.onDestroyView();
59 | ButterKnife.unbind(this); // Only for fragments!
60 | }
61 |
62 | /**
63 | * Callback invoked when this Fragment is part of a ViewPager and it has been
64 | * selected, as indicated by {@link android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int)
65 | * onPageSelected(int)}.
66 | */
67 | public void onPageSelected() {
68 | // TODO: Consider making this abstract. The reason it wasn't abstract in the first place
69 | // is not all Fragments in our ViewPager need to do things upon being selected. As such,
70 | // those Fragments' classes would just end up stubbing this implementation.
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/util/DelayedSnackbarHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.util;
21 |
22 | import android.support.design.widget.Snackbar;
23 | import android.view.View;
24 |
25 | /**
26 | * Created by Phillip Hsu on 7/10/2016.
27 | *
28 | * Handler to prepare a Snackbar to be shown only when requested to.
29 | * Useful when the Snackbar is created in an app component that
30 | * is not where it should be shown.
31 | */
32 | public final class DelayedSnackbarHandler {
33 | // TODO: Consider wrapping this in a WeakReference, so that you
34 | // don't prevent this from being GCed if you never call #show().
35 | private static Snackbar snackbar;
36 | private static String message;
37 |
38 | private DelayedSnackbarHandler() {}
39 |
40 | /**
41 | * Saves a reference to the given Snackbar, so that you can
42 | * call {@link #show()} at a later time.
43 | */
44 | public static void prepareSnackbar(Snackbar sb) {
45 | snackbar = sb;
46 | }
47 |
48 | /**
49 | * Shows the Snackbar previously prepared with
50 | * {@link #prepareSnackbar(Snackbar)}
51 | */
52 | public static void show() {
53 | if (snackbar != null) {
54 | snackbar.show();
55 | snackbar = null;
56 | }
57 | }
58 |
59 | /**
60 | * Saves a static reference to the message, so that you can
61 | * call {@link #makeAndShow(View)} at a later time.
62 | */
63 | public static void prepareMessage(String msg) {
64 | message = msg;
65 | }
66 |
67 | /**
68 | * Makes a Snackbar with the message previously prepared with
69 | * {@link #prepareMessage(String)} and shows it.
70 | */
71 | public static void makeAndShow(View snackbarAnchor) {
72 | if (snackbarAnchor != null && message != null) {
73 | Snackbar.make(snackbarAnchor, message, Snackbar.LENGTH_LONG).show();
74 | message = null;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/timers/TimerController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.timers;
21 |
22 | import android.util.Log;
23 |
24 | import com.philliphsu.clock2.timers.data.AsyncTimersTableUpdateHandler;
25 |
26 | /**
27 | * Created by Phillip Hsu on 7/27/2016.
28 | */
29 | public class TimerController {
30 | private static final String TAG = "TimerController";
31 | private final Timer mTimer;
32 | private final AsyncTimersTableUpdateHandler mUpdateHandler;
33 |
34 | public TimerController(Timer timer, AsyncTimersTableUpdateHandler updateHandler) {
35 | mTimer = timer;
36 | mUpdateHandler = updateHandler;
37 | }
38 |
39 | /**
40 | * Start/resume or pause the timer.
41 | */
42 | public void startPause() {
43 | if (mTimer.hasStarted()) {
44 | if (mTimer.isRunning()) {
45 | mTimer.pause();
46 | } else {
47 | mTimer.resume();
48 | }
49 | } else {
50 | mTimer.start();
51 | }
52 | update();
53 | }
54 |
55 | public void stop() {
56 | mTimer.stop();
57 | update();
58 | }
59 |
60 | public void addOneMinute() {
61 | mTimer.addOneMinute();
62 | update();
63 | }
64 |
65 | public void updateLabel(String label) {
66 | Log.d(TAG, "Updating Timer with label = " + label);
67 | Timer newTimer = Timer.create(
68 | mTimer.hour(),
69 | mTimer.minute(),
70 | mTimer.second(),
71 | mTimer.group(),
72 | label);
73 | mTimer.copyMutableFieldsTo(newTimer);
74 | mUpdateHandler.asyncUpdate(mTimer.getId(), newTimer);
75 | // Prompts a reload of the list data, so the list will reflect this modified timer
76 | }
77 |
78 | public void deleteTimer() {
79 | mUpdateHandler.asyncDelete(mTimer);
80 | }
81 |
82 | private void update() {
83 | mUpdateHandler.asyncUpdate(mTimer.getId(), mTimer);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/stopwatch/data/LapsTable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.stopwatch.data;
21 |
22 | import android.database.sqlite.SQLiteDatabase;
23 |
24 | /**
25 | * Created by Phillip Hsu on 8/8/2016.
26 | */
27 | public final class LapsTable {
28 | private LapsTable() {}
29 |
30 | public static final String TABLE_LAPS = "laps";
31 |
32 | public static final String COLUMN_ID = "_id";
33 | public static final String COLUMN_T1 = "elapsed";
34 | public static final String COLUMN_T2 = "total";
35 | public static final String COLUMN_PAUSE_TIME = "pause_time";
36 | public static final String COLUMN_TOTAL_TIME_TEXT = "total_time_text";
37 |
38 | public static final String SORT_ORDER = COLUMN_ID + " DESC";
39 |
40 | public static void onCreate(SQLiteDatabase db) {
41 | db.execSQL("CREATE TABLE " + TABLE_LAPS + " ("
42 | // https://sqlite.org/autoinc.html
43 | // If the AUTOINCREMENT keyword appears after INTEGER PRIMARY KEY, that changes the
44 | // automatic ROWID assignment algorithm to prevent the reuse of ROWIDs over the
45 | // lifetime of the database. In other words, the purpose of AUTOINCREMENT is to
46 | // prevent the reuse of ROWIDs from previously deleted rows.
47 | // If we ever clear the laps of a stopwatch timing, we want the next timing's laps
48 | // to begin again from id = 1. Using AUTOINCREMENT prevents that from happening;
49 | // the laps will begin from the last ID used plus one.
50 | + COLUMN_ID + " INTEGER PRIMARY KEY, "
51 | + COLUMN_T1 + " INTEGER NOT NULL, "
52 | + COLUMN_T2 + " INTEGER NOT NULL, "
53 | + COLUMN_PAUSE_TIME + " INTEGER NOT NULL, "
54 | + COLUMN_TOTAL_TIME_TEXT + " TEXT);");
55 | }
56 |
57 | public static void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
58 | db.execSQL("DROP TABLE IF EXISTS " + TABLE_LAPS);
59 | onCreate(db);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_stopwatch.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
26 |
27 |
31 |
32 |
38 |
39 |
43 |
44 |
45 |
46 |
51 |
52 |
57 |
58 |
61 |
62 |
64 |
65 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/dialogs/SystemTimePickerDialog.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.dialogs;
21 |
22 | import android.app.Dialog;
23 | import android.app.TimePickerDialog;
24 | import android.os.Bundle;
25 | import android.support.annotation.NonNull;
26 | import android.support.v4.app.DialogFragment;
27 | import android.widget.TimePicker;
28 |
29 | import com.philliphsu.bottomsheetpickers.time.BottomSheetTimePickerDialog;
30 |
31 | /**
32 | * Created by Phillip Hsu on 9/28/2016.
33 | */
34 | public class SystemTimePickerDialog extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
35 |
36 | private BottomSheetTimePickerDialog.OnTimeSetListener mListener;
37 | private int mInitialHourOfDay;
38 | private int mInitialMinute;
39 | private boolean mIs24HourMode;
40 |
41 | public static SystemTimePickerDialog newInstance(BottomSheetTimePickerDialog.OnTimeSetListener l,
42 | int hourOfDay, int minute, boolean is24HourMode) {
43 | SystemTimePickerDialog dialog = new SystemTimePickerDialog();
44 | dialog.mListener = l;
45 | dialog.mInitialHourOfDay = hourOfDay;
46 | dialog.mInitialMinute = minute;
47 | dialog.mIs24HourMode = is24HourMode;
48 | return dialog;
49 | }
50 |
51 | public void setOnTimeSetListener(BottomSheetTimePickerDialog.OnTimeSetListener listener) {
52 | mListener = listener;
53 | }
54 |
55 | @NonNull
56 | @Override
57 | public Dialog onCreateDialog(Bundle savedInstanceState) {
58 | return new TimePickerDialog(getActivity(), this, mInitialHourOfDay, mInitialMinute, mIs24HourMode);
59 | }
60 |
61 | @Override
62 | public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
63 | // http://stackoverflow.com/q/19452993/5055032
64 | // BUG PRE-LOLLIPOP! This is also called when the dialog is dismissed, so clicking
65 | // the 'Done' button will end up calling this twice!
66 | if (view.isShown() && mListener != null) {
67 | mListener.onTimeSet(view, hourOfDay, minute);
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/ringtone/playback/RingtoneLoop.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.ringtone.playback;
21 |
22 | import android.content.Context;
23 | import android.media.AudioManager;
24 | import android.media.MediaPlayer;
25 | import android.net.Uri;
26 |
27 | import java.io.IOException;
28 |
29 | /**
30 | * Created by Phillip Hsu on 9/5/2016.
31 | *
32 | * A MediaPlayer configured to play a ringtone in a loop.
33 | */
34 | public final class RingtoneLoop {
35 |
36 | private final Context mContext;
37 | private final AudioManager mAudioManager;
38 | private final Uri mUri;
39 |
40 | private MediaPlayer mMediaPlayer;
41 |
42 | public RingtoneLoop(Context context, Uri uri) {
43 | mContext = context;
44 | mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
45 | mUri = uri;
46 | }
47 |
48 | public void play() {
49 | try {
50 | mMediaPlayer = new MediaPlayer();
51 | mMediaPlayer.setDataSource(mContext, mUri);
52 | if (mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
53 | // "Must call this method before prepare() or prepareAsync() in order
54 | // for the target stream type to become effective thereafter."
55 | mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
56 | mMediaPlayer.setLooping(true);
57 | // There is prepare() and prepareAsync().
58 | // "For files, it is OK to call prepare(), which blocks until
59 | // MediaPlayer is ready for playback."
60 | mMediaPlayer.prepare();
61 | mMediaPlayer.start();
62 | }
63 | } catch (SecurityException | IOException e) {
64 | destroyLocalPlayer();
65 | }
66 | }
67 |
68 | public void stop() {
69 | if (mMediaPlayer != null) {
70 | destroyLocalPlayer();
71 | }
72 | }
73 |
74 | private void destroyLocalPlayer() {
75 | if (mMediaPlayer != null) {
76 | mMediaPlayer.reset();
77 | mMediaPlayer.release();
78 | mMediaPlayer = null;
79 | }
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/settings/SettingsActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.settings;
21 |
22 | import android.app.Activity;
23 | import android.content.Intent;
24 | import android.content.SharedPreferences;
25 | import android.os.Bundle;
26 | import android.preference.PreferenceManager;
27 | import android.view.MenuItem;
28 |
29 | import com.philliphsu.clock2.BaseActivity;
30 | import com.philliphsu.clock2.R;
31 |
32 | /**
33 | * Created by Phillip Hsu on 6/6/2016.
34 | */
35 | public class SettingsActivity extends BaseActivity {
36 | public static final String EXTRA_THEME_CHANGED = "com.philliphsu.clock2.settings.extra.THEME_CHANGED";
37 |
38 | private String mInitialTheme;
39 | private SharedPreferences mPrefs;
40 |
41 | @Override
42 | protected void onCreate(Bundle savedInstanceState) {
43 | super.onCreate(savedInstanceState);
44 | mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
45 | mInitialTheme = getSelectedTheme();
46 | }
47 |
48 | @Override
49 | protected int layoutResId() {
50 | return R.layout.activity_settings;
51 | }
52 |
53 | @Override
54 | protected int menuResId() {
55 | return 0;
56 | }
57 |
58 | @Override
59 | protected boolean isDisplayShowTitleEnabled() {
60 | return true;
61 | }
62 |
63 | @Override
64 | public boolean onOptionsItemSelected(MenuItem item) {
65 | switch (item.getItemId()) {
66 | case android.R.id.home:
67 | setThemeResult(getSelectedTheme());
68 | return false; // Don't capture, proceed as usual
69 | default:
70 | return false;
71 | }
72 | }
73 |
74 | @Override
75 | public void onBackPressed() {
76 | setThemeResult(getSelectedTheme());
77 | super.onBackPressed();
78 | }
79 |
80 | private String getSelectedTheme() {
81 | return mPrefs.getString(getString(R.string.key_theme), "");
82 | }
83 |
84 | private void setThemeResult(String selectedTheme) {
85 | Intent result = new Intent();
86 | result.putExtra(EXTRA_THEME_CHANGED, !selectedTheme.equals(mInitialTheme));
87 | setResult(Activity.RESULT_OK, result);
88 | }
89 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
30 |
31 |
35 |
36 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
60 |
61 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/item_timer.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
29 |
30 |
33 |
34 |
37 |
38 |
42 |
43 |
44 |
48 |
49 |
50 |
55 |
56 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/stopwatch/ui/LapViewHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.stopwatch.ui;
21 |
22 | import android.view.View;
23 | import android.view.ViewGroup;
24 | import android.widget.TextView;
25 |
26 | import com.philliphsu.clock2.list.BaseViewHolder;
27 | import com.philliphsu.clock2.R;
28 | import com.philliphsu.clock2.stopwatch.Lap;
29 |
30 | import butterknife.Bind;
31 |
32 | /**
33 | * Created by Phillip Hsu on 8/8/2016.
34 | */
35 | public class LapViewHolder extends BaseViewHolder {
36 |
37 | @Bind(R.id.lap_number) TextView mLapNumber;
38 | @Bind(R.id.elapsed_time) ChronometerWithMillis mElapsedTime;
39 | @Bind(R.id.total_time) TextView mTotalTime;
40 |
41 | public LapViewHolder(ViewGroup parent) {
42 | super(parent, R.layout.item_lap, null);
43 | }
44 |
45 | @Override
46 | public void onBind(Lap lap) {
47 | super.onBind(lap);
48 | if (getItemViewType() == LapsAdapter.VIEW_TYPE_FIRST_LAP) {
49 | itemView.setVisibility(View.GONE);
50 | } else {
51 | mLapNumber.setText(String.valueOf(lap.getId()));
52 | bindElapsedTime(lap);
53 | bindTotalTime(lap);
54 | }
55 | }
56 |
57 | private void bindElapsedTime(Lap lap) {
58 | // In case we're reusing a chronometer instance that could be running:
59 | // If the lap is not running, this just guarantees the chronometer
60 | // won't tick, regardless of whether it was running.
61 | // If the lap is running, we don't care whether the chronometer is
62 | // also running, because we call start() right after. Stopping it just
63 | // guarantees that, if it was running, we don't deliver another set of
64 | // concurrent messages to its handler.
65 | mElapsedTime.stop();
66 | // We're going to forget about the + sign in front of the text. I think
67 | // the 'Elapsed' header column is sufficient to convey what this timer means.
68 | // (Don't want to figure out a solution)
69 | mElapsedTime.setDuration(lap.elapsed());
70 | if (lap.isRunning()) {
71 | mElapsedTime.start();
72 | }
73 | }
74 |
75 | private void bindTotalTime(Lap lap) {
76 | if (lap.isEnded()) {
77 | mTotalTime.setVisibility(View.VISIBLE);
78 | mTotalTime.setText(lap.totalTimeText());
79 | } else {
80 | mTotalTime.setVisibility(View.INVISIBLE);
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_timer.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
30 |
31 |
34 |
35 |
38 |
39 |
43 |
44 |
45 |
49 |
50 |
51 |
56 |
57 |
63 |
64 |
70 |
71 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/fragment_stopwatch.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
26 |
27 |
30 |
31 |
36 |
37 |
43 |
44 |
48 |
55 |
56 |
57 |
58 |
64 |
65 |
68 |
69 |
71 |
72 |
75 |
76 |
77 |
78 |
79 |
80 |
85 |
86 |
--------------------------------------------------------------------------------
/app/src/main/java/com/philliphsu/clock2/timers/data/TimersTableManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Phillip Hsu
3 | *
4 | * This file is part of ClockPlus.
5 | *
6 | * ClockPlus is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * ClockPlus is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with ClockPlus. If not, see .
18 | */
19 |
20 | package com.philliphsu.clock2.timers.data;
21 |
22 | import android.content.ContentValues;
23 | import android.content.Context;
24 | import android.database.Cursor;
25 | import android.os.SystemClock;
26 | import android.util.Log;
27 |
28 | import com.philliphsu.clock2.timers.Timer;
29 | import com.philliphsu.clock2.data.DatabaseTableManager;
30 |
31 | /**
32 | * Created by Phillip Hsu on 7/30/2016.
33 | */
34 | public class TimersTableManager extends DatabaseTableManager {
35 | public static final String TAG = "TimersTableManager";
36 |
37 | public TimersTableManager(Context context) {
38 | super(context);
39 | }
40 |
41 | @Override
42 | protected String getQuerySortOrder() {
43 | return TimersTable.SORT_ORDER;
44 | }
45 |
46 | @Override
47 | public TimerCursor queryItem(long id) {
48 | return wrapInTimerCursor(super.queryItem(id));
49 | }
50 |
51 | @Override
52 | public TimerCursor queryItems() {
53 | return wrapInTimerCursor(super.queryItems());
54 | }
55 |
56 | public TimerCursor queryStartedTimers() {
57 | String where = TimersTable.COLUMN_END_TIME + " > " + SystemClock.elapsedRealtime()
58 | + " OR " + TimersTable.COLUMN_PAUSE_TIME + " > 0";
59 | return queryItems(where, null);
60 | }
61 |
62 | @Override
63 | protected TimerCursor queryItems(String where, String limit) {
64 | return wrapInTimerCursor(super.queryItems(where, limit));
65 | }
66 |
67 | @Override
68 | protected String getTableName() {
69 | return TimersTable.TABLE_TIMERS;
70 | }
71 |
72 | @Override
73 | protected ContentValues toContentValues(Timer timer) {
74 | ContentValues cv = new ContentValues();
75 | cv.put(TimersTable.COLUMN_HOUR, timer.hour());
76 | cv.put(TimersTable.COLUMN_MINUTE, timer.minute());
77 | cv.put(TimersTable.COLUMN_SECOND, timer.second());
78 | Log.d(TAG, "toContentValues() label = " + timer.label());
79 | cv.put(TimersTable.COLUMN_LABEL, timer.label());
80 | // cv.put(TimersTable.COLUMN_GROUP, timer.group());
81 | Log.d(TAG, "endTime = " + timer.endTime() + ", pauseTime = " + timer.pauseTime());
82 | cv.put(TimersTable.COLUMN_END_TIME, timer.endTime());
83 | cv.put(TimersTable.COLUMN_PAUSE_TIME, timer.pauseTime());
84 | cv.put(TimersTable.COLUMN_DURATION, timer.duration());
85 | return cv;
86 | }
87 |
88 | @Override
89 | protected String getOnContentChangeAction() {
90 | return TimersListCursorLoader.ACTION_CHANGE_CONTENT;
91 | }
92 |
93 | private TimerCursor wrapInTimerCursor(Cursor c) {
94 | return new TimerCursor(c);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------