Commit Graph
100 Commits
Author SHA1 Message Date
Thomas Kuehne 3e9c10c0d7 persistence: replace calls to persistForDevice with persistSamples 2026-05-29 01:31:10 +00:00
Thomas Kuehne 1569e05acb Garmin: use harmonised persistSamples methods 2026-05-29 01:31:05 +00:00
Thomas Kuehne 57e493fa86 persistence: add SampleProvider support 2026-05-29 01:30:58 +00:00
Thomas Kuehne e7b86faf7a persistence: add AbstractTimeSample support 2026-05-29 01:20:59 +00:00
Thomas Kuehne 79b5abe85e persistence: add BatteryLevel support 2026-05-29 01:20:37 +00:00
Thomas Kuehne eac3c94a0b persistence: add BaseActivitySummary support 2026-05-29 01:20:14 +00:00
Thomas Kuehne 422047de19 DBHelper: improve JavaDoc 2026-05-29 01:18:34 +00:00
Thomas Kuehne 38e43a32b6 GB.toast: improve JavaDoc 2026-05-28 23:26:38 +00:00
Thomas Kuehne 2f2bb33ddf add missing @Override annotations 2026-05-25 17:24:58 +00:00
Thomas Kuehne dd2b864461 DeviceCoordinator: explicitly specify @Nullable for some returns 2026-05-25 16:01:16 +00:00
Thomas Kuehne 04c7f9e9e6 DeviceCoordinator: explicitly specify @NonNull for arguments 2026-05-25 16:00:49 +00:00
Thomas Kuehne f58130ba8d annotations: prefer androidx.annotation over org.jetbrains.annotations
The Androidx annotations are frequently used whereas Jetbrains annotations are infrequently used.
Where possible, use Androidx instead of Jetbrains annotations.
2026-05-24 18:17:04 +00:00
Thomas Kuehne 5cb0e6b70d Garmin: add more ANT+ gadget IDs 2026-05-24 13:31:49 +00:00
Thomas KuehneandJosé Rebelo 85543cb4c6 igpsport: Rebase to current master 2026-05-13 23:33:24 +02:00
Thomas KuehneandJosé Rebelo 2d36bda559 igpsport: Update for current master rebase 2026-05-13 23:33:24 +02:00
Thomas KuehneandJosé Rebelo 014b180a30 igsport: rebase device code to master ad34fec706 2026-05-13 23:33:24 +02:00
Thomas Kuehne 1b8bdbcf30 WorkoutValueFormatter: replace strings with unit constants declared in ActivitySummaryEntries 2026-05-08 10:35:51 +00:00
Thomas Kuehne 6fab1ef852 Garmin: add dedicated lap summary format for stop watch activities 2026-05-08 09:38:32 +00:00
Thomas Kuehne 0ccbda5e62 Garmin: add test for fallback sport with subsport=0 2026-05-08 09:38:15 +00:00
Thomas Kuehne 86268476bf Garmin: fix AVG_GROUND_CONTACT_TIME_BALANCE for session.getAvgStanceTimeBalance() == 0 2026-05-08 09:37:52 +00:00
Thomas Kuehne 2355e04bbd Garmin: INDOOR_TRACK is a pace activity 2026-05-08 09:37:33 +00:00
Thomas Kuehne bf7b2b2691 Garmin: fix scaling for FitSession's TotalDistance, TotalTimerTime and getStandTime 2026-05-08 09:37:17 +00:00
Thomas Kuehne 3781924351 Garmin: improve workout parsing
- add initial / final / min stamina handling for session summary
- add fractional cycle and cadence handling for session summary
- add fallback handling for diving summary
2026-05-08 09:36:57 +00:00
Thomas Kuehne ad1ac39c4d Garmin: fix null timestamp for FitEvent 2026-05-08 09:36:39 +00:00
Thomas Kuehne 553bfa2ab7 Garmin: add TRAINING_EFFECT_ANAEROBIC fallback handling 2026-05-08 09:36:22 +00:00
Thomas Kuehne fad0fb08d5 Garmin: add more ANT+ gadget IDs 2026-05-08 09:36:04 +00:00
Thomas Kuehne f586f0d52f Garmin: add more FIT messages and field definitions 2026-05-08 09:35:49 +00:00
Thomas Kuehne 7960835407 ActivityPoint: standardise on step length - remove stride handling 2026-05-08 09:35:10 +00:00
Thomas Kuehne e13a219efc Garmin: fix Step Length visualisation 2026-05-08 09:34:50 +00:00
Thomas Kuehne d45bcd4db3 Garmin: add basic Send Waypoint activity
- 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)
2026-05-03 16:11:55 +00:00
Thomas Kuehne c51a0535c9 add EXTRA_OPTIONS support to FwAppInstallerActivity and FileInstallerActivity
If present, the extra of type Bundle is passed on to as `options` argument to DeviceCoordinator.findInstallHandler and EventHandler.onInstallApp.
2026-05-03 16:11:49 +00:00
Thomas Kuehne 72dcc1db2c Garmin: experimental settings for wake / sleep times (#4331)
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
2026-05-02 21:27:55 +00:00
Thomas Kuehne e5bd136385 Garmin: add BUNDLE_EXTRA_INSTALL_TASK_NAME and BUNDLE_EXTRA_INSTALL_BYTES for onInstallApp 2026-05-02 21:27:31 +00:00
Thomas Kuehne c6b13d07d3 Garmin: fix AntGadget.NameGadget for non-Garmin devices
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.
2026-05-01 20:29:28 +00:00
Thomas Kuehne f1ecc71716 Garmin: re-use FitImporter to reduce memory pressure 2026-05-01 10:43:15 +00:00
Thomas Kuehne b8061337e2 Garmin: avoid reading the FIT file twice for auto GPX export 2026-05-01 10:43:10 +00:00
Thomas Kuehne c1d8eb58b9 Garmin: check if GPX export is enabled before generating the export ActivityTrack 2026-05-01 10:43:02 +00:00
Thomas Kuehne c926cadbb8 GPX: export track type 2026-04-30 18:24:01 +00:00
Thomas Kuehne 188d6a8ce9 Garmin: add more FIT messages and fields 2026-04-30 16:56:45 +00:00
Thomas Kuehne c021f615e2 Garmin: add more AntGadget IDs 2026-04-30 16:50:08 +00:00
Thomas Kuehne 76884c5820 Garmin: add more GarminSport codes 2026-04-30 16:49:46 +00:00
Thomas Kuehne 2f072424f6 BLE: add new Bluetooth standard mapping to BleNamesResolver 2026-04-30 16:49:24 +00:00
Thomas Kuehne 5bf6032e75 Garmin: fix laps with speed 0.0 for isPaceActivity=true
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)
``
2026-04-29 18:22:53 +00:00
Thomas Kuehne d999213277 Garmin: fix test failures due to updated NativeFITMessage 2026-04-28 20:05:49 +00:00
Thomas Kuehne 5dbd72f82a Garmin: fix .FIT file summary creation when calculation results in infinity
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)
``
2026-04-26 09:43:51 +00:00
Thomas Kuehne b7bdea78b0 Garmin: fix .FIT file decoding for STRAVA generated files
example files for testing:
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2020/Activity_20201211_002_Cycling_Strava_f0e4ebdad26738b169400fb35fb4b31e.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2022/Activity_20221014_002_Cycling_Strava_456175fbfb40fb170c3aff7ba8769290.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2023/Activity_20230123_002_Cycling_Strava_316afc56c074e3027f91d51c8c491ba5.fit
2026-04-26 09:43:46 +00:00
Thomas Kuehne bf5fde297d Garmin: fix .FIT file decoding for COROS generated files
example files for testing:
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2021/Activity_20210630_001_Running_COROS-PACE-2_9677fe59cdc4684a89189dad1c288bb4.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2021/Activity_20210830_001_Running_COROS-APEX-46mm_11bb1b1e1c61bfed8bdd8ff0623391c5.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2023/Activity_20230626_043_Windsurfing_COROS-VERTIX_ff49a5a499ee66c4229038c547e32c8e.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2023/Activity_20230630_043_Windsurfing_COROS-VERTIX-2_d41760a0235a9b8037273b7651c4f532.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2023/Activity_20230821_043_Windsurfing_COROS-APEX-Pro_6d750dd6c2190bc6a0d89c441e708656.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2023/Activity_20231117_001_Running_COROS-PACE-3_badb78c49b7aef7b5e112f28da83604c.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2024/Activity_20240107_017_Hiking_COROS-APEX-2-Pro_0a7a9b95b09df66ffa48ea97bb27209d.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2025/Activity_20251119_002_008_Cycling_Mountain_COROS-DURA_4e04b1f1bad2e57127e9a2affd4cd7d0.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2025/Activity_20250722_001_Running_COROS-PACE-Pro_13d6d1e2a93a1ed855a068145ae80110.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2025/Activity_20250801_001_003_Running_Trail_COROS-Wearables_99901ef8f988756d25ac3afbbb1222eb.fit
2026-04-26 09:43:39 +00:00
Thomas Kuehne b8e1337b49 Garmin: fix Failed to get string resource by name for numeric device ID
FIT file for testing:
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2026/Activity_20260118_002_009_Cycling_Downhill_EdgeMtb_1da0225a17673383029e744960ba3a56.fit
2026-04-26 09:25:34 +00:00
Thomas Kuehne 16b29bd09d Garmin: fix .FIT file decoding for older Garmin devices
example files for testing:
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2016/Activity_20161021_005_000_Swimming_Fr230_77e3563673fbc2b19a60a78b6f5f6f49.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2018/Activity_20180113_000_015_Elliptical_Fenix3Hr_51b4891a23b94b634b93c666e1417fea.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2024/Activity_20240708_015_014_Rowing_Indoor-Rowing_Fr735xt_e358d81585941c7ac1dc747987d711bc.fit
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2025/Activity_20250128_011_000_Walking_Fr55_872d00f0d3b2a4251c86255dad477d93.fit
2026-04-26 07:58:35 +00:00
Thomas Kuehne e01599a9e3 Garmin: enhance activity summaries
- 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
2026-04-25 00:16:16 +00:00
Thomas Kuehne 0372f855c9 Garmin: code cleanup in FitImporter / GarminWorkoutParser 2026-04-24 20:54:30 +00:00
Thomas Kuehne 748e388bdd Garmin: extend AntGadget support for dual ANT+ / Bluetooth devices 2026-04-24 20:54:19 +00:00
Thomas Kuehne 0e010c0ce0 Garmin: decode more FIT messages and fields 2026-04-24 20:53:53 +00:00
Thomas Kuehne f0c5748eaa Garmin: add more sport / subsport codes 2026-04-24 20:50:55 +00:00
Thomas Kuehne fc36a2e073 Garmin: fix UINT64Z BaseType from 0x8F (UINT64) to 0x90 2026-04-24 20:49:38 +00:00
Thomas KuehneandJosé Rebelo 9b9e6dd34a Garmin: add more ANT+ IDs and fallback to formatted ANT ID before serial number 2026-04-19 14:19:52 +02:00
Thomas Kuehne cd09de5ebb Garmin: use more human friendly names for ANT+ gear in activity summaries 2026-04-16 10:19:41 +00:00
Thomas Kuehne 426a88f020 Garmin: enhance activity summaries
- prioritise names: workout name > session sports profile > sport name
- gracefully fallback from Enhanced Respiration to plain Respiration
- gracefully fallback from Enhanced Speed to plain Speed
- add gear info showing last battery reading of connected devices
- add altitude min/max/avg
- add user heart rate (min/max/resting)
- add workout feel (0 - 100%)
- add device battery state (initial / final)
- add ebike battery state (initial / final)
- add more recovery, work, energy statistics
- diving: add SAC (Surface Air Consumption)
- diving: add water density with fallback to water type
- diving: ignore disabled gases
2026-04-14 05:00:58 +00:00
Thomas Kuehne 1b8c103610 Garmin: streamline adding data to activity summary
ActivitySummaryData already checks if the value is `null`.
Unless forcing a display or performing calculations, there is no need to also check for `null` values in GarminWorkoutParser.
2026-04-13 19:25:42 +00:00
Thomas Kuehne 35d2d31093 Garmin: map more Session, Lap, Monitoring, Record and EcgSummary fit fields 2026-04-13 19:24:59 +00:00
Thomas Kuehne 45318a3c84 fix: ActivityPoint.getN2Load 2026-04-13 19:24:18 +00:00
Thomas Kuehne f9d9ecce09 Garmin: extract and store metrics (#5708, #5709, #5710)
This extracts the following metrics and stores them in a new GenericMetricSample / GENERIC_METRIC_SAMPLE table:
- endurance score
- functional threshold power
- hill endurance
- hill score
- hill strength
- MET max VO2
- running lactate threshold power
- training readiness

Visualisation and charts aren't part of this PR.
2026-04-12 17:13:10 +00:00
Thomas KuehneandJosé Rebelo bde914fad2 Garmin: extend support for non-GPS activities
- chart elevation even if the activity has no GPS recording (e.g. treadmill and floor climbing)
- added distance chart
- added stride chart
- added step length chart
- added body energy chart - 24/7 energy level
- added stamina chart - activity specific endurance capacity
- added N2 load (Nitrogen) chart for diving
- added CNS toxicity (Central Nervous System) chart for diving
- added oxygen toxicity summary for diving
- added surface interval summary for diving
- adjusted dive summary layout
2026-04-11 01:43:45 +02:00
Thomas KuehneandJosé Rebelo 5b2f982509 Garmin: fix identification of relevant FitDiveSummary session record
The logic depended on the sequence of records and not their actual content.
2026-04-11 01:43:45 +02:00
Thomas KuehneandJosé Rebelo 4da08f7968 Garmin: ignore Null Island for ActivitySummaryData.setHasGps
Some indoor tracks, like Edge1030's Cycling / Virtual Activity, record all points with fake Null Island (0°N 0°E) position.
2026-04-11 01:43:45 +02:00
Thomas KuehneandJosé Rebelo 9344940260 extend support for non-GPS activities
This enhances the general GB code _without_ the device specific adjustments required to actually display values:
- chart elevation even if the activity has no GPS recording (e.g. treadmill and floor climbing)
- added distance chart
- added stride chart
- added step length chart
- added body energy chart - 24/7 energy level
- added stamina chart - activity specific endurance capacity
- added N2 load (Nitrogen) chart for diving
- added CNS toxicity (Central Nervous System) chart for diving
- added oxygen toxicity summary for diving
- added surface interval summary for diving
2026-04-11 01:43:45 +02:00
Thomas KuehneandJosé Rebelo 536ad17c4d Garmin HRM 600: Initial support
Based on feedback in #5633
2026-04-11 00:03:36 +02:00
Thomas Kuehne 9edeec2a57 Garmin: fix start time handling for stopwatch (#4507) and prepare for multi sessions in one file (#5862. #5860)
Prioritise the session specific start time over the file creation time.
2026-04-10 17:33:39 +00:00
Thomas KuehneandJosé Rebelo fc6dcc793b Garmin: export FIT laps as GPX track segments 2026-04-07 00:14:44 +02:00
Thomas KuehneandJosé Rebelo 68aa74bc39 GPX: fix redirecting URLs in xsi:schemaLocation
Some XML parsers don't support HTTP redirection for schemaLocation so encode the actual URLs.
2026-04-07 00:14:06 +02:00
Thomas Kuehne d65b1fd853 DeviceCoordinator.findInstallHandler: add Bundle parameter
EventHandler.onInstallApp already has a Bundle parameter for passing options to install handlers.
This prepares the infrastructure for PR #5923.
2026-04-03 20:57:30 +00:00
Thomas KuehneandJosé Rebelo 05b229c833 Gpx: export track name
Some Garmin devices only read gpx/trk/name and ignore gpx/metadata/name.
Export the same name to both.
2026-04-03 18:53:54 +02:00
Thomas Kuehne de1c74f223 fix: always use GPSCoordinate.hasAltitude to check if altitude value is valid
Altitude is a floating point value that supports NaN so it is too easy to use the wrong comparison operation.
2026-04-03 16:40:55 +00:00
Thomas Kuehne 3cd5ae847b Garmin: add support for installing .FIT location and segment files
The uploaded location file creates new waypoints on the device by updating the LCTNS.FIT / Location.fit file.
2026-03-30 01:26:02 +02:00
Thomas KuehneandJosé Rebelo 6fcb07ea98 GPX: add support for importing older GPX version 1.0 files
Also takes care of slightly quirky GPX 1.1 files that contain extra spaces, XML comments or use floats instead of integers for cadence and heart rate.
2026-03-25 23:17:42 +01:00
076a85d762 Garmin: fix CobsCoDec.encode
Co-authored-by: José Rebelo <joserebelo@outlook.com>
2026-03-21 00:16:35 +01:00
Thomas KuehneandJosé Rebelo 165cd803a0 Garmin: fuzzy test for CobsCoDec 2026-03-21 00:16:35 +01:00
Thomas KuehneandJosé Rebelo fde8563b4a backport upstream BouncyCastle fixes
aligned with bcgit/bc-java@7b094ad188
2026-03-17 00:00:31 +01:00
Thomas KuehneandJosé Rebelo e6bdac82d4 Garmin: GpxRouteFileConverter add depth, temperature, speed and tests 2026-03-16 23:31:39 +01:00
Thomas Kuehne d985e0ab7e strings: clean-up British vs US spellings and GPS 2026-03-14 19:39:59 +01:00
Thomas Kuehne 4ebb31f255 add missing @Override annotations 2026-03-14 11:02:58 +01:00
Thomas KuehneandJosé Rebelo cb5634dcfe Garmin: add Recovery Heart Rate and Rate of Perceived Exertion to activity summary
RPE / rate of perceived exertion
https://support.garmin.com/en-US/?faq=8nISJXqSZVAI3Td4IWRqsA

recovery heart rate
https://support.garmin.com/en-US/?faq=3HTTUrSoRF51m8vGUtMhY9
2026-03-11 22:13:16 +01:00
Thomas KuehneandJosé Rebelo 07b1e593b3 nQuant: backport Gadgetbridge fixups 2026-03-09 22:28:03 +01:00
Thomas KuehneandJosé Rebelo c8da8b4717 nQuant: refresh to mcychan/nQuant.android@12822f15c9 2026-03-09 22:28:03 +01:00
Thomas KuehneandJosé Rebelo 26cf09d700 Garmin: move test FIT data into files 2026-03-09 22:15:35 +01:00
Thomas Kuehne 98fe5caaa4 Garmin: FIT file type 57 is SPORTS_BACKUP 2026-03-08 08:30:55 +01:00
Thomas KuehneandJosé Rebelo 7dc6044138 BleNamesResolver: add more standard services and characteristics 2026-03-07 21:28:35 +01:00
Thomas KuehneandJosé Rebelo bacc85bcb8 Garmin: add sleep disruption FIT fields 2026-02-28 18:36:59 +01:00
Thomas Kuehne 9a9ba5b30c Garmin: add more FIT sport types
example FIT files for testing:

STREET_RUN (sport:1, subsport:2)
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2025/Activity_20250410_Running_Nike_1794463148babf53fb33b260a19a91fe.fit

VIRTUAL_CYCLING (sport:2, subsport:58)
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2026/Activity_20260110_Cycling_Mywhoosh_cbefa61fcd6d7c0f9916e07d119fbceb.fit

INDOOR_ROWING (sport:4, subsport:14)
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2017/Activity_20170518_FitnessEquipment_VivoActiveHr_94dbffeb8be296bb39027edc041a2963.fit

STOPWATCH (sport:52, subsport:0)
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2023/Activity_20221129_52_Fenix5Plus_43621059f6fc664f8f3b577e2f1d8695.fit

CCR_DIVING (sport:53, subsport:63)
https://github.com/ThomasKuehne/FIT-test-files/tree/main/Activity/2017/Activity_20230816_Diving_Descent_d602dcb95b6701d1921e9d6a26594ebe.fit
2026-02-28 17:39:51 +01:00
Thomas Kuehne 17a4338984 Garmin: add more FILETYPEs 2026-02-21 12:55:02 +01:00
Thomas KuehneandJosé Rebelo 84dab742b1 GPXExporter: fix generated XML and export depth and ambient temperature 2025-11-22 19:54:21 +01:00
Thomas Kuehne a62eed5cae WriteAction: use more compact logging format 2025-10-25 20:23:06 +02:00
Thomas KuehneandJosé Rebelo b09ed96de6 GxpParser: add support for version 2 of Garmin's TrackPointExtension 2025-10-24 21:36:06 +02:00
Thomas KuehneandJosé Rebelo 4d9afdbfb8 GxpParser: forward description, depth and temperature to ActivityPoint 2025-10-24 21:34:23 +02:00
Thomas KuehneandJosé Rebelo 01ff179071 ble: adjust TransactionBuilder's MTU logging 2025-10-14 23:27:36 +02:00
Thomas Kuehne 4355236799 ble: prepare evenrealities for online chunking PR
Adjust G1DeviceSupport and G1SideManager to limit the impact of #5218
2025-10-14 21:09:13 +02:00
Thomas KuehneandJosé Rebelo c8f6b8cfaf GxpParser: extraction more waypoint and trackpoint data (#5465) 2025-10-12 23:50:37 +02:00
Thomas KuehneandJosé Rebelo 3fd826cd79 fix: unescaped' and " as well as white space sequences in string.xml
https://developer.android.com/guide/topics/resources/string-resource#FormattingAndStyling
Escape single quotes (') and double quote (").
Unescaped characters are removed by the Android tool chain.

A string contained completely in quotes
   <string>"a b   c"</string>
triggers special white space preserving handling (a b   c) instead of the normal white space collapse (a b c).
2025-10-11 23:41:55 +02:00
Thomas KuehneandJosé Rebelo a28ed02534 Garmin: extend FIT file parsing 14 - COURSE_POINT 32 / type 4
based on https://github.com/muktihari/fit
2025-10-10 01:01:44 +02:00
Thomas KuehneandJosé Rebelo 89485c76ad GpxTrackPoint: fix NullpointerException in toString 2025-10-10 00:54:50 +02:00