- harmonise extra `address` to `device` - the old extra `address` logs a warning but is still supported
- support optional `device` extra for action nodomain.freeyourgadget.gadgetbridge.command.ACTIVITY_SYNC
- support optional `device` extra for action nodomain.freeyourgadget.gadgetbridge.command.DEBUG_SEND_NOTIFICATION
- support optional `device` extra for action nodomain.freeyourgadget.gadgetbridge.command.DEBUG_INCOMING_CALL
- support optional `device` extra for action nodomain.freeyourgadget.gadgetbridge.command.DEBUG_END_CALL
- support ComponentName extras for action nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION
- code review
See Freeyourgadget/website#247 for the documentation update.
EventHandler.onTestNewFunction
- add optional `options` Bundle parameter for receiving arguments
intent nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION
- add optional String extra `address` to specify the MAC address of the target device
- add optional Bundle extra `options` to pass arguments to EventHandler.onTestNewFunction
- construct a synthetic `options` bundle if the `options` extra is missing but there are `options_...` extras
Global setting `Settings / Developer options / Intent API / Allow Debug Command` must be enabled and the device(s) connected for the following examples.
Example to trigger onTestNewFunction for all currently connected devices:
`adb shell am broadcast -p nodomain.freeyourgadget.gadgetbridge -a "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION"`
Example to trigger onTestNewFunction for a specific device:
`adb shell am broadcast -p nodomain.freeyourgadget.gadgetbridge -a "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION" --es address "12:34:56:78:9A:BC" `
Example to trigger onTestNewFunction for a specific device with an option Bundle containing float x=4.2 and integer array y=[1,2,3] extras:
`adb.exe shell am broadcast -p nodomain.freeyourgadget.gadgetbridge -a "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION" --es address "31:31:43:30:40:07" --ef options_x 4.2 --eia options_y 1,2,3`
Extras for some other types can also be specified via command line. See https://developer.android.com/tools/adb#IntentSpec for details.
- (de-)activate via Settings / Developer Options / Experimental metrics UI
- UI currently uses this only for TrainingAcuteLoad, TrainingChronicLoad and RestingMetabolicRate
- Garmin devices are the only ones that actually record these values in the database
- fix: use milliseconds instead of seconds to align with most other samples
- DB upgrade copies existing data from GARMIN_RESTING_METABOLIC_RATE_SAMPLE, GENERIC_TRAINING_LOAD_ACUTE_SAMPLE and GENERIC_TRAINING_LOAD_CHRONIC_SAMPLE to GENERIC_METRIC_SAMPLE
- new data is saved to both the specific table as well as GENERIC_METRIC_SAMPLE
- add GenericMetricSampleProvider with service functions
- add GENERIC_MAXIMUM_OXYGEN_UPTAKE parsing for Garmin
The Androidx annotations are frequently used whereas Jetbrains annotations are infrequently used.
Where possible, use Androidx instead of Jetbrains annotations.
- add initial / final / min stamina handling for session summary
- add fractional cycle and cadence handling for session summary
- add fallback handling for diving summary
- available in device specific settings for supported gadgets
- supports pasting common text formats (e.g. 27°59′18″N 86°55′31″E)
- supports geo: URIs (e.g. geo:27.988333,86.925278,8848)
Experiment to support setting typical wake / sleep times for devices without realtime settings.
Settings / Developer options / Experimental settings
-> enable
Device specific setting / Experimental settings
-> wake time
-> sleep time
-> send
For Garmin ANT devices the extended ANT device number and the filtered serial number result in the same name.
This link between ANT device number and serial number is not always true for non-Garmin devices.
FIT file for testing:
https://github.com/ThomasKuehne/FIT-test-files/blob/main/Activity/2018/Activity_20180324_005_000_Swimming_Fr935_ae9c05519ca8c802f33a8ffd90b15915.fit
``
Error saving specific samplesjava.lang.IllegalArgumentException: Infinity is not a valid double value as per JSON specification. To override this behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.
at com.google.gson.Gson.checkValidFloatingPoint(Gson.java:508)
at com.google.gson.Gson$1.write(Gson.java:470)
at com.google.gson.Gson$1.write(Gson.java:453)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2.write(ReflectiveTypeAdapterFactory.java:251)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:491)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:100)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:64)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2.write(ReflectiveTypeAdapterFactory.java:251)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:491)
at com.google.gson.TypeAdapter.toJsonTree(TypeAdapter.java:181)
at com.google.gson.typeadapters.RuntimeTypeAdapterFactory$1.write(RuntimeTypeAdapterFactory.java:309)
at com.google.gson.TypeAdapter$NullSafeTypeAdapter.write(TypeAdapter.java:304)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:225)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:161)
at com.google.gson.Gson.toJson(Gson.java:943)
at com.google.gson.Gson.toJson(Gson.java:898)
at com.google.gson.Gson.toJson(Gson.java:847)
at com.google.gson.Gson.toJson(Gson.java:824)
at nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryData.toJson(ActivitySummaryData.java:189)
at nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryData.toString(ActivitySummaryData.java:185)
at nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminWorkoutParser.updateSummary(GarminWorkoutParser.java:1080)
at nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitImporter.persistWorkout(FitImporter.java:687)
``
Example pace calculation when speed is exactly 0.0 m/s.
``
Error saving specific samplesjava.lang.IllegalArgumentException: Infinity is not a valid double value as per JSON specification. To override this behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.
at com.google.gson.Gson.checkValidFloatingPoint(Gson.java:508)
at com.google.gson.Gson$1.write(Gson.java:470)
at com.google.gson.Gson$1.write(Gson.java:453)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2.write(ReflectiveTypeAdapterFactory.java:251)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:491)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:100)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:64)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2.write(ReflectiveTypeAdapterFactory.java:251)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:491)
at com.google.gson.TypeAdapter.toJsonTree(TypeAdapter.java:181)
at com.google.gson.typeadapters.RuntimeTypeAdapterFactory$1.write(RuntimeTypeAdapterFactory.java:309)
at com.google.gson.TypeAdapter$NullSafeTypeAdapter.write(TypeAdapter.java:304)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:225)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:161)
at com.google.gson.Gson.toJson(Gson.java:943)
at com.google.gson.Gson.toJson(Gson.java:898)
at com.google.gson.Gson.toJson(Gson.java:847)
at com.google.gson.Gson.toJson(Gson.java:824)
at nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryData.toJson(ActivitySummaryData.java:195)
at nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryData.toString(ActivitySummaryData.java:191)
at nodomain.freeyourgadget.gadgetbridge.devices.garmin.GarminWorkoutParser.updateSummary(GarminWorkoutParser.java:1079)
``
- add fallback sources for HR_AVG, TOTAL_ASCENT, TOTAL_DESCENT, AVG_POWER, BODY_ENERGY_AT_START and BODY_ENERGY_AT_END
- fallback to lap average speed if the lap enhanced average speed isn't available
- ensure that paces/speeds are only rounded by WorkoutValueFormatter and not also by GarminWorkoutParser
- add diving lap summary for apnea
- add scuba tank summary
- fix diving summary gaps when CNS, N2 load or O2 toxicity values are 0