Commit Graph
15340 Commits
Author SHA1 Message Date
José Rebelo 86d42bab78 GPX: Fix parsing of timestamps without timezone
Although these are non-conforming, there are a lot of gpx files online
that do not contain a timezone and fail to be parsed.
2026-05-23 18:42:49 +01:00
José Rebelo 89e495c6b1 Garmin: Fix empty caller when unknown 2026-05-23 15:15:58 +01:00
José Rebelo 43eb4bc4b7 CMF Buds 2a: Fix touch options 2026-05-23 13:34:25 +01:00
José Rebelo f5b5416ca8 Garmin: Show toast on waypoint upload complete 2026-05-22 22:54:11 +01:00
José Rebelo f317b744eb Set up logging before database 2026-05-22 21:54:41 +01:00
José Rebelo e011d794e6 Only load map on focused workout details fragment (#5456)
Should reduce memory pressure when loading very large workouts, which
would be loading the maps in parallel in adjacent pages.
2026-05-21 20:06:41 +01:00
Martin BraunandJosé Rebelo b8a85e03ea Add Third Party Alarm Intent API: Set and Dismiss alarms for your device from any app (#6088)
Adds the capability to set and dismiss alarms from third party apps through an Intent API, fixes #5553

**This PR was co-authored by ChatGPT and José Rebelo (passively):**

- Scaffold for the core component `DeviceAlarmReceiver` was taken from José's `DeviceSettingsReceiver`
- The core implementation was written by me by hand, ChatGPT was used to review and find potential issues and bugs
- The `DeviceAlarmReceiverTest` unit tests were written by ChatGPT and reviewed by me

**About these changes:**

- Adds a new developer settings entry for the device that the user needs to enable, so other apps can use the Intent API for such device
- Supports app blacklisting as it is done in the `DeviceSettingsReceiver`
- `ConfigureAlarms.addMissingAlarms()` was migrated to `DBHelper.fillMissingAlarms()` to provide this abstraction globally
- `AlarmReceiver` was migrated to `SunriseSunsetAlarmReceiver` to avoid ambiguity with this feature; the formerly called `AlarmReceiver` was related to setting calendar events based on the sunrise/sunset via an Intent API
- The API is registered in the `DeviceCommunicationService`
- The `ConfigureAlarms` activity updates its list after setting alarms from a third party app by broadcasting `ACTION_SAVE_ALARMS`
- It is possible to set alarms of a device that is offline, it should sync when the device connects next time, unless it downloads the alarms from the device when connecting
- However, this device-to-GadgetBridge alarm sync API is not commonly abstracted, so we cannot respect existing alarms on the devices when changing alarms within the new Intent API; the database is the single source of truth and connecting the device after using the API will reset alarms
- ~~The API was designed to align with the `AlarmClock` API from Android, but~~ there is no feature parity to improve the design and interaction; after all the `AlarmClock` API is interacted with `startActivity`, but `GadgetBridge` uses `sendBroadcast` receivers, which is recommend for background tasks
- Errors are not raised to the caller (i.e. providing unknown or invalid Mac Address of device or trying to set an alarm on a nonexisting slot); these errors are logged though

**EDIT: Additional changes during the development:**

- Since slot IDs are unpredictable, the flow is title-driven (there is no way to provide an ID)
- Dismissing an alarm through the API removes its title
- Only alarms without a title can be overwritten and a title should be set through this API to retain the ability to dismiss it without dismissing all alarms of the user
- Dismissing all alarms regardless of the title is still possible
- The title is exposed in the UI not just when the device supports it, but also when this API is enabled in the developer settings of the device itself

**Example usage:**

- https://gitlab.com/martin-braun/warpclock-plus/-/blob/feat/gb/app/src/main/java/com/antonok/warpclock/AlarmIntentService.kt demonstrates dismissing all alarms and setting multiple alarms (search for `sendBroadcast`)
- `DeviceAlarmReceiverTest` should cover all cases for a more complete overview of the capabilities of the API

Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6088
2026-05-21 19:57:07 +02:00
José Rebelo 0c11ba44f8 CMF Buds 2a: Add touch options 2026-05-21 09:51:14 +01:00
Jack Wilsdon 51b305fb04 Add Thunderbird support 2026-05-19 23:53:38 +01:00
José Rebelo 3c848e6ac0 Moondrop Space Travel 2 Ultra: Initial support 2026-05-19 20:26:16 +01:00
José Rebelo dec078a2a0 Xiaomi-protobuf: Fix swapped min and max temperatures 2026-05-19 18:59:29 +01:00
José Rebelo 0a149f873a Merge pull request 'Pebble: Add support for installing dual slot firmware' (#5985)
Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/5985
2026-05-19 19:45:40 +02:00
Steffen WinterandArjan Schrijver df6a1c73e4 Fix drawer being drawn behind status bar
Before this commit the Gadgetbridge logo in the open navigation drawer
was partly cut of due to missing window insets on the drawer content.
2026-05-19 15:53:33 +02:00
José Rebelo a6a1188a11 Huawei Watch Fit 5 / 5 Pro: Initial support 2026-05-18 22:10:12 +01:00
José Rebelo 61f4396805 Garmin GPSMAP H1: Initial support 2026-05-18 21:49:00 +01:00
José Rebelo 09022454b8 Amazfit Bip S: Attempt to fix reboot on notification without subject or body 2026-05-17 16:23:38 +01:00
Benjamin Temple ad08874466 Pebble: Don't sleep for 100ms when doing firmware installs
originally the 100ms sleep after writes was introduced to fix a bug where sending an appmessage right after ACKing a previous appmessage cuased the outgoing packet to be NACK'd by the 3.0+ firmware. 4fe498efc
Keeping because 100ms for most situations doesn't matter, but definitely worth avoiding when uploading new firmware to the watch.
2026-05-17 08:06:18 -07:00
Benjamin Temple 1f36e541e3 Pebble: Ensure that we always try to install on the inactive firmware slot for dual slot firmware watches 2026-05-17 08:06:17 -07:00
Benjamin Temple 309dffbe61 Pebble: Display active firmware slot (for 2 slot watches) in watch details 2026-05-17 08:06:15 -07:00
Benjamin Temple 9d46ba6bc9 Pebble: Keep mmSequence in 5-bit range and don't overflow into the command bits 2026-05-17 08:06:14 -07:00
Benjamin Temple 5cd9c40436 Pebble: Update firmware install protocol to better match rebble.
1. We should upload all of the firmware before starting the install process. Otherwise this can cause issues with the install sometimes failing
2. Updates the encoding of the upload start. There are different upload start packet structures
3. Encode the install firmwareStart packet correctly to include how big it will be so that the watch can pre-erase the flash region.
4. Send the firmware then resouces to match the order that the pebble app sends the files.
5. remove arbitrary 100ms sleep in the main loop, the state machine blocks on readWithException already.
2026-05-17 08:06:13 -07:00
Benjamin Temple 045787fa93 Pebble: Fix blocking for 1s after writing every chunk to the watch
vastly speeds up transfer speeds
2026-05-17 08:06:11 -07:00
Benjamin Temple c29064a36c Pebble: Add support for dual slot firmware 2026-05-17 08:06:10 -07:00
Benjamin Temple f920968deb Pebble: Fix not being able to install firmware since firmware util was comparing the wrong model string 2026-05-17 08:06:04 -07:00
José Rebelo 3fe42f3d8f Huami: Avoid infinite loop when fetching very short activity 2026-05-17 16:04:14 +01:00
José Rebelo d085e6ae72 Garmin: Sync and archive some unknown files (#5824)
This is an attempt to prevent Instinct watches from becoming unstable as
time passes, since they start running out of memory.
2026-05-17 15:45:57 +01:00
José Rebelo 6961ff77db Sinilink: Initial support
Developed and tested against the XY-AP50L
2026-05-17 09:13:29 +01:00
José RebeloandJosé Rebelo c1f5647b6f Huawei: Allow encryption to be enabled / disabled 2026-05-17 00:46:18 +02:00
José Rebelo e93d6105bf Merge pull request 'Pebble: Fix pebble time 2 and core 2 duo not immediately showing up in device list' (#6124)
Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6124
2026-05-16 22:15:31 +02:00
José Rebelo 122f0bacb7 Anker Soundcore Sport X20: Reuse some equalizer strings 2026-05-16 21:11:24 +01:00
duhowandJosé Rebelo b8f5440a59 Anker: Add new device Soundcore Sport X20 (#5987)
This is an almost full implementation for [Anker](https://gadgetbridge.org/gadgets/headphones/anker/) [Soundcore Sport X20](https://www.soundcore.com/products/a3968-sport-x20-earbuds) earbuds.

Provides:

- Firmware version and serial number
- Display battery life when sent by earbuds
- ANC Settings
- Find Device
- Equalizer with Presets
- 3D Surrounding Sound
- Toggle "Touch Tone" (sound when button is pressed)
- Set the behavior of button actions
- Set Auto Power-Off Timer
- Enable discovery/pairing to add a second device to use the earbuds

Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/5987
2026-05-16 22:11:02 +02:00
Benjamin Temple f95273100e Pebble: Fix pebble time 2 and core 2 duo not immediately showing up in device list 2026-05-16 12:02:09 -07:00
José Rebelo c1d8fce4d3 Add setting to enable TRACE log level 2026-05-16 18:48:03 +01:00
José Rebelo 4761716bea Health Connect: Move per-sample logging to TRACE 2026-05-16 18:47:38 +01:00
José Rebelo d1f5531217 Prevent crash on devices without GPS 2026-05-16 18:09:57 +01:00
José Rebelo 37ad178dac Redmi Buds 6: Initial support 2026-05-16 17:54:51 +01:00
José Rebelo 5ffd6b6074 Set mimeType when sharing files 2026-05-15 23:09:10 +01:00
José Rebelo bb97a90909 GpxReceiver: Set mimeType to application/gpx+xml 2026-05-15 23:08:52 +01:00
Steffen Winter 5752a2bf96 Gradle: Migrate top-level build files to Kotlin DSL
Migrate the top-level build files to the new Kotlin DSL and use the new
pluginManagement block instead of the old buildscript.
2026-05-15 22:08:56 +02:00
Steffen WinterandJosé Rebelo d33ada370f Gradle: Migrate to version catalog 2026-05-15 22:02:12 +02:00
Davide GessaandJosé Rebelo 491f214611 Casio GBD200 device support (#6070)
In this pull request I separated the implementation of the GBD200 from the common implementation of GBX100 since during protocol reverse engineering (done here: github.com/dakk/casio-gshock-bt-proto/) I've found some discrepancies in the BLE protocol, and in my opinion it is better to separate since they are too different in many ways.
The flow works from initial pairing, connection, workout / step sync, configuration sync.

The following feature has been implemented and tested:
- [x] Watch connection and handshake
- [x] Config sync
- [x] Goal settings
- [x] Phone finder
- [x] Sport activity start and stop events
- [x] Sport activity sync with segment data
- [x] Step data sync
- [x] Notifications
- [x] Sport activity and OpenTracks
- [x] Alarm setting

Non Casio related edit:
- OpenTracksController.saveToGpx now handles empty activity (since gbd200 has no gps, and cannot handle gps data, running GBLocationService would be useless)

It should also address some of the following issues:
- https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/5529
- https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/2634
- https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/2597
- https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/5096
- https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/3395
- https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/2602
- https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/4095
- https://codeberg.org/Freeyourgadget/Gadgetbridge/issues/4092
- (test all the GBD200 related issues https://codeberg.org/Freeyourgadget/Gadgetbridge/issues?state=open&type=all&labels=&milestone=0&project=0&assignee=0&poster=0&sort=relevance&q=GBD-200)

Todo:
- [x] Test for some day on my wrist

![image](/attachments/4e4fff71-bbff-43a9-8d0e-1c6fef9e6d67)
![image](/attachments/61eaefdd-b36f-4334-bd05-e999edc31570)
![image](/attachments/821ba2a2-0dd1-4cc0-9e46-8f7a21acbe5c)
![image](/attachments/532c7e6b-7fb4-4166-a8d6-d63ace16afd2)

Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6070
2026-05-15 21:28:35 +02:00
José Rebelo 22859347f8 Redmi Watch Move: Initial support 2026-05-15 18:23:24 +01:00
José Rebelo 4ad2284d5f Merge pull request 'Pebble: Include battery read in pull-to-refresh update' (#6110)
Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6110
2026-05-15 13:48:49 +02:00
Dany MestasandJosé Rebelo e0820f106f AlarmClockReceiver: populate spec so notifications render on Xiaomi
Previously sourceAppId, title, and body were left null and sourceName
was the literal "ALARMCLOCKRECEIVER", causing Xiaomi watches to drop
the alarm-fire notification (the watch falls back to Gadgetbridge's own
package id which is not on the app allowlist, and the spec has nothing
to display).

Plumb the captured clock-app package (com.android.deskclock or
com.google.android.deskclock) through sendAlarm so:
- sourceAppId carries the real clock package
- sourceName is the resolved application label (NotificationUtils.getApplicationLabel)
- title = "Alarm" (R.string.menuitem_alarm)
- body = current time formatted via DateFormat

Strict improvement for all device families; Huami/ZeppOs previously
also displayed the alarm with empty title/body.
2026-05-15 13:48:35 +02:00
MrYoranimo a16b90f6aa Xiaomi-protobuf: combine installed apps and watchface cache when reporting installed apps
Because the list of installed apps and the list of installed faces are
requested from Xiaomi devices separately, a race condition will occur if
the lists are not combined: when processing the AppInfo event, all
previously known installed apps are removed from the app manager cache, which
will cause either all apps or all faces to get forgotten.
2026-05-15 01:21:20 +02:00
José Rebelo d5643468b9 iGPSPORT: Update install notification progress 2026-05-14 23:49:03 +01:00
José Rebelo 81ab123c32 iGPSPORT: Improve upload progress 2026-05-14 23:46:29 +01:00
Benjamin Temple 12db34cf90 Pebble: Include battery read in pull-to-refresh update 2026-05-14 15:38:02 -07:00
José Rebelo cbd92ef6fe update changelog, bump version 2026-05-14 21:12:43 +01:00
Benjamin Temple 552547ec9e Pebble: Add support for pull to refresh for pebble health data
Only signalActivityDataFinish on error as datalog will invoke once health sync data finishes syncing
2026-05-13 23:24:41 -07:00