1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-28 21:06:50 +01:00

Lefun: Implement settings

This commit is contained in:
Yukai Li 2020-10-05 14:20:20 -06:00 committed by Gitea
parent c8d3d6df20
commit 6974a86b87
21 changed files with 1023 additions and 3 deletions

View File

@ -45,4 +45,11 @@ public class DeviceSettingsPreferenceConst {
public static final String PREF_LONGSIT_SWITCH = "pref_longsit_switch"; public static final String PREF_LONGSIT_SWITCH = "pref_longsit_switch";
public static final String PREF_LONGSIT_SWITCH_NOSHED = "screen_longsit_noshed"; public static final String PREF_LONGSIT_SWITCH_NOSHED = "screen_longsit_noshed";
public static final String PREF_DO_NOT_DISTURB_NOAUTO = "do_not_disturb_no_auto"; public static final String PREF_DO_NOT_DISTURB_NOAUTO = "do_not_disturb_no_auto";
public static final String PREF_FIND_PHONE_ENABLED = "prefs_find_phone";
public static final String PREF_ANTILOST_ENABLED = "pref_antilost_enabled";
public static final String PREF_HYDRATION_SWITCH = "pref_hydration_switch";
public static final String PREF_HYDRATION_PERIOD = "pref_hydration_period";
public static final String PREF_AMPM_ENABLED = "pref_ampm_enabled";
public static final String PREF_LEFUN_INTERFACE_LANGUAGE = "pref_lefun_interface_language";
} }

View File

@ -41,6 +41,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference;
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreferenceFragment; import nodomain.freeyourgadget.gadgetbridge.util.XTimePreferenceFragment;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_ALTITUDE_CALIBRATE; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_ALTITUDE_CALIBRATE;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_AMPM_ENABLED;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_ANTILOST_ENABLED;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BUTTON_1_FUNCTION; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BUTTON_1_FUNCTION;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BUTTON_2_FUNCTION; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BUTTON_2_FUNCTION;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BUTTON_3_FUNCTION; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_BUTTON_3_FUNCTION;
@ -48,10 +50,14 @@ import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.Dev
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DATEFORMAT; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DATEFORMAT;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DISCONNECTNOTIF_NOSHED; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DISCONNECTNOTIF_NOSHED;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DO_NOT_DISTURB_NOAUTO; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DO_NOT_DISTURB_NOAUTO;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_FIND_PHONE_ENABLED;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HYBRID_HR_DRAW_WIDGET_CIRCLES; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HYBRID_HR_DRAW_WIDGET_CIRCLES;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HYBRID_HR_FORCE_WHITE_COLOR; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HYBRID_HR_FORCE_WHITE_COLOR;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HYBRID_HR_SAVE_RAW_ACTIVITY_FILES; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HYBRID_HR_SAVE_RAW_ACTIVITY_FILES;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HYDRATION_PERIOD;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_HYDRATION_SWITCH;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_LANGUAGE; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_LANGUAGE;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_LEFUN_INTERFACE_LANGUAGE;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_LIFTWRIST_NOSHED; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_LIFTWRIST_NOSHED;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_LONGSIT_PERIOD; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_LONGSIT_PERIOD;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_LONGSIT_SWITCH; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_LONGSIT_SWITCH;
@ -351,6 +357,12 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat {
addPreferenceHandlerFor(PREF_LONGSIT_PERIOD); addPreferenceHandlerFor(PREF_LONGSIT_PERIOD);
addPreferenceHandlerFor(PREF_LONGSIT_SWITCH); addPreferenceHandlerFor(PREF_LONGSIT_SWITCH);
addPreferenceHandlerFor(PREF_DO_NOT_DISTURB_NOAUTO); addPreferenceHandlerFor(PREF_DO_NOT_DISTURB_NOAUTO);
addPreferenceHandlerFor(PREF_FIND_PHONE_ENABLED);
addPreferenceHandlerFor(PREF_ANTILOST_ENABLED);
addPreferenceHandlerFor(PREF_HYDRATION_SWITCH);
addPreferenceHandlerFor(PREF_HYDRATION_PERIOD);
addPreferenceHandlerFor(PREF_AMPM_ENABLED);
addPreferenceHandlerFor(PREF_LEFUN_INTERFACE_LANGUAGE);
addPreferenceHandlerFor(PREF_HYBRID_HR_DRAW_WIDGET_CIRCLES); addPreferenceHandlerFor(PREF_HYBRID_HR_DRAW_WIDGET_CIRCLES);
addPreferenceHandlerFor(PREF_HYBRID_HR_FORCE_WHITE_COLOR); addPreferenceHandlerFor(PREF_HYBRID_HR_FORCE_WHITE_COLOR);

View File

@ -26,6 +26,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
@ -154,4 +155,16 @@ public class LefunDeviceCoordinator extends AbstractDeviceCoordinator {
public boolean supportsFindDevice() { public boolean supportsFindDevice() {
return true; return true;
} }
@Override
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[]{
R.xml.devicesettings_liftwrist_display_noshed,
R.xml.devicesettings_ampm,
R.xml.devicesettings_antilost,
R.xml.devicesettings_longsit,
R.xml.devicesettings_hydration_reminder,
R.xml.devicesettings_lefun_interface_language,
};
}
} }

View File

@ -50,7 +50,7 @@ public class SettingsCommand extends BaseCommand {
} }
public void setOption1(byte option1) { public void setOption1(byte option1) {
if (option1 < 0 || option1 > 24) if (option1 != (byte)0xff && (option1 < 0 || option1 > 24))
throw new IllegalArgumentException("option1 must be between 0 and 24 inclusive"); throw new IllegalArgumentException("option1 must be between 0 and 24 inclusive");
this.option1 = option1; this.option1 = option1;
} }
@ -60,7 +60,7 @@ public class SettingsCommand extends BaseCommand {
} }
public void setAmPmIndicator(byte amPmIndicator) { public void setAmPmIndicator(byte amPmIndicator) {
if (amPmIndicator != AM_PM_12_HOUR && amPmIndicator != AM_PM_24_HOUR) if (amPmIndicator != (byte)0xff && (amPmIndicator != AM_PM_12_HOUR && amPmIndicator != AM_PM_24_HOUR))
throw new IllegalArgumentException("Indicator must be 12 or 24 hours"); throw new IllegalArgumentException("Indicator must be 12 or 24 hours");
this.amPmIndicator = amPmIndicator; this.amPmIndicator = amPmIndicator;
} }
@ -70,7 +70,7 @@ public class SettingsCommand extends BaseCommand {
} }
public void setMeasurementUnit(byte measurementUnit) { public void setMeasurementUnit(byte measurementUnit) {
if (measurementUnit != MEASUREMENT_UNIT_METRIC && measurementUnit != MEASUREMENT_UNIT_IMPERIAL) if (measurementUnit != (byte)0xff && (measurementUnit != MEASUREMENT_UNIT_METRIC && measurementUnit != MEASUREMENT_UNIT_IMPERIAL))
throw new IllegalArgumentException(("Unit must be metric or imperial")); throw new IllegalArgumentException(("Unit must be metric or imperial"));
this.measurementUnit = measurementUnit; this.measurementUnit = measurementUnit;
} }

View File

@ -21,6 +21,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun;
import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.widget.Toast; import android.widget.Toast;
@ -40,22 +41,28 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import de.greenrobot.dao.query.Query; import de.greenrobot.dao.query.Query;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants; import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.FeaturesCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.FindPhoneCommand; import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.FindPhoneCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.GetActivityDataCommand; import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.GetActivityDataCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.GetPpgDataCommand; import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.GetPpgDataCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.GetSleepDataCommand; import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.GetSleepDataCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.GetStepsDataCommand; import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.GetStepsDataCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.PpgResultCommand; import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.PpgResultCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.SettingsCommand;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.LefunActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.LefunActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.LefunActivitySampleDao; import nodomain.freeyourgadget.gadgetbridge.entities.LefunActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.entities.LefunBiometricSample; import nodomain.freeyourgadget.gadgetbridge.entities.LefunBiometricSample;
import nodomain.freeyourgadget.gadgetbridge.entities.LefunSleepSample; import nodomain.freeyourgadget.gadgetbridge.entities.LefunSleepSample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec; import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
@ -73,16 +80,27 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateA
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.FindDeviceRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.FindDeviceRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetActivityDataRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetActivityDataRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetBatteryLevelRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetBatteryLevelRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetEnabledFeaturesRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetFirmwareInfoRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetFirmwareInfoRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetGeneralSettingsRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetHydrationReminderIntervalRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetPpgDataRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetPpgDataRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetSedentaryReminderIntervalRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetSleepDataRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.GetSleepDataRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.Request; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.Request;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SendCallNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SendCallNotificationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SendNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SendNotificationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SetAlarmRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SetAlarmRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SetEnabledFeaturesRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SetGeneralSettingsRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SetHydrationReminderIntervalRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SetLanguageRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SetProfileRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SetSedentaryReminderIntervalRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SetTimeRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.SetTimeRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.StartPpgRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.StartPpgRequest;
import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { public class LefunDeviceSupport extends AbstractBTLEDeviceSupport {
private static final Logger LOG = LoggerFactory.getLogger(LefunDeviceSupport.class); private static final Logger LOG = LoggerFactory.getLogger(LefunDeviceSupport.class);
@ -122,6 +140,9 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport {
GetBatteryLevelRequest batReq = new GetBatteryLevelRequest(this, builder); GetBatteryLevelRequest batReq = new GetBatteryLevelRequest(this, builder);
batReq.perform(); batReq.perform();
inProgressRequests.add(batReq); inProgressRequests.add(batReq);
sendUnitsSetting(builder);
sendUserProfile(builder);
} catch (IOException e) { } catch (IOException e) {
GB.toast(getContext(), "Failed to initialize Lefun device", Toast.LENGTH_SHORT, GB.toast(getContext(), "Failed to initialize Lefun device", Toast.LENGTH_SHORT,
GB.ERROR, e); GB.ERROR, e);
@ -357,12 +378,266 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport {
@Override @Override
public void onSendConfiguration(String config) { public void onSendConfiguration(String config) {
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
switch (config) {
case DeviceSettingsPreferenceConst.PREF_AMPM_ENABLED: {
boolean enabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_AMPM_ENABLED, false);
byte ampmValue = enabled ? SettingsCommand.AM_PM_12_HOUR : SettingsCommand.AM_PM_24_HOUR;
sendGeneralSettings(null, ampmValue, (byte) 0xff);
break;
}
case DeviceSettingsPreferenceConst.PREF_LIFTWRIST_NOSHED: {
boolean enabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_LIFTWRIST_NOSHED, true);
FeaturesCommand features = getCurrentEnabledFeatures();
features.setFeature(FeaturesCommand.FEATURE_RAISE_TO_WAKE, enabled);
sendEnabledFeaturesSetting(features);
break;
}
case DeviceSettingsPreferenceConst.PREF_ANTILOST_ENABLED: {
boolean enabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_ANTILOST_ENABLED, true);
FeaturesCommand features = getCurrentEnabledFeatures();
features.setFeature(FeaturesCommand.FEATURE_ANTI_LOST, enabled);
sendEnabledFeaturesSetting(features);
break;
}
case DeviceSettingsPreferenceConst.PREF_LONGSIT_SWITCH: {
boolean enabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_LONGSIT_SWITCH, false);
FeaturesCommand features = getCurrentEnabledFeatures();
features.setFeature(FeaturesCommand.FEATURE_SEDENTARY_REMINDER, enabled);
sendEnabledFeaturesSetting(features);
break;
}
case DeviceSettingsPreferenceConst.PREF_LONGSIT_PERIOD: {
String periodStr = prefs.getString(DeviceSettingsPreferenceConst.PREF_LONGSIT_PERIOD, "60");
try {
int period = Integer.parseInt(periodStr);
sendSedentaryReminderIntervalSetting(period);
} catch (NumberFormatException e) {
GB.toast(getContext(), "Invalid sedentary reminder interval value", Toast.LENGTH_SHORT,
GB.ERROR, e);
}
break;
}
case DeviceSettingsPreferenceConst.PREF_HYDRATION_SWITCH: {
boolean enabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_HYDRATION_SWITCH, false);
FeaturesCommand features = getCurrentEnabledFeatures();
features.setFeature(FeaturesCommand.FEATURE_HYDRATION_REMINDER, enabled);
sendEnabledFeaturesSetting(features);
break;
}
case DeviceSettingsPreferenceConst.PREF_HYDRATION_PERIOD: {
String periodStr = prefs.getString(DeviceSettingsPreferenceConst.PREF_HYDRATION_PERIOD, "60");
try {
int period = Integer.parseInt(periodStr);
sendHydrationReminderIntervalSetting(period);
} catch (NumberFormatException e) {
GB.toast(getContext(), "Invalid sedentary reminder interval value", Toast.LENGTH_SHORT,
GB.ERROR, e);
}
break;
}
case SettingsActivity.PREF_MEASUREMENT_SYSTEM: {
sendUnitsSetting(null);
break;
}
case DeviceSettingsPreferenceConst.PREF_LEFUN_INTERFACE_LANGUAGE: {
String value = prefs.getString(DeviceSettingsPreferenceConst.PREF_LEFUN_INTERFACE_LANGUAGE, "0");
int intValue = Integer.parseInt(value);
sendLanguageSetting((byte) intValue);
break;
}
}
}
private void sendUnitsSetting(TransactionBuilder builder) {
Prefs prefs = GBApplication.getPrefs();
String units = prefs.getString(SettingsActivity.PREF_MEASUREMENT_SYSTEM,
getContext().getString(R.string.p_unit_metric));
byte lefunUnits;
if (getContext().getString(R.string.p_unit_metric).equals(units)) {
lefunUnits = SettingsCommand.MEASUREMENT_UNIT_METRIC;
} else {
lefunUnits = SettingsCommand.MEASUREMENT_UNIT_IMPERIAL;
}
sendGeneralSettings(builder, (byte) 0xff, lefunUnits);
}
private FeaturesCommand getCurrentEnabledFeatures() {
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
boolean raiseToWakeEnabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_LIFTWRIST_NOSHED, true);
boolean antilostEnabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_ANTILOST_ENABLED, true);
boolean sedentaryEnabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_LONGSIT_SWITCH, false);
boolean hydrationEnabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_HYDRATION_SWITCH, false);
FeaturesCommand cmd = new FeaturesCommand();
cmd.setFeature(FeaturesCommand.FEATURE_RAISE_TO_WAKE, raiseToWakeEnabled);
cmd.setFeature(FeaturesCommand.FEATURE_ANTI_LOST, antilostEnabled);
cmd.setFeature(FeaturesCommand.FEATURE_SEDENTARY_REMINDER, sedentaryEnabled);
cmd.setFeature(FeaturesCommand.FEATURE_HYDRATION_REMINDER, hydrationEnabled);
return cmd;
}
private void sendGeneralSettings(TransactionBuilder builder, byte amPm, byte units) {
boolean givenBuilder = builder != null;
try {
if (!givenBuilder)
builder = performInitialized(SetGeneralSettingsRequest.class.getSimpleName());
SetGeneralSettingsRequest request = new SetGeneralSettingsRequest(this, builder);
request.setAmPm(amPm);
request.setUnits(units);
request.perform();
inProgressRequests.add(request);
if (!givenBuilder)
performConnected(builder.getTransaction());
} catch (IOException e) {
GB.toast(getContext(), "Failed to set settings", Toast.LENGTH_SHORT,
GB.ERROR, e);
}
}
private void sendUserProfile(TransactionBuilder builder) {
boolean givenBuilder = builder != null;
try {
if (!givenBuilder)
builder = performInitialized(SetProfileRequest.class.getSimpleName());
SetProfileRequest request = new SetProfileRequest(this, builder);
ActivityUser user = new ActivityUser();
request.setUser(user);
request.perform();
inProgressRequests.add(request);
if (!givenBuilder)
performConnected(builder.getTransaction());
} catch (IOException e) {
GB.toast(getContext(), "Failed to send profile", Toast.LENGTH_SHORT,
GB.ERROR, e);
}
}
private void sendEnabledFeaturesSetting(FeaturesCommand cmd) {
try {
TransactionBuilder builder = performInitialized(SetEnabledFeaturesRequest.class.getSimpleName());
SetEnabledFeaturesRequest request = new SetEnabledFeaturesRequest(this, builder);
request.setCmd(cmd);
request.perform();
inProgressRequests.add(request);
performConnected(builder.getTransaction());
} catch (IOException e) {
GB.toast(getContext(), "Failed to set enabled features", Toast.LENGTH_SHORT,
GB.ERROR, e);
}
}
private void sendSedentaryReminderIntervalSetting(int period) {
try {
TransactionBuilder builder = performInitialized(SetSedentaryReminderIntervalRequest.class.getSimpleName());
SetSedentaryReminderIntervalRequest request = new SetSedentaryReminderIntervalRequest(this, builder);
request.setInterval(period);
request.perform();
inProgressRequests.add(request);
performConnected(builder.getTransaction());
} catch (IOException e) {
GB.toast(getContext(), "Failed to set sedentary reminder interval", Toast.LENGTH_SHORT,
GB.ERROR, e);
}
}
private void sendHydrationReminderIntervalSetting(int period) {
try {
TransactionBuilder builder = performInitialized(SetHydrationReminderIntervalRequest.class.getSimpleName());
SetHydrationReminderIntervalRequest request = new SetHydrationReminderIntervalRequest(this, builder);
request.setInterval(period);
request.perform();
inProgressRequests.add(request);
performConnected(builder.getTransaction());
} catch (IOException e) {
GB.toast(getContext(), "Failed to set hydration reminder interval", Toast.LENGTH_SHORT,
GB.ERROR, e);
}
}
private void sendLanguageSetting(byte language) {
try {
TransactionBuilder builder = performInitialized(SetLanguageRequest.class.getSimpleName());
SetLanguageRequest request = new SetLanguageRequest(this, builder);
request.setLanguage(language);
request.perform();
inProgressRequests.add(request);
performConnected(builder.getTransaction());
} catch (IOException e) {
GB.toast(getContext(), "Failed to set language", Toast.LENGTH_SHORT,
GB.ERROR, e);
}
}
public void receiveGeneralSettings(int amPm, int units) {
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
boolean ampmEnabled = amPm == SettingsCommand.AM_PM_12_HOUR;
prefs.edit()
.putBoolean(DeviceSettingsPreferenceConst.PREF_AMPM_ENABLED, ampmEnabled)
.apply();
}
public void receiveEnabledFeaturesSetting(FeaturesCommand cmd) {
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
prefs.edit()
.putBoolean(DeviceSettingsPreferenceConst.PREF_LIFTWRIST_NOSHED,
cmd.getFeature(FeaturesCommand.FEATURE_RAISE_TO_WAKE))
.putBoolean(DeviceSettingsPreferenceConst.PREF_LONGSIT_SWITCH,
cmd.getFeature(FeaturesCommand.FEATURE_SEDENTARY_REMINDER))
.putBoolean(DeviceSettingsPreferenceConst.PREF_HYDRATION_SWITCH,
cmd.getFeature(FeaturesCommand.FEATURE_HYDRATION_REMINDER))
.putBoolean(DeviceSettingsPreferenceConst.PREF_ANTILOST_ENABLED,
cmd.getFeature(FeaturesCommand.FEATURE_ANTI_LOST))
.apply();
}
public void receiveSedentaryReminderIntervalSetting(int period) {
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
prefs.edit()
.putString(DeviceSettingsPreferenceConst.PREF_LONGSIT_PERIOD, String.valueOf(period))
.apply();
}
public void receiveHydrationReminderIntervalSetting(int period) {
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress());
prefs.edit()
.putString(DeviceSettingsPreferenceConst.PREF_HYDRATION_PERIOD, String.valueOf(period))
.apply();
} }
@Override @Override
public void onReadConfiguration(String config) { public void onReadConfiguration(String config) {
// Just going to read all the settings
try {
TransactionBuilder builder = performInitialized("Read settings");
GetGeneralSettingsRequest getGeneralSettingsRequest
= new GetGeneralSettingsRequest(this, builder);
getGeneralSettingsRequest.perform();
inProgressRequests.add(getGeneralSettingsRequest);
GetEnabledFeaturesRequest getEnabledFeaturesRequest
= new GetEnabledFeaturesRequest(this, builder);
getEnabledFeaturesRequest.perform();
inProgressRequests.add(getEnabledFeaturesRequest);
GetSedentaryReminderIntervalRequest getSedentaryReminderIntervalRequest
= new GetSedentaryReminderIntervalRequest(this, builder);
getSedentaryReminderIntervalRequest.perform();
inProgressRequests.add(getSedentaryReminderIntervalRequest);
GetHydrationReminderIntervalRequest getHydrationReminderIntervalRequest
= new GetHydrationReminderIntervalRequest(this, builder);
getHydrationReminderIntervalRequest.perform();
inProgressRequests.add(getHydrationReminderIntervalRequest);
performConnected(builder.getTransaction());
} catch (IOException e) {
GB.toast(getContext(), "Failed to retrieve settings", Toast.LENGTH_SHORT,
GB.ERROR, e);
}
} }
@Override @Override
@ -489,6 +764,7 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport {
public void completeInitialization() { public void completeInitialization() {
gbDevice.setState(GBDevice.State.INITIALIZED); gbDevice.setState(GBDevice.State.INITIALIZED);
gbDevice.sendDeviceUpdateIntent(getContext()); gbDevice.sendDeviceUpdateIntent(getContext());
onReadConfiguration("");
} }
private int dateToTimestamp(byte year, byte month, byte day, byte hour, byte minute, byte second) { private int dateToTimestamp(byte year, byte month, byte day, byte hour, byte minute, byte second) {

View File

@ -0,0 +1,57 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
Copyright (C) 2020 Yukai Li
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.BaseCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.FeaturesCommand;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
public class GetEnabledFeaturesRequest extends Request {
public GetEnabledFeaturesRequest(LefunDeviceSupport support, TransactionBuilder builder) {
super(support, builder);
}
@Override
public byte[] createRequest() {
FeaturesCommand cmd = new FeaturesCommand();
cmd.setOp(BaseCommand.OP_GET);
return cmd.serialize();
}
@Override
public void handleResponse(byte[] data) {
FeaturesCommand cmd = new FeaturesCommand();
cmd.deserialize(data);
if (cmd.getOp() == BaseCommand.OP_GET) {
getSupport().receiveEnabledFeaturesSetting(cmd);
}
operationStatus = OperationStatus.FINISHED;
}
@Override
public int getCommandId() {
return LefunConstants.CMD_FEATURES;
}
}

View File

@ -0,0 +1,60 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
Copyright (C) 2020 Yukai Li
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.BaseCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.SettingsCommand;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
public class GetGeneralSettingsRequest extends Request {
public GetGeneralSettingsRequest(LefunDeviceSupport support, TransactionBuilder builder) {
super(support, builder);
}
@Override
public byte[] createRequest() {
SettingsCommand cmd = new SettingsCommand();
cmd.setOp(BaseCommand.OP_GET);
return cmd.serialize();
}
@Override
public void handleResponse(byte[] data) {
SettingsCommand cmd = new SettingsCommand();
cmd.deserialize(data);
if (cmd.getOp() == BaseCommand.OP_GET) {
getSupport().receiveGeneralSettings(
(int) cmd.getAmPmIndicator() & 0xff,
(int) cmd.getMeasurementUnit() & 0xff
);
}
operationStatus = OperationStatus.FINISHED;
}
@Override
public int getCommandId() {
return LefunConstants.CMD_SETTINGS;
}
}

View File

@ -0,0 +1,57 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
Copyright (C) 2020 Yukai Li
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.BaseCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.HydrationReminderIntervalCommand;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
public class GetHydrationReminderIntervalRequest extends Request {
public GetHydrationReminderIntervalRequest(LefunDeviceSupport support, TransactionBuilder builder) {
super(support, builder);
}
@Override
public byte[] createRequest() {
HydrationReminderIntervalCommand cmd = new HydrationReminderIntervalCommand();
cmd.setOp(BaseCommand.OP_GET);
return cmd.serialize();
}
@Override
public void handleResponse(byte[] data) {
HydrationReminderIntervalCommand cmd = new HydrationReminderIntervalCommand();
cmd.deserialize(data);
if (cmd.getOp() == BaseCommand.OP_GET) {
getSupport().receiveHydrationReminderIntervalSetting((int) cmd.getHydrationReminderInterval() & 0xff);
}
operationStatus = OperationStatus.FINISHED;
}
@Override
public int getCommandId() {
return LefunConstants.CMD_HYDRATION_REMINDER_INTERVAL;
}
}

View File

@ -0,0 +1,57 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
Copyright (C) 2020 Yukai Li
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.BaseCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.SedentaryReminderIntervalCommand;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
public class GetSedentaryReminderIntervalRequest extends Request {
public GetSedentaryReminderIntervalRequest(LefunDeviceSupport support, TransactionBuilder builder) {
super(support, builder);
}
@Override
public byte[] createRequest() {
SedentaryReminderIntervalCommand cmd = new SedentaryReminderIntervalCommand();
cmd.setOp(BaseCommand.OP_GET);
return cmd.serialize();
}
@Override
public void handleResponse(byte[] data) {
SedentaryReminderIntervalCommand cmd = new SedentaryReminderIntervalCommand();
cmd.deserialize(data);
if (cmd.getOp() == BaseCommand.OP_GET) {
getSupport().receiveSedentaryReminderIntervalSetting((int) cmd.getSedentaryReminderInterval() & 0xff);
}
operationStatus = OperationStatus.FINISHED;
}
@Override
public int getCommandId() {
return LefunConstants.CMD_SEDENTARY_REMINDER_INTERVAL;
}
}

View File

@ -0,0 +1,63 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
Copyright (C) 2020 Yukai Li
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.BaseCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.FeaturesCommand;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
public class SetEnabledFeaturesRequest extends Request {
private FeaturesCommand cmd;
public SetEnabledFeaturesRequest(LefunDeviceSupport support, TransactionBuilder builder) {
super(support, builder);
}
public FeaturesCommand getCmd() {
return cmd;
}
public void setCmd(FeaturesCommand cmd) {
this.cmd = cmd;
}
@Override
public byte[] createRequest() {
cmd.setOp(BaseCommand.OP_SET);
return cmd.serialize();
}
@Override
public void handleResponse(byte[] data) {
FeaturesCommand cmd = new FeaturesCommand();
cmd.deserialize(data);
if (cmd.getOp() == BaseCommand.OP_SET && !cmd.isSetSuccess())
reportFailure("Could not set enabled features");
operationStatus = OperationStatus.FINISHED;
}
@Override
public int getCommandId() {
return LefunConstants.CMD_FEATURES;
}
}

View File

@ -0,0 +1,78 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
Copyright (C) 2020 Yukai Li
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.BaseCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.SettingsCommand;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
public class SetGeneralSettingsRequest extends Request {
private byte amPm;
private byte units;
public SetGeneralSettingsRequest(LefunDeviceSupport support, TransactionBuilder builder) {
super(support, builder);
}
public byte getAmPm() {
return amPm;
}
public void setAmPm(byte amPm) {
this.amPm = amPm;
}
public byte getUnits() {
return units;
}
public void setUnits(byte units) {
this.units = units;
}
@Override
public byte[] createRequest() {
SettingsCommand cmd = new SettingsCommand();
cmd.setOp(BaseCommand.OP_SET);
cmd.setOption1((byte) 0xff); // Don't set
cmd.setAmPmIndicator(amPm);
cmd.setMeasurementUnit(units);
return cmd.serialize();
}
@Override
public void handleResponse(byte[] data) {
SettingsCommand cmd = new SettingsCommand();
cmd.deserialize(data);
if (cmd.getOp() == BaseCommand.OP_SET && !cmd.isSetSuccess())
reportFailure("Could not set settings");
operationStatus = OperationStatus.FINISHED;
}
@Override
public int getCommandId() {
return LefunConstants.CMD_SETTINGS;
}
}

View File

@ -0,0 +1,67 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
Copyright (C) 2020 Yukai Li
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.BaseCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.HydrationReminderIntervalCommand;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
public class SetHydrationReminderIntervalRequest extends Request {
private int interval;
public SetHydrationReminderIntervalRequest(LefunDeviceSupport support, TransactionBuilder builder) {
super(support, builder);
}
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
@Override
public byte[] createRequest() {
HydrationReminderIntervalCommand cmd = new HydrationReminderIntervalCommand();
cmd.setOp(BaseCommand.OP_SET);
cmd.setHydrationReminderInterval((byte) interval);
return cmd.serialize();
}
@Override
public void handleResponse(byte[] data) {
HydrationReminderIntervalCommand cmd = new HydrationReminderIntervalCommand();
cmd.deserialize(data);
if (cmd.getOp() == BaseCommand.OP_SET && !cmd.isSetSuccess())
reportFailure("Could not set hydration reminder interval");
operationStatus = OperationStatus.FINISHED;
}
@Override
public int getCommandId() {
return LefunConstants.CMD_HYDRATION_REMINDER_INTERVAL;
}
}

View File

@ -0,0 +1,65 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
Copyright (C) 2020 Yukai Li
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.SetLanguageCommand;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
public class SetLanguageRequest extends Request {
private byte language;
public SetLanguageRequest(LefunDeviceSupport support, TransactionBuilder builder) {
super(support, builder);
}
public byte getLanguage() {
return language;
}
public void setLanguage(byte language) {
this.language = language;
}
@Override
public byte[] createRequest() {
SetLanguageCommand cmd = new SetLanguageCommand();
cmd.setLanguage(language);
return cmd.serialize();
}
@Override
public void handleResponse(byte[] data) {
SetLanguageCommand cmd = new SetLanguageCommand();
cmd.deserialize(data);
if (!cmd.isSetSuccess())
reportFailure("Could not set language");
operationStatus = OperationStatus.FINISHED;
}
@Override
public int getCommandId() {
return LefunConstants.CMD_LANGUAGE;
}
}

View File

@ -0,0 +1,74 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
Copyright (C) 2020 Yukai Li
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.BaseCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.ProfileCommand;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
public class SetProfileRequest extends Request {
private ActivityUser user;
public SetProfileRequest(LefunDeviceSupport support, TransactionBuilder builder) {
super(support, builder);
}
public ActivityUser getUser() {
return user;
}
public void setUser(ActivityUser user) {
this.user = user;
}
@Override
public byte[] createRequest() {
ProfileCommand cmd = new ProfileCommand();
cmd.setOp(BaseCommand.OP_SET);
// No "other" option available, only male or female
cmd.setGender(user.getGender() == ActivityUser.GENDER_FEMALE
? ProfileCommand.GENDER_FEMALE
: ProfileCommand.GENDER_MALE);
cmd.setHeight((byte) user.getHeightCm());
cmd.setWeight((byte) user.getWeightKg());
cmd.setAge((byte) user.getAge());
return cmd.serialize();
}
@Override
public void handleResponse(byte[] data) {
ProfileCommand cmd = new ProfileCommand();
cmd.deserialize(data);
if (cmd.getOp() == BaseCommand.OP_SET && !cmd.isSetSuccess())
reportFailure("Could not set profile");
operationStatus = OperationStatus.FINISHED;
}
@Override
public int getCommandId() {
return LefunConstants.CMD_PROFILE;
}
}

View File

@ -0,0 +1,67 @@
/* Copyright (C) 2016-2020 Andreas Shimokawa, Carsten Pfeiffer, Daniele
Gobbetti
Copyright (C) 2020 Yukai Li
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 <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.BaseCommand;
import nodomain.freeyourgadget.gadgetbridge.devices.lefun.commands.SedentaryReminderIntervalCommand;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus;
public class SetSedentaryReminderIntervalRequest extends Request {
private int interval;
public SetSedentaryReminderIntervalRequest(LefunDeviceSupport support, TransactionBuilder builder) {
super(support, builder);
}
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
@Override
public byte[] createRequest() {
SedentaryReminderIntervalCommand cmd = new SedentaryReminderIntervalCommand();
cmd.setOp(BaseCommand.OP_SET);
cmd.setSedentaryReminderInterval((byte) interval);
return cmd.serialize();
}
@Override
public void handleResponse(byte[] data) {
SedentaryReminderIntervalCommand cmd = new SedentaryReminderIntervalCommand();
cmd.deserialize(data);
if (cmd.getOp() == BaseCommand.OP_SET && !cmd.isSetSuccess())
reportFailure("Could not set sedentary reminder interval");
operationStatus = OperationStatus.FINISHED;
}
@Override
public int getCommandId() {
return LefunConstants.CMD_SEDENTARY_REMINDER_INTERVAL;
}
}

View File

@ -976,4 +976,14 @@
<item>7days</item> <item>7days</item>
<item>30days</item> <item>30days</item>
</string-array> </string-array>
<string-array name="lefun_interface_language_names">
<item>@string/english</item>
<item>@string/simplified_chinese</item>
</string-array>
<string-array name="lefun_interface_language_values">
<item>0</item>
<item>1</item>
</string-array>
</resources> </resources>

View File

@ -547,6 +547,14 @@
<string name="bip_prefs_shotcuts_summary">Choose the shortcuts on the band screen</string> <string name="bip_prefs_shotcuts_summary">Choose the shortcuts on the band screen</string>
<string name="pref_title_force_white_color_scheme">Force black on white color scheme</string> <string name="pref_title_force_white_color_scheme">Force black on white color scheme</string>
<string name="pref_summary_force_white_color_scheme">Useful if you your watch has dark hands</string> <string name="pref_summary_force_white_color_scheme">Useful if you your watch has dark hands</string>
<string name="lefun_prefs_hydration_reminder_title">Hydration reminder</string>
<string name="lefun_prefs_hydration_reminder_summary">The band will vibrate to remind you to drink water</string>
<string name="lefun_prefs_hydration_reminder_interval_title">Hydration reminder interval (in minutes)</string>
<string name="lefun_prefs_antilost_title">Anti-loss</string>
<string name="lefun_prefs_antilost_summary">The band will vibrate if the Bluetooth connection to your phone disconnects</string>
<string name="lefun_prefs_ampm_title">12-hour display</string>
<string name="lefun_prefs_ampm_summary">Display time in 12-hour format with AM/PM indicator</string>
<string name="lefun_interface_language_title">Interface language</string>
<string name="automatic">Automatic</string> <string name="automatic">Automatic</string>
<string name="simplified_chinese">Simplified Chinese</string> <string name="simplified_chinese">Simplified Chinese</string>
<string name="traditional_chinese">Traditional Chinese</string> <string name="traditional_chinese">Traditional Chinese</string>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:defaultValue="false"
android:icon="@drawable/ic_access_time"
android:key="pref_ampm_enabled"
android:summary="@string/lefun_prefs_ampm_summary"
android:title="@string/lefun_prefs_ampm_title" />
</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:defaultValue="true"
android:icon="@drawable/ic_vibration"
android:key="pref_antilost_enabled"
android:summary="@string/lefun_prefs_antilost_summary"
android:title="@string/lefun_prefs_antilost_title" />
</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen
android:icon="@drawable/ic_settings"
android:key="screen_hydration_reminder"
android:persistent="false"
android:summary="@string/lefun_prefs_hydration_reminder_summary"
android:title="@string/lefun_prefs_hydration_reminder_title">
<SwitchPreference
android:defaultValue="false"
android:key="pref_hydration_switch"
android:title="@string/lefun_prefs_hydration_reminder_title" />
<EditTextPreference
android:defaultValue="60"
android:key="pref_hydration_period"
android:summary="@string/lefun_prefs_hydration_reminder_summary"
android:title="@string/lefun_prefs_hydration_reminder_interval_title"/>
</PreferenceScreen>
</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:defaultValue="0"
android:entries="@array/lefun_interface_language_names"
android:entryValues="@array/lefun_interface_language_values"
android:icon="@drawable/ic_language"
android:key="pref_lefun_interface_language"
android:summary="%s"
android:title="@string/lefun_interface_language_title" />
</androidx.preference.PreferenceScreen>