Add smart wakeup interval

This commit is contained in:
Martin.JM 2024-02-21 16:20:50 +01:00
parent 37b5d0404a
commit 51024f7b5e
14 changed files with 122 additions and 18 deletions

View File

@ -45,7 +45,7 @@ public class GBDaoGenerator {
public static void main(String[] args) throws Exception {
final Schema schema = new Schema(70, MAIN_PACKAGE + ".entities");
final Schema schema = new Schema(71, MAIN_PACKAGE + ".entities");
Entity userAttributes = addUserAttributes(schema);
Entity user = addUserInfo(schema, userAttributes);
@ -835,6 +835,7 @@ public class GBDaoGenerator {
alarm.addIndex(indexUnique);
alarm.addBooleanProperty("enabled").notNull();
alarm.addBooleanProperty("smartWakeup").notNull();
alarm.addIntProperty("smartWakeupInterval");
alarm.addBooleanProperty("snooze").notNull();
alarm.addIntProperty("repetition").notNull().codeBeforeGetter(
"public boolean isRepetitive() { return getRepetition() != ALARM_ONCE; } " +

View File

@ -1,5 +1,5 @@
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, Daniel
Dakhno, Daniele Gobbetti, Dmitry Markin, Lem Dulfo, Taavi Eomäe
Dakhno, Daniele Gobbetti, Dmitry Markin, Lem Dulfo, Taavi Eomäe, Martin.JM
This file is part of Gadgetbridge.
@ -26,6 +26,8 @@ import android.widget.CheckedTextView;
import android.widget.EditText;
import android.widget.TimePicker;
import java.text.NumberFormat;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
@ -50,6 +52,7 @@ public class AlarmDetails extends AbstractGBActivity {
private CheckedTextView cbSunday;
private EditText title;
private EditText description;
private EditText smartWakeupInterval;
private GBDevice device;
@Override
@ -65,6 +68,7 @@ public class AlarmDetails extends AbstractGBActivity {
timePicker = findViewById(R.id.alarm_time_picker);
cbSmartWakeup = findViewById(R.id.alarm_cb_smart_wakeup);
smartWakeupInterval = findViewById(R.id.alarm_cb_smart_wakeup_interval);
cbSnooze = findViewById(R.id.alarm_cb_snooze);
cbMonday = findViewById(R.id.alarm_cb_monday);
cbTuesday = findViewById(R.id.alarm_cb_tuesday);
@ -78,6 +82,7 @@ public class AlarmDetails extends AbstractGBActivity {
cbSmartWakeup.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
((CheckedTextView) v).toggle();
smartWakeupInterval.setEnabled(((CheckedTextView) v).isChecked());
}
});
cbSnooze.setOnClickListener(new View.OnClickListener() {
@ -127,9 +132,26 @@ public class AlarmDetails extends AbstractGBActivity {
boolean smartAlarmForced = forcedSmartWakeup(alarm.getPosition());
cbSmartWakeup.setChecked(alarm.getSmartWakeup() || smartAlarmForced);
int smartAlarmVisibility = supportsSmartWakeup(alarm.getPosition()) ? View.VISIBLE : View.GONE;
boolean smartAlarmVisible = supportsSmartWakeup(alarm.getPosition());
int smartAlarmVisibility = smartAlarmVisible ? View.VISIBLE : View.GONE;
cbSmartWakeup.setVisibility(smartAlarmVisibility);
cbSmartWakeup.setEnabled(!smartAlarmForced);
if (smartAlarmForced) {
cbSmartWakeup.setEnabled(false);
// Force the text to be visible for the "interval" part
// Enabled or not can still be seen in the checkmark
// TODO: I'd like feedback on this
if (GBApplication.isDarkThemeEnabled())
cbSmartWakeup.setTextColor(getResources().getColor(R.color.primarytext_dark));
else
cbSmartWakeup.setTextColor(getResources().getColor(R.color.primarytext_light));
}
if (smartAlarmVisible)
cbSmartWakeup.setText(R.string.alarm_smart_wakeup_interval);
smartWakeupInterval.setVisibility(supportsSmartWakeupInterval(alarm.getPosition()) ? smartAlarmVisibility : View.GONE);
smartWakeupInterval.setEnabled(alarm.getSmartWakeup() || smartAlarmForced);
if (alarm.getSmartWakeupInterval() != null)
smartWakeupInterval.setText(NumberFormat.getInstance().format(alarm.getSmartWakeupInterval()));
cbSnooze.setChecked(alarm.getSnooze());
int snoozeVisibility = supportsSnoozing() ? View.VISIBLE : View.GONE;
@ -163,6 +185,14 @@ public class AlarmDetails extends AbstractGBActivity {
return false;
}
private boolean supportsSmartWakeupInterval(int position) {
if (device != null) {
DeviceCoordinator coordinator = device.getDeviceCoordinator();
return coordinator.supportsSmartWakeupInterval(device, position);
}
return false;
}
/**
* The alarm at this position *must* be a smart alarm
*/
@ -224,6 +254,8 @@ public class AlarmDetails extends AbstractGBActivity {
alarm.setEnabled(true);
}
alarm.setSmartWakeup(supportsSmartWakeup(alarm.getPosition()) && cbSmartWakeup.isChecked());
String interval = smartWakeupInterval.getText().toString();
alarm.setSmartWakeupInterval(interval.equals("") ? null : Integer.parseInt(interval));
alarm.setSnooze(supportsSnoozing() && cbSnooze.isChecked());
int repetitionMask = AlarmUtils.createRepetitionMask(cbMonday.isChecked(), cbTuesday.isChecked(), cbWednesday.isChecked(), cbThursday.isChecked(), cbFriday.isChecked(), cbSaturday.isChecked(), cbSunday.isChecked());
alarm.setRepetition(repetitionMask);

View File

@ -147,7 +147,7 @@ public class ConfigureAlarms extends AbstractGBActivity {
}
private Alarm createDefaultAlarm(@NonNull Device device, @NonNull User user, int position) {
return new Alarm(device.getId(), user.getId(), position, false, false, false, 0, 6, 30, false, null, null);
return new Alarm(device.getId(), user.getId(), position, false, false, null, false, 0, 6, 30, false, null, null);
}
@Override

View File

@ -0,0 +1,38 @@
/* Copyright (C) 2024 Martin.JM
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.database.schema;
import android.database.sqlite.SQLiteDatabase;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.database.DBUpdateScript;
import nodomain.freeyourgadget.gadgetbridge.entities.AlarmDao;
public class GadgetbridgeUpdate_71 implements DBUpdateScript {
@Override
public void upgradeSchema(final SQLiteDatabase db) {
if (!DBHelper.existsColumn(AlarmDao.TABLENAME, AlarmDao.Properties.SmartWakeupInterval.columnName, db)) {
final String statement = "ALTER TABLE " + AlarmDao.TABLENAME + " ADD COLUMN \""
+ AlarmDao.Properties.SmartWakeupInterval.columnName + "\" INTEGER";
db.execSQL(statement);
}
}
@Override
public void downgradeSchema(final SQLiteDatabase db) {
}
}

View File

@ -323,6 +323,11 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
return false;
}
@Override
public boolean supportsSmartWakeupInterval(GBDevice device, int alarmPosition) {
return false;
}
@Override
public boolean forcedSmartWakeup(GBDevice device, int alarmPosition) {
return false;

View File

@ -337,6 +337,12 @@ public interface DeviceCoordinator {
*/
boolean supportsSmartWakeup(GBDevice device, int alarmPosition);
/**
* Returns true if the smart alarm at the specified position supports setting an interval for this device/coordinator
* @param alarmPosition Position of the alarm
*/
boolean supportsSmartWakeupInterval(GBDevice device, int alarmPosition);
/**
* Returns true if the alarm at the specified position *must* be a smart alarm for this device/coordinator
* @param alarmPosition Position of the alarm

View File

@ -116,6 +116,11 @@ public abstract class HuaweiLECoordinator extends AbstractBLEDeviceCoordinator i
return huaweiCoordinator.supportsSmartAlarm(device, position);
}
@Override
public boolean supportsSmartWakeupInterval(GBDevice device, int alarmPosition) {
return supportsSmartWakeup(device, alarmPosition);
}
@Override
public boolean forcedSmartWakeup(GBDevice device, int alarmPosition) {
return huaweiCoordinator.forcedSmartWakeup(device, alarmPosition);

View File

@ -44,6 +44,8 @@ public interface Alarm extends Serializable {
boolean getSmartWakeup();
Integer getSmartWakeupInterval();
boolean getSnooze();
int getRepetition();

View File

@ -733,7 +733,7 @@ public class HuaweiSupportProvider {
title = context.getString(R.string.alarm_smart_wakeup);
description = context.getString(R.string.huawei_alarm_smart_description);
}
return new Alarm(device.getId(), user.getId(), position, false, smartWakeup, false, 0, 6, 30, true, title, description);
return new Alarm(device.getId(), user.getId(), position, false, smartWakeup, null, false, 0, 6, 30, true, title, description);
}
private void getAlarms() {

View File

@ -66,6 +66,7 @@ public class GetEventAlarmList extends Request {
eventAlarm.index + positionOffset,
eventAlarm.status,
false,
null,
false,
eventAlarm.repeat,
eventAlarm.startHour,
@ -86,6 +87,7 @@ public class GetEventAlarmList extends Request {
i + positionOffset,
false,
false,
null,
false,
0,
0,

View File

@ -61,6 +61,7 @@ public class GetSmartAlarmList extends Request {
0,
smartAlarm.status,
true,
null,
false,
smartAlarm.repeat,
smartAlarm.startHour,
@ -79,6 +80,7 @@ public class GetSmartAlarmList extends Request {
0,
false,
true,
null,
false,
0,
0,

View File

@ -51,7 +51,8 @@ public class AlarmUtils {
* @return
*/
public static nodomain.freeyourgadget.gadgetbridge.model.Alarm createSingleShot(int index, boolean smartWakeup, boolean snooze, Calendar calendar) {
return new Alarm(-1, -1, index, true, smartWakeup, snooze, Alarm.ALARM_ONCE, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), false, GBApplication.getContext().getString(R.string.quick_alarm), GBApplication.getContext().getString(R.string.quick_alarm_description));
// TODO: add interval setting?
return new Alarm(-1, -1, index, true, smartWakeup, null, snooze, Alarm.ALARM_ONCE, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), false, GBApplication.getContext().getString(R.string.quick_alarm), GBApplication.getContext().getString(R.string.quick_alarm_description));
}
/**
@ -130,7 +131,7 @@ public class AlarmUtils {
int hour = Integer.parseInt(tokens[4]);
int minute = Integer.parseInt(tokens[5]);
return new Alarm(device.getId(), user.getId(), index, enabled, smartWakeup, false, repetition, hour, minute, false, null, null);
return new Alarm(device.getId(), user.getId(), index, enabled, smartWakeup, null, false, repetition, hour, minute, false, null, null);
}
private static Comparator<Alarm> createComparator() {

View File

@ -23,16 +23,6 @@
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin">
<androidx.appcompat.widget.AppCompatCheckedTextView
android:id="@+id/alarm_cb_smart_wakeup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:drawableStart="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center"
android:text="@string/alarm_smart_wakeup"
android:textAppearance="?android:attr/textAppearanceSmall" />
<androidx.appcompat.widget.AppCompatCheckedTextView
android:id="@+id/alarm_cb_snooze"
android:layout_width="wrap_content"
@ -63,6 +53,24 @@
android:maxLength="256"
android:singleLine="false" />
<androidx.appcompat.widget.AppCompatCheckedTextView
android:id="@+id/alarm_cb_smart_wakeup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:drawableStart="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center"
android:text="@string/alarm_smart_wakeup"
android:textAppearance="?android:attr/textAppearanceSmall" />
<EditText
android:id="@+id/alarm_cb_smart_wakeup_interval"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:hint="@string/alarm_smart_wakeup_interval_default" />
<TimePicker
android:id="@+id/alarm_time_picker"
android:layout_width="match_parent"

View File

@ -779,6 +779,8 @@
<string name="alarm_fri_short">Fri</string>
<string name="alarm_sat_short">Sat</string>
<string name="alarm_smart_wakeup">Smart wakeup</string>
<string name="alarm_smart_wakeup_interval">Smart wakeup, interval (minutes):</string>
<string name="alarm_smart_wakeup_interval_default">Default: 5</string>
<string name="alarm_snooze">Snooze</string>
<string name="user_feedback_miband_set_alarms_failed">There was an error setting the alarms, please try again.</string>
<string name="user_feedback_miband_set_alarms_ok">Alarms sent to device.</string>