OpenVitals Debug
tech.mmarca.openvitals.debug
Zapstore _@zapstore.dev Republished from GitHub / F-Droid by the Zapstore main account.
First release: Aug 4, 2026, 17 total releases.
Most recent release: Sep 26, 2026.
Appears in 0 app stacks.
0 sats / 0 zaps received in the past year.
Sats Received
Underlying data available via MCP: app_zaps, app_releases.
Zap Count
Underlying data available via MCP: app_zaps, app_releases.
Releases
- Sep 26, 2026 2.10.1-debugReleased 2026-09-26. This release puts a goal ring on each day of the Month view, so one look at the month shows which days reached the goal and how close the others came. It also stops the dashboard from shuffling its tiles on every refresh when "Sort empty tiles last" is on. - **A goal ring on each day of the month.** In a metric's Month view, each day has a thin ring around its number. It fills clockwise from the top with the day's share of the daily goal: 7,500 steps against a 10,000 goal fills three quarters, and a day on or past the goal is full. Steps, distance, calories, active calories, floors, elevation, wheelchair pushes, workouts, hydration, mindfulness and sleep each use their own daily goal. Days with no data and future days get no ring. Nutrition has none yet: its "at most" goals need a different reading. Based on a contribution by Teccheck. - **Libraries.** The Health Connect library moves to 1.2.0-alpha06, and the other libraries the app is built on are updated. Nothing changes on screen. - **Translations.** Spanish updates contributed by gallegonovato on Codeberg Translate. - **Dashboard tiles no longer shuffle on refresh.** With "Sort empty tiles last" on, a refresh marked every tile as loading, so the empty tiles jumped back to their saved places and then sank again once the data arrived. A loading tile is not empty: it now keeps its place, and moves only when its own data arrives and changes whether it is empty. On the first load after the app starts, the dashboard still waits for every tile and then sorts once.
More…
The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304507 --> - Sep 25, 2026 2.10.0-debugReleased 2026-09-25. This release adds food logging: a catalog of your own foods with their nutrients, logged by portion as Health Connect nutrition records. Settings can estimate your basal metabolic rate and save it to Health Connect, off by default. Every chart speaks to a screen reader, Finnish and Polish join the language picker with every language complete, and phone-to-phone sync shows the code on both phones and seals every frame. A long list of fixes lands from an audit of the app: editing a workout no longer deletes its heart rate, power, cadence and speed, heart rate averages agree across the app, Bluetooth sensors reconnect after a reboot or a drop, and a finished recording survives until it is saved. - **Food logging.** Add entry gains a Food tile. There are no preloaded foods: "New food" asks for a name, an amount, a category and any of Health Connect's 42 nutrients for that amount. Tapping a saved food logs a portion: the nutrients scale with the amount eaten and land in Health Connect as one nutrition record named after the food. A logged food never shows up in the drink history. - **Basal metabolic rate estimate.** Settings, Body profile gains a Sex field and a "Basal metabolic rate" switch, off by default. On, OpenVitals estimates the calories your body burns at rest with Mifflin-St Jeor from your sex, birth year, weight and height, and saves one value per day to Health Connect for the last 90 days. Each day uses the weight measured on or before it. A day that already has a rate from another source, a watch or a CSV import included, is left alone, and switching off removes every estimate. The card shows today's estimate or names what the profile still lacks. - **Charts for screen readers.** Every chart now tells a screen reader its title, the number of values, the lowest, the highest and the latest. Bar and line period charts also offer one element per day, so a reader can walk the period and select a day. Zoom in, zoom out and show the whole range are offered as actions, the scrubber offers next and previous point and reads the value, and the sleep schedule, the stage lanes and the Body Energy influence strip describe themselves. Not yet tried with TalkBack. - **Finnish and Polish.** Both join the language picker, and every offered language is complete: Czech, German, Spanish, Estonian, Finnish, French, Galician, Italian, Japanese, Polish, Portuguese, Russian and Simplified Chinese. Spanish updates contributed by gallegonovato on Codeberg Translate. - **Phone-to-phone sync shows the code on both phones.** The six-digit code used to be typed on one phone. Both phones now show a code and each user says whether they match; nothing is exchanged before both did, and "They do not match" ends the session with nothing sent. Every frame after the key exchange is sealed, so a changed, replayed, dropped or reordered frame ends the sync. The first phone to press Start now waits up to ten minutes for the other user instead of thirty seconds. Both phones need this version.
More…
- **Privacy policy.** The policy now names every data flow the app has: watch sync, the position sent to a watch that asks, music controls, calendar, weather, phone-to-phone sync, imports and exports, activity recording, diagnostics, and what is kept outside Health Connect and for how long. Everyone is asked to accept it once. "Review policy" no longer crashes on a phone without a browser. - **Heart rate averages agree.** The Today tile showed 71 bpm where the Heart rate screen showed 65: it folded Health Connect's hourly averages, which weight a workout hour by its samples. The tile, the week, month and year bars, the baselines and the reports now use the same day average as the day view, kept per day so a period opens without re-reading every sample. - **Steps follow Health Connect's totals.** Step totals and series come from Health Connect's own aggregate, so they match the Health Connect app and every other app that reads it. - **Text scale.** Text no longer shrinks below three quarters of its size, or below 12 sp, to fit; what still does not fit ends in an ellipsis instead of showing a wrong value. - **Imports keep the file's times.** A watch sync or a folder import went through the entry form, which lost the seconds of the start and rounded the duration up to a minute, and importing the same file twice stored the workout twice. The file's own start and end are kept, a watch file is stored as recorded by the watch, and a second import of the same file updates the records instead of adding them. - **A finished recording waits for you.** A workout you finished but had not saved lived only in memory, so a process killed on the way to the permission screen took the route, the laps and the heart rate with it. It now stays on disk until it is saved or discarded, and the review form comes back at start-up. - **Bluetooth sensors.** A reboot no longer leaves sensors on "Connecting": Android forgets unpaired sensors and most use a random address, so a forgotten sensor is found by a scan first. Sensors that slept during a pause reconnect on resume. A sensor with two data streams, such as cycling power with speed and cadence, delivers both. Each workout reads only the sensors that fit it: heart rate always, bike sensors for cycling, a foot pod for strides, and the setup card previews them. On Android 11 and older, adding a sensor no longer crashes, and watch and phone sync work again. Not yet confirmed on a phone. - **Editing a workout deleted its sensor series.** Changing a title removed heart rate, power, cadence and speed for good, on every recorded and every watch-imported workout. An edit now leaves the series alone unless the time window moved. An edit or a delete also no longer wipes the metrics of a second activity that started inside the window, and an edit writes first and deletes last, so an interrupted save leaves a duplicate at worst. - **Garmin watches.** A sync that failed part way no longer drops the files the watch had already archived; the next sync imports them. A workout that did not reach Health Connect, for a missing write grant or a rate limit, is fetched again, and a sync you started says so. The activity import reads the time zone per file, so a trip across time zones no longer skips or misplaces workouts. Pairing a new watch shows Android's companion dialog again, so background access can be granted. A running sync keeps the Bluetooth radio, so nothing opens a second connection to the same watch. Not yet confirmed on a watch. - **Widgets.** A background refresh no longer redraws a good tile as "0" or "No data" when Health Connect could not be read; the tile keeps its last value. - **Dashboard.** A cancelled load no longer leaves one tile on "Loading..." for the life of the app. - **Health Connect writers.** The history caches and the step-distance backfill no longer take a failed or rate-limited read for "no data", which could delete every derived distance record, and they skip a background pass that could only see the app's own records. - **Settings fields.** The weight, height and step length fields stop rewriting what you type, and a comma decimal is accepted. - **Drink amounts.** A saved drink of a litre or more opened as "1,500" and was read as 1.5 ml; it now reads back correctly in every locale. - **Rotation.** After a widget tap, a rotation no longer opens another copy of the screen, and after opening a route file it no longer imports it again. - **Settings sections open faster.** Each section now builds only what it shows, and Data transfer has its own screen. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304506 --> - Sep 19, 2026 2.9.1-debugReleased 2026-09-19. This release puts the phone's music on a Garmin watch: the watch shows what is playing, and its buttons play, pause, skip, seek and change the volume. Older Garmin watches with no settings tree, such as the first Instinct, get alarms from a list kept on the phone. "Send a point" reaches more watches, the drink dialog no longer hides nutrients, and the new watch texts are translated in every offered language. - **Music controls on a Garmin watch.** "Music controls on watch", on the watch's device screen, puts the phone's player on the watch's music controls. The watch shows the player, track, artist, album and position; from the wrist you can play, pause, skip, seek and change the volume. Off by default, and it needs "Stay connected". Android shows the phone's players only to an app with notification access, so switching it on without that grant shows a disclosure first; the grant alone forwards no notifications. Track details go only to the watch over Bluetooth and are never stored. Confirmed on a vivoactive 5. - **Alarms for older Garmin watches.** A watch with no settings tree, such as the first Instinct, had no Alarms action at all. It now opens a list kept on the phone: up to ten alarms, each with a time, repeat days, sound or vibration, backlight and one of the watch's preset labels. Edits save on the phone; nothing reaches the watch until you tap "Send to watch", and a send replaces every alarm on the watch. Alarms set on the watch do not show in the list. Not yet confirmed on a watch. - **Translations.** Spanish updates contributed by gallegonovato on Codeberg Translate. The new watch strings are translated in every offered language. - **"Send a point" on more watches.** The row asked for one capability only, so a watch that stores points through Garmin's Explore sync was told that no paired watch can store points. It is now offered there too. Not yet confirmed on a watch that stores points.
More…
- **Drink dialog hid nutrients.** The dialog body was cut off right after the hydration impact rows, so nutrients looked missing. The dialog now sizes to the window, a bottom fade shows when more sits below, and hydration impact is a dropdown like Category. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304498 --> - Sep 18, 2026 2.9.0-debugReleased 2026-09-18. This release lets you choose the guideline that names your blood pressure readings - ACC/AHA, ESH, ESC or ISH - and send a point from the phone to a Garmin watch's saved locations. Elevation correction now covers activities recorded on the phone, Garmin watches show ringing calls, older ones such as the original Instinct receive notifications, Russian joins the language picker with every language back at 100%, and a round of fixes removes the freezes behind "app isn't responding". - **Choose the blood pressure guideline.** The categories were fixed to ACC/AHA 2017, where high starts at 130/80 mmHg; Europe and the ISH start at 140/90. Settings gains a Vitals section with the choice: ACC/AHA 2017, ESH 2023, ESC 2024 or ISH 2020. ACC/AHA stays the default, and every guideline still flags a reading above 180 or above 120. The blood pressure screen gains "How it is classified", which explains how a reading gets its category, lists the thresholds and links the guideline's sources. - **Send a point to a Garmin watch.** A watch that can store locations gets a "Send a point" row. Type a name and coordinates - decimal degrees, degrees and decimal minutes, or degrees, minutes and seconds - or share a place from a maps app: OpenVitals appears as "Send to watch" for geo: links and shared text, and reads Google Maps, OpenStreetMap and OsmAnd links. A shared place only fills the form; nothing is sent until you tap Send. The watch keeps the point in its saved locations, where it can be picked as a navigation target, and each way the send can fail has its own message. Asked for as Gadgetbridge's "Send Point". Not yet confirmed on a watch. - **Ringing calls on a Garmin watch.** Calls never reached any watch. A ringing call now shows on the wrist with the caller's name and leaves once it is answered. With a dialer that uses Android's call-style notification, the watch's accept and reject buttons work. No phone permission is needed and nothing reads the call log. - **Russian.** Russian joins the language picker, contributed by Xapitonov on Codeberg Translate. - **Elevation correction covers phone recordings.** 2.8.0 corrected imported routes only. A GPS activity recorded on the phone now goes through the same correction when it finishes, under the same rule: a route not fully covered by your tiles keeps its own altitudes. The figure shown while recording is still the sensor's; the corrected route and gain land on the review form. The switch is now called "Correct altitude from tiles".
More…
- **Every language at 100%.** Czech, German, Spanish, Estonian, French, Galician, Italian, Japanese, Portuguese and Simplified Chinese are complete again. Italian updates contributed by NeriSal. - **Notifications on older Garmin watches.** Older watches such as the original Instinct showed nothing. The phone now waits until the watch has declared its capabilities before it sends the start-up sequence, so these watches subscribe for notifications and list their files. A watch that asks what an app is called gets an answer instead of waiting forever. A dismissed notification is always withdrawn from the watch, so phantom entries no longer pile up until nothing new appears. - **No more "app isn't responding" freezes.** Work that made the main thread wait now runs in the background: home widget refreshes, the quick beverage widget tap (it saves first and updates the tile after), beverage logging, heart rate charts over long periods, and the source labels on lists of readings, which made the Blood pressure screen sluggish. When Android does record a freeze, its trace - thread names and stack frames, no health values - goes into the report email and the debug log export. - **A night claims an early bedtime.** A night was filed by its start time alone, so a session that began before the "Night starts at" hour showed as a nap on the evening before and the wake-up date had no sleep. A night now also claims a session that starts before its window and spends more than half its span inside it. - **Long Apple Health import errors.** A long error shows its start and points to Copy error or Download full report for the rest. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304497 --> - Sep 12, 2026 2.8.0-debugReleased 2026-09-12. This release corrects the altitude of imported routes from elevation tiles stored on the phone, so a drifting barometer no longer inflates the gain. Workout plans gain sets, weight and rest per exercise, home widgets refresh on an interval you choose, older Garmin watches such as the Instinct 2X now sync, voice cues duck your music, and Body Energy counts respiratory records and holds steady after a heart zone edit. - **Elevation correction from offline elevation tiles.** Older barometric altimeters drift, so an imported route carries wrong altitude and an inflated gain. Settings > Activities gains Elevation correction: import SRTM .hgt tiles (or a zip holding one) downloaded on a computer, switch on Correct altitude on import, and every route imported from then on - GPX, TCX, KML, KMZ and FIT, whether one file, a folder or a watch sync - takes its altitude from the tiles and has its gain recomputed with the same smoothing a recording uses. A route with even one point outside your tiles keeps the altitudes it came with, and the import log says so. Phone recordings and activities already in Health Connect are untouched. The app downloads nothing; the tile card links to the guide that says where to get them. - **Sets, weight and rest per exercise in workout plans.** A strength plan such as "lat pulldown, 3 sets of 12 at 50 kg, 2 min rest" took six rows to build. An exercise row now has Sets, Weight (kg) and Rest after each set. Saving unrolls the row so Health Connect and other apps see plain steps; loading folds identical runs back into one row. The weight goes all the way through: the guided run shows and speaks it and its banner adds "Set 2 of 3", the review form prefills it per set so a lighter or heavier set can be corrected before saving, and the workout detail shows a Weight row. Durations can be typed in seconds or minutes, and whole minutes read as "2 min" in the builder, the setup card, the run banner and the voice cues. Older drafts still load. - **Choose how often home widgets refresh.** 2.7.3 fixed the widgets at every 30 minutes. Settings > Display now offers 15, 30, 60 or 120 minutes; 30 stays the default, and changing it re-plans the running refresh at once. Android decides the exact moment, and shorter intervals use more battery. - **Older Garmin watches sync too.** Watches on Garmin's older Bluetooth transport, such as the Instinct 2X, used to pair and then fail on their first sync. They now sync and receive forwarded notifications. Live heart rate and step streaming need the newer transport, so such a watch syncs but shows no live readings. Body weight a watch relays from a paired Garmin scale lands in Health Connect. A watch that lists no files on the first try is asked a second way, and a sync cut off midway keeps what arrived and is reported as interrupted so the next sync retries the rest. Contributed by hawk01. - **Voice announcements duck other audio.** Announcements and plan cues spoke over music at full volume. They now hold audio focus while speaking, so music dips and comes back when the last queued cue ends. Speech is tagged as guidance, so headphones play it on the media stream.
More…
- **Body Energy counts respiratory records.** The Respiration modifier always said "0 records": the 28-day respiratory baseline was never computed, and the day's records were only read once a baseline existed. Both now work the way HRV does. - **Body Energy holds steady after a heart zone edit.** Changing the zone mode made the score alternate between two values: today opened on the neutral 50 until the history was rebuilt, then jumped back on the next load. Today now keeps its last known value while the rebuild runs, the rebuild starts as soon as the setting is saved, and the dashboard card and detail screen reload once it lands. - **The app icon renders on every launcher.** The adaptive launcher icon was broken on some devices. The whole icon set, debug variant included, was redrawn as vectors following Android's adaptive icon guidelines. Contributed by Teccheck. - **Imported route gain is smoothed.** The gain of an imported route now goes through the same smoothing filter a recording uses, as the documentation already said, instead of a raw sum of every climb. - **Translations.** German updated to 99%; Polish is progressing on Codeberg Translate and will be offered in the language picker once it passes 70% coverage. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304491 --> - Sep 6, 2026 2.7.3-debugReleased 2026-09-06. This release estimates sleep stages on the phone for Garmin watches that never record them, such as the Venu SQ, from the heart rate and movement the watch does hand over. Home widgets refresh every 30 minutes, a whole folder of FIT files imports again, the Log screen no longer demands every write permission before it opens, and a Start over button rebuilds Body energy, Recovery and Expenditure from scratch. - **Sleep stages for Garmin watches that never record them.** Older watches such as the Venu SQ leave sleep staging to Garmin's servers, so their nights synced as nothing at all, or as an awake-only "sleep" session. What such a watch does hand over is a heart rate and a movement count for every minute, and OpenVitals now estimates the night from those on the phone: when sleep began and ended, and a light, deep, REM and awake timeline. One session per night, marked as estimated in its notes and rewritten in place as the night's files arrive over later syncs. A watch that records its own stages is left alone. - **Import a whole folder of FIT files again.** The folder button on the FIT importer card was lost in the move to Kotlin (2.5.0), leaving only one file at a time. It is back: pick the folder and every FIT file inside it is written straight to Health Connect, sub-folders included, in the order the activities happened. Garmin wellness files in the folder land as nightly HRV. A file that will not read fails on its own and the rest carries on; a very large folder says how many files were taken, and a folder with no FIT files says so instead of erroring. - **Start Body energy, Recovery and Expenditure over.** These are the three metrics OpenVitals works out itself and keeps outside Health Connect, and the only way to make it forget a bad run of them was clearing app data, which takes every preference with it. Settings > Recovery gains a Start over card that wipes exactly that derived set - the history, the tuning learned from your watch, the baselines and the expenditure cache - and rebuilds it from Health Connect behind a confirmation. Health Connect data, body profile, heart zones and goals are kept. - **Home widgets refresh every 30 minutes.** The widgets relied on Android's own update timer, which Doze skips and some phones throttle, so they refreshed a few times a day. They now re-read Health Connect every half hour while at least one is placed, and redraw as soon as the dashboard has loaded today. - **Log without handing over every write permission.** The Log screen used to lock itself until OpenVitals held every Health Connect write permission, even if you only wanted to record your weight. It now opens with any or no write access, and each tile asks Health Connect for just its own permissions when you tap it. Declining still opens the entry form, which offers Grant again whenever you are ready.
More…
- **Onboarding needs only the reads.** Step one used to insist on the Activity and Sleep write permissions as well. Decline every write in the Health Connect dialog and you can still continue; the log asks for a tile's write access when you first use it. - **The entry forms ask for write access the same way as the rest of the app.** A form whose write permission is missing shows the "Some permissions are missing" callout with Grant permission, instead of an inline Grant button beside the title. - **One heart rate average per screen.** 2.7.2 corrected the day's heart rate on the dashboard, but the Statistics card on the heart rate detail screen's day view still averaged raw readings, so the same day showed 82 bpm on the dashboard and 116 bpm one tap deeper (field report, Xiaomi Smart Band 10 via Gadgetbridge and Health Connect). That card, the HRV week and month charts and their statistics, the 28-day HRV baseline, the PDF report, the period charts for SpO2, body temperature, glucose and VO2max, respiratory rate and the overview captions all use the corrected averages now. - **The HRV tile can be granted from Settings.** The "Manual entry write access" card now includes heart rate variability. - **A missing write permission reads as one.** Saving a vitals or mindfulness entry without write access shows the permission message instead of a raw error. - **Metric detail screens hold still while they reload.** The transient syncing notice no longer pushes the sections down and back on every reload; only the sync-paused banner occupies that space. - **Translations.** Spanish, Japanese and Galician updated; Polish is progressing on Codeberg Translate and will be offered in the language picker once it passes 70% coverage. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304487 --> - Sep 2, 2026 2.7.2-debugReleased 2026-09-02. This release fixes the day's heart numbers: averages now weight each reading by how long it held, so a 50-minute run no longer outvotes the other 23 hours and a day that truly averaged 79 bpm no longer prints as 115. Steps can now be imported from CSV files with an optional end-time column, the quick beverage widget logs again, and a workout plan made on this phone keeps its Edit and Delete entries. - **Steps in the CSV importer.** Steps join the metrics a CSV can bring in, as the importer's first interval metric. Map an optional "End date and time" column and each row spans from its start to that end; a row without one - the column unmapped, the cell blank - counts as one minute. An end that cannot be read or is not after the start rejects only that row's steps, so the instant metrics beside it still import, and re-importing the same file replaces records rather than duplicating them. - **A workout no longer skews the day's heart rate.** Day averages weighted each reading by how often the device wrote, not by how long the value held: Gadgetbridge records background heart rate about once a minute but workouts at about once a second, so a 50-minute run outvoted the other 23 hours and a day that averaged 79 bpm printed as 115 (field report, Xiaomi Smart Band 10 via Gadgetbridge and Health Connect). Averages are now time-weighted everywhere a day is summarized: the heart rate and HRV day cards, the overview day values, resting heart rate, respiratory rate, SpO2 statistics, the sleep score's overnight HRV, the daily vitals series and the stress score. - **The quick beverage widget logs again.** Tapping the 1x1 quick beverage widget or the 2x1's Add button silently logged nothing in 2.7.0 and 2.7.1 release builds; the tap saves the drink again. - **Your workout plans keep Edit and Delete.** A plan physically written by OpenVitals on this phone could lose its Edit and Delete menu entries when device sync relabeled where it came from; ownership is now decided by the record's actual writer, and the displayed source stays display-only. - **The dashboard holds still while a sync runs.** The syncing notice no longer pushes the cards down when a refresh starts; only the sync-paused banner occupies that space.
More…
- **Translations.** Czech, Spanish, French, Portuguese and Simplified Chinese updated; Finnish and Polish have begun on Codeberg Translate and will be offered in the language picker once they pass 70% coverage. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304483 --> - Aug 30, 2026 2.7.1-debugReleased 2026-08-30. This release is about training with a plan. Build a routine once - blocks of exercises with reps or seconds, rests, and rounds - and start it as a guided run: the phone counts push-ups and squats with its proximity sensor where it can, timed steps and rests count down on a ring and move on by themselves, and every step is spoken and shown in the notification. Plans live in Health Connect, so one made in another app can be started too. Any workout can now be exported without its route as TCX, FIT or CSV, every language the picker offers is complete, and a nap from a Garmin watch finally counts as sleep. - **Workout plans.** A new Workout plans screen builds a routine: blocks of exercises picked from a searchable catalogue, each with a reps or seconds goal, rests between them, and a round count per block. Plans are stored in Health Connect as planned exercise sessions, grouped as today, upcoming and past. From the activity screen, Start walks a plan as a guided run - Step 2 of 6, Round 1 of 3, reps counted against the goal, timed steps and rests counting down on a ring that empties clockwise so a phone on the floor a metre away still tells you where you are, a spoken cue at every step and rest, and the same progress in the notification. Done, Skip, Skip rest and Back a step are the controls; Finish session saves the workout with the plan linked, and the linked plan shows on the workout's detail screen. A plan made in another app can be started or copied to today but not edited here; a logged workout can be saved as a plan; a recent plan can be repeated. - **Reps counted by the phone in a plan.** A plan step finds the same recognizer the single-exercise recording uses: push-ups and squats on the proximity sensor, pull-ups, rope skipping and trampoline jumping on the accelerometer. Squats are new to the proximity sensor, in plans and on their own. The step's label is matched loosely - "Pushups", "push ups" and the exercise's name in the phone's language all count - so a hand-named step is not left to manual counting. - **Workouts export without their route.** Every workout detail screen carries an Export workout card: save or share the session's type, times, duration, distance, calories and heart rate as TCX, FIT or CSV, with the GPS route deliberately left out. The card is there for sessions that never had a route too - a treadmill run has data worth getting out. - **Every language is complete.** Czech, Spanish, French, German, Italian, Estonian, Portuguese and Simplified Chinese are fully translated, including the workout plan, guided run and exercise names. - **Naps count as sleep.** A nap synced from a Garmin watch arrived with no stages - the watch's nap record only bounds it - so the session read as "nothing recorded" on the timeline and contributed nothing to the stage shares. It is now recorded as one light-sleep stage, as Gadgetbridge does.
More…
- **Out of bed, on the timeline and in the shares.** The stretch between two goes at a night takes a dusty rose in the Awake family instead of a brown that read as a different kind of thing, and Share of time in bed gets an Out of bed row after Awake, so the shares account for the whole span the timeline draws. - **The rest countdown beeps for five seconds, not three.** Three left barely enough time to get back into position before the bell. - **A night stored as overlapping records no longer doubles its duration.** Mi Fitness writes a night as a whole plus a partial record of the same hours. The day view, which recomputes from the stages, showed 8h23m; the detail screen summed the parts and showed 13h15m. The merged session's duration now comes from its resolved stages. - **Plan controls no longer wrap their labels.** Once Back appears the row holds four controls, and Done and Finish session wrapped mid-word on a phone; the icon buttons give up their side padding and the labels shrink rather than wrap. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304480 --> - Aug 26, 2026 2.7.0-debugReleased 2026-08-26. This release is about the app answering questions it used to leave to the user. The daily goal card now says how far ahead or behind a week is and what each remaining day needs, instead of a count of days that hit the mark. Offline maps rotate under two fingers and keep the live fix centred while recording. The summary fills tile by tile as each metric arrives, so a phone with a busy Health Connect opens straight away instead of holding a spinner for minutes. A Garmin sync no longer tells the watch to drop a day of data it never received. And the app speaks Simplified Chinese. - **Goal balance and per-day catch-up.** Goals met and success rate said how many days hit the goal; they could not say that a week with six met days still ended 606 steps short, or what each remaining day needs to average for the week to land on goal. The daily goal card on the activity screens now carries a standing line - so much ahead, so much behind, on track - and a catch-up line with the per-day figure for the days left, today included. The statistics grid gets a Goal balance tile. Every elapsed calendar day is judged, a day with nothing logged counting as zero, and the sign stays in your favour whichever way the goal points. - **Map rotation, and a camera that follows the recording.** Both offline renderers take two-finger rotation. MapLibre gets its compass back to reset north; Mapsforge, having none, gets one that appears whenever the map is off north. The destination flag stays upright on a rotated map. While recording, the camera keeps the live fix centred; panning hands the wheel to you, and the recenter button hands it back. - **Simplified Chinese.** A full translation, offered by the in-app language picker. - **The summary fills as each metric lands.** Reported by a user whose app "refuses to open" for minutes at a time, worse later in the day. The dashboard waited on one batch of Health Connect reads before drawing anything. It now renders at once with every tile loading and dispatches one read per metric, in widget order, so a tile answers when its own read does. Tiles that genuinely share a read stay together. A throttled Health Connect no longer stalls the screen: a read that would have to wait more than a couple of seconds shows its fallback and the dashboard says "wait about N min" instead of spinning. The weekly cardio read also asked for a whole day of one-minute heart-rate buckets in one request, which failed on exactly the watches with the most data and silently fell back to step estimates; it now reads five-minute buckets in bounded chunks that retry alone. - **The recording screen leads with its tabs.** The tab row comes first, and the Dashboard layout button sits under it rather than pushing the tabs down. CoMaps guidance lives on the map tab only - it is about the route, so it belongs with the route; the stats grid already carries it as a placeable cell. Start no longer refuses with a toast about a card you cannot see from the stats tab: it asks, with "Start anyway" and a way into CoMaps to set a route, and asks once. Dismissing the guidance card while setting a ride up no longer brings it straight back once the ride is running.
More…
- **Sleep day view drops the averages of one night.** Avg gap and the sleep target card described a mean of a single night. The stat is left out on the day view and the target card needs two nights to average; the daily goal card above already says what one night is. The four key-metric cards on a single night restated what the timeline, the time-in-bed shares and the sleep score already show, so they are gone from the day view. Week, month and year keep everything. - **A Garmin sync never tells the watch to drop a file it did not download.** The watch reuses its monitoring file numbers, and the sync's memory of what it had already copied was keyed on type and number alone. A new day's file matched a key from weeks earlier, was skipped, and then - on the theory that a held file the watch still offered had missed the flag - was told it was safe to archive. A day and a half of heart rate and steps went that way. The key now carries the file's date and size, and the archive flag only follows a download made in the same session. - **The recording screen's app bar is back.** The activity entry route was compared with its query string attached, so it never matched: no title, no dashboard editor pencil, no outdoor-mode toggle, focus mode never hid the bar, and outdoor mode never reached the chrome - the grey band above and below a black screen. It matches on its path now. With the pencil back, the duplicate Dashboard layout button that had been added to cover for it is gone. - **Black chrome under AMOLED, and outdoor mode reaches the frame.** The navigation bar took a near-black that lights a grey band along the bottom of a black screen; under the AMOLED theme it is pure black now. Outdoor mode repainted the recording body but not the app bar above or the gesture-bar inset below, framing the screen in exactly the contrast the mode exists to remove; it covers both now. - **Large Apple Health exports no longer run out of memory.** Steps, distance and active energy were deduplicated across sources by sorting the whole export's worth together, so every one was held until the parse finished; a step-dense export died against the heap cap a third of the way through. Records that can no longer overlap anything still to come are converted and released as the parse runs. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304475 --> - Aug 22, 2026 2.6.6-debugReleased 2026-08-22. This release is about the watch earning its place without a recording running. CoMaps guidance now reaches a Garmin watch whenever CoMaps is navigating, on its own switch, instead of riding along with a GPS recording nobody wanted to start. A newly paired watch keeps its link to the phone by default, because almost everything the watch can do depends on one. A caffeinated drink can be logged over the time it actually took, so a coffee nursed through a morning stops spiking at the first sip. And the app speaks French. - **CoMaps guidance on the watch, as its own feature.** The next manoeuvre, the distance to it and the street appear on the watch as a notification that updates in place, whenever CoMaps is navigating. It has its own per-watch switch, separate from the activity recording integration: guidance alone reaches the watch, the recording integration alone shows in the recording, both on shows in both, and neither can switch the other off. Starting a GPS recording just to get directions on your wrist is no longer the price of admission. The watch card asks for the CoMaps permission itself and says so if the grant is refused; granting it after the fact now re-opens the subscription rather than leaving a dead one. - **A drink can be logged over the period it took.** The Log drink dialog asks how long a caffeinated drink took - at once, 15 or 30 minutes, 1, 2 or 3 hours - and stores it as the nutrition record's end time. The caffeine model already spread a dose across a record's interval, but every drink written from the app was a one-second record, so a coffee nursed over two hours spiked at the first sip. The drink sheet already showed the duration and now has one worth showing. - **French.** A full translation, offered by the in-app language picker. - **Stay connected is on by default.** A Garmin watch expects its companion phone to hold the link, and most of what the watch can do rides on one: weather, find-my-phone, live heart rate and steps, handing over a recording the moment it finishes, and now CoMaps guidance on the wrist. Pairing a watch and finding none of it working, with no hint that a single switch was the reason, is the worse default of the two. It costs battery on both sides, which is what the card on the device screen says and what the switch is there for; a wearer who turns it off has that written down and this default never reaches them again. This is not only a new-pairing default - an existing install that never touched the toggle has nothing stored, and so picks the link up at its next start. Forgetting a watch clears the choice along with everything else, so a re-pair is a fresh watch getting the fresh default.
More…
- **An activity keeps the title given on the wrist.** The FIT `activity` message carries a name the public profile omits, and it is the title the wearer typed on the watch, so it now outranks the workout name when an activity is titled. - **A multi-hour ride no longer fails to import.** Health Connect caps a single record at about 1 MB, which a long ride's GPS route can exceed. The insert failed on every retry and took the whole batched import down with it. The route is now thinned by the ratio the platform reports and the insert retried, so the ride arrives. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304469 --> - Aug 19, 2026 2.6.5-debugReleased 2026-08-19. This release is about the app doing its job without being watched. The watch can now sync itself on a schedule, so sleep and activity arrive without opening the app. Sync with another phone stops choking on years of dense data and stops calling a partial transfer complete; when it fails, it now hands you the evidence instead of a shrug. A night slept in two goes no longer books the time out of bed as time awake. And the app speaks Czech. - **Automatic watch sync.** A new Automatic sync setting on the watch's device screen syncs a Garmin watch on its own every 30 minutes, hour, or two hours - off by default and chosen per watch. Scheduled runs are quiet by design: a watch out of range at 3am is not a fault to report, and the last sync time is what says the schedule is working. Android chooses the exact moment, so a run can be a little late; the battery-optimization exemption offered during pairing keeps overnight runs close to schedule. The schedule survives reboots and updates. - **Czech.** A full translation, offered by the in-app language picker. - **Notes on mindfulness sessions.** The timer save and the manual entry form take a note, stored in Health Connect with the session, so it stays yours and moves with your data. The list keeps notes behind a deliberate tap, and editing a session can change or clear its note. - **Beers in the beverage catalogue.** Beer, lager, pilsner, stout, and alcohol-free beer, with nutrition filled in and honest hydration credit - an alcoholic beer counts less than its volume. - **Sync with another phone handles years of data and slow links.** A data-dense library - a bike computer's worth of heart rate samples - used to be read into memory whole, which pinned small phones at their heap limit until the session timed out. The transfer now streams, so memory use no longer grows with the size of the library. Batches are also capped by size on the wire, so a batch of sample-heavy records crosses a slow Bluetooth link before the other side gives up waiting, and a pause caused by Health Connect rate limiting no longer kills the session. Older versions of the app still sync with this one.
More…
- **A failed sync explains itself.** The failure screen now shows why the session aborted and how far it got, with the same Copy and Share report buttons a successful sync gets. The last report is also offered when you reopen the wizard, so it can still be sent the day after. - **Time out of bed is no longer counted as time awake.** A night slept in two goes bridged the gap so the chart stays continuous, but the bridge was typed as awake: a 90-minute get-up read as 1h38m awake and dragged down sleep efficiency and the sleep score. The gap now appears in both the day and week charts as its own out-of-bed segment, in a colour no sleep stage uses, and stays out of the awake numbers. Sleep duration never counted it and is unchanged. - **A partial transfer no longer reports itself completed.** When sync with another phone could not read a page of records even after retrying, it used to end the stream quietly and let the session say it finished. It now aborts with the reason, on both phones' reports. - **The mindfulness year heatmap shows the last twelve months.** The rolling year window only drew the days that fell in the window's first calendar year, so the months since January - including today - were missing. The grid now covers the whole window, laid out in week columns with month labels. - **Mindfulness entries no longer say "null".** Sessions recorded by the old Flutter-era app stamped the word "null" where there was no note; those now read as having no note, and re-saving one scrubs it from the record for good. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304465 --> - Aug 13, 2026 2.6.4-debugReleased 2026-08-13. This release is about numbers that were technically correct and told you nothing. Body Energy charged a broken night almost exactly what it charged a perfect one, because it counted the minutes you slept and never asked how they went. Weight over a month was a calendar of near-identical coloured dots, shaded by a quantity that barely moves. A month of nutrition was a total nobody eats by. And a Garmin day could report 889 steps while the watch had recorded 1,007, because records that overlapped by a single minute had that minute discarded by Health Connect. Each of those is a different bug with the same shape: the data was there and the reading was not. - **Body Energy reflects how well you slept, not only how long.** Overnight charge now scales by sleep efficiency, time spent awake after falling asleep, and the deep and REM share of the night. Two eight-hour nights of very different quality used to land within a few points of each other and now sit about fifteen apart. Three properties keep it honest: an ordinary night charges exactly what it charged before, so the change spreads nights apart rather than moving everyone up; the effect is capped at twenty percent either way, so no single night of odd staging can undo hours actually slept; and a sleep source that records no stages is left exactly as it was, because a start and an end alone read as a flawless night and would earn a bonus for recording nothing. - **A flawless night reads above a merely good one.** The sleep score stops distinguishing nights once they clear its clinical thresholds, which is right for a score answering whether a night was healthy and wrong for one asking how much it restored. The charge reads the same measurements on a continuous scale instead. Stage architecture is deliberately not stretched that way: more deep sleep than the healthy range is not more recovery. - **Body measurements draw a trend line over week, month and year.** Weight, body fat, lean mass and the rest previously handed those ranges to the calendar heatmap, which colours a day by how big its number is. That reads well for steps and reads as nothing for a weight that spends its life inside a two-kilo band. The scale is fitted to the values rather than anchored at zero, because a kilogram of drift is invisible on an axis that starts at nothing. Day keeps its own intraday chart. - **Nutrition leads with a daily average over a period.** Each nutrient tile shows the daily average with the period total kept underneath, across the vitamin and mineral grids as well as the four macros. A single day is left alone, where the total already is the day. - **A new Nutrition setting chooses what an average divides by.** Averaging over logged days only, the default, is what someone who logs occasionally means by their daily calories. Turned off, the divisor is every elapsed day of the period. Either way a period still running divides only by the days that have happened, so this month's average on the thirteenth is over thirteen days and not thirty-one.
More…
- **Garmin step counts no longer come up short.** Each sync's first intraday record began at the edge of its fifteen-minute slot, which was before the previous sync's last record ended. Health Connect discards the overlapping span when it aggregates, so records that summed to 1,007 steps reported 889. Distance and active calories were losing the same way. - **An entry list stays expanded after an entry is swiped away.** How far the list had been expanded was remembered against the entries themselves, so deleting one reset it to the first page, which pulled everything below it up the screen and left the reader looking at a section they had never scrolled to. - **Maximum heart rate is no longer invented from a quiet fortnight.** With no trustworthy observed maximum the app used the highest rate it had seen plus ten, so a fortnight peaking at 141 produced a stated maximum of 151 with nothing marking it as a guess. It now uses the same age-based figure as heart-rate recovery and Body Energy, honours a maximum stated in the body profile outright, and labels an estimate as an estimate. - **The cardio load target no longer reports impossible percentages.** A week scored from heart rate was being compared against older weeks that could only ever be scored from movement, which produced figures such as 2640 percent of target. The baseline now only includes weeks scored by the same yardstick. - **Chart date labels arrive whole.** A label was confined to its own slot and clipped there, so a month showed "1(" for the 16th, and a year on a line chart cut its month names down to slivers. Labels are now measured against the width they actually have and thinned to what fits. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304459 --> - Aug 12, 2026 2.6.3-debugReleased 2026-08-12. This release is about the watch feeling paired, not just synced. A Garmin watch can now stay connected whenever it is in range - the way the vendor's app behaves - and that held link carries what a companion app carries: live heart rate and steps, weather from a weather app on the phone, the phone's calendar on the wrist, find-my-phone that actually rings, and GPS ephemeris handed over for second-long fixes. None of it grows the app an internet permission, and everything personal is off by default behind its own switch. Around the watch work, the sleep score is rebuilt on published sleep-science pillars, and onboarding gains a one-tap Grant all. - **Stay connected.** A per-watch switch holds the Bluetooth link open whenever the watch is in range, instead of only while notifications need forwarding. Android's companion-device presence wakes the app when the watch comes back, so the link returns promptly. - **Live readings.** With Stay connected on, a second switch streams the watch's current heart rate and step count to the phone. The values appear on the watch screen and the dashboard, live in memory only, and disappear when the link drops - the same measurements arrive later through the normal sync. - **A watch tile on the dashboard.** The most recently synced watch, with its battery, last sync time, and a sync button. While live readings stream, the tile shows the current heart rate and steps instead of the last sync time. - **Weather on the watch.** The watch's weather glance is answered from a weather app on the phone that broadcasts the Gadgetbridge generic-weather format; Breezy Weather is the tested one. OpenVitals itself never contacts a weather service. - **Calendar on the watch.** The watch's calendar glance can show the phone's upcoming events. Off by default; switching it on asks for Android's calendar permission. Events are read only while answering the watch, go to it over Bluetooth, and are never stored - declined and cancelled meetings stay off the wrist. - **Find my phone, both directions.** The watch's find-my-phone feature now rings the phone at alarm volume, even when silenced, with a notification to stop it. Finding the watch from the phone worked before and still does.
More…
- **GPS ephemeris.** Import a satellite prediction file on the watch screen and the phone hands it to the watch when it asks, turning a minutes-long cold GPS fix into a seconds-long one. Nothing is downloaded: the user fetches the file, the app recognizes its format by content and serves it. A stale file is refused rather than served. - **Grant all in onboarding.** The first permission screen gains a Grant all button that requests every category in one Health Connect dialog. Mindfulness, cycle tracking, and additional access keep their own explicit steps. - **A permissions checklist after pairing.** Adding a watch now offers the OS-level grants a watch benefits from - notification access, battery-optimization exemption - each explained, each declinable. - **Sleep score rebuilt on sleep-science pillars.** Duration, quality, and overnight HRV recovery are scored using published sleep guidance (NSF/AASM), with age and night HRV feeding the score, recovery, and the dashboard. - **The pairing path decides what a device is.** A device added through Settings, Watches is a watch; one added through the sensors flow is a live sensor, even when it is physically a smartwatch. The device's name no longer decides. - **The watch tidies up after a sync.** Files already copied to the phone are archived on the watch after import, so its storage does not fill with what the phone already holds. - **Watch battery on the phone.** The battery percentage arrives during a sync and shows on the device screen and the dashboard tile. - **Cardio load and intensity minutes read workout heart rate.** They were reading 15-minute aggregates that fell through the gap filter and fell back to movement data even when dense workout HR existed in Health Connect. - **Body tiles open their own metric screens.** Tapping Weight landed on a Body overview, a two-hop trip to the metric the tile already named. Body tiles now open their metric directly, like heart and vitals. - **The syncing banner is no longer clipped** at the top of the dashboard. - **A smartwatch added as a sensor stays a sensor.** The BLE sensor registry no longer reclassifies it by name. - **Diagnostics exports include raw process logs**, unsanitized, which is what a support thread actually needs. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304457 --> - Aug 8, 2026 2.6.2-debugReleased 2026-08-08. This release lets a reading into the app that no wearable took. HRV can now be logged by hand - for everyone whose RMSSD comes from a camera app or a chest-strap app rather than a watch - and every hand-logged vitals reading can finally carry the moment it was actually taken, not the moment it was typed in. Around that, a batch of dashboard and sleep fixes: day switching that answers the tap, tiles that never show another day's numbers, and nights that land on their own dates. - **Manual HRV entry.** Heart rate variability joins the Log screen: one RMSSD value in ms, written to Health Connect as a manual entry, feeding the dashboard tile, the HRV screen, and baselines like any watch reading. Entries made in OpenVitals can be edited and deleted from the HRV day view; readings from other sources stay read-only. The tile sits in the Log grid's default layout and can be removed in its edit mode. - **Date and time pickers on every new vitals entry.** Blood pressure, SpO2, respiratory rate, body temperature, and HRV forms offered the pickers only while editing; a new entry silently stamped "now". They now show when adding too, defaulting to now, and reset after each save so the next reading defaults to now again. - **Switching days on the dashboard answers instantly.** The date flips at once, tiles show a loading state instead of the previous day's numbers, and the rings sweep in exactly once with the right values - they used to animate twice, first with the old day's data. - **The small weekly cardio tile no longer loads forever.** Placed alongside the cardio ring, it stayed on "Loading" even though its data was already on screen.
More…
- **Coming back from a metric screen keeps your place.** The widget carousel returns to the page you were on and the dashboard keeps its scroll position, instead of jumping back to the first page through a loading flash. - **No dot at the end of the hydration day graph.** Dots mark entries; the line's trailing hold at "now" is drawn as line only. Applies to every cumulative day chart (hydration, nutrition, mindfulness). - **A sleep window set within one day files each night on its own date.** With a window like 00:00 to 12:00, the night window silently spanned 36 hours: each date showed whichever adjacent night was longer, whole nights appeared as naps, and the month view missed today. Midnight-spanning windows (the 18:00 to 10:00 default) were always correct and are unchanged. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304450 --> - Aug 6, 2026 2.6.1-debugReleased 2026-08-06. This release puts a navigator next to the recorder. With a CoMaps build that shares its navigation, a GPS recording shows the guidance you are actually following - the turn, the route, the destination - while OpenVitals keeps doing the one thing it was doing: recording. CoMaps plans and navigates; OpenVitals reads and records. Nothing read from CoMaps is written to Health Connect. - **Live CoMaps navigation while recording.** With the integration on and a CoMaps build that shares navigation: - The next turn floats over the live recording map - direction, distance, and the street it turns onto - and the stats dashboard offers a guidance tile the layout editor can place like any other. - The planned route is drawn point-for-point on the offline map, the same geometry CoMaps draws: a wide cased blue line with white bent arrows through every turn and a flag on the destination. The location dot becomes a compass arrow that points where the phone points. - Start becomes a doorway: with guidance enabled, the setup screen's Start opens the armed recording view, where you set the route up in CoMaps or dismiss the guidance card - then Start begins the session. Already guiding, dismissed, or integration off: Start starts immediately. - Guidance shown during the ride can be kept with the saved activity and read back on its detail screen - on this device only, never in Health Connect. Deleting the activity deletes it. - Observed, not polled: CoMaps announces each change and OpenVitals listens; a phone that is navigating nowhere is never queried. Off by default under Settings > Activity recording, guarded by CoMaps' own runtime permission.
More…
- **One launcher icon.** The release build ships the artwork the debug build had; debug keeps the shape and differs only in colour. - **3-button system navigation no longer covers the bottom of screens.** Screens without the app's own navigation bar now leave room for the system bar. - **Heart and vitals tiles open their own metric screens.** Tapping Blood pressure opens the blood pressure detail directly; the intermediate Heart & Vitals overview is gone. - **The swipe-to-delete red stays hidden until the row is swiped.** It used to show through entry rows at rest. - **One reload shows one indicator.** The pull spinner answers the pull gesture; background syncs speak through the inline banner - never both. Dashboard widgets replay their animations only when a reload actually brought new data. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304447 --> - Aug 5, 2026 2.6.0-debugReleased 2026-08-05. This release is about the two conversations your health data has outside the app: with your doctor, and with you. A PDF report you can hand across a desk, menstrual cycle tracking that lives entirely in Health Connect, and blood-pressure logging that captures what clinicians actually ask about a reading. Everything is built on the device; nothing needs an account or the internet. - **Menstrual cycle tracking.** Log period flow, spotting, sexual activity, ovulation tests, cervical mucus, and basal body temperature - one category at a time, each saved as its own Health Connect record. Period days are derived from your flow entries, and cycle statistics predict the next period using established fertility-awareness rules; when your cycles vary too much for an honest prediction, the app says so instead of guessing. Cycle data stays an explicit, separately granted Health Connect permission category, and OpenVitals stores none of it outside Health Connect. - **Health report export (PDF).** Pick metrics, a daily, weekly or monthly detail level, and a preset or custom range, and OpenVitals builds a PDF from Health Connect - on the device, with the platform's own PDF engine. Every metric gets a chart, summary statistics, and a data table; the report states its own gaps in print when a permission is missing, the range was truncated, or the build was cancelled. Metrics with more to say get clinical sections: - **Blood pressure:** systolic and diastolic statistics kept separate, averages by meal context, and every reading listed with its position and cuff location. Contexts the user chose are shown as such; estimated ones are marked. - **Blood glucose:** averages by relation to meal, fasting first - the number a doctor asks for. - **Workouts:** totals per activity type and the full session list, not just minutes per day. - **Sleep:** average bedtime and wake-up (averaged correctly across midnight), the deep/REM/light/awake stage mix, and one row per night.
More…
- Body metrics show their change over the range, and body temperature lists every reading like a fever diary. - **Richer blood-pressure logging.** The entry form gains three optional dropdowns - when the reading was taken (before/after breakfast, lunch, dinner), body position, and cuff location - plus a collapsible measurement guide covering the standard home protocol: rest five minutes, cuff two centimetres above the elbow crease, three readings with the first discarded, and the under-135/85 home target. Position and cuff location are native Health Connect fields, readable by any app. - **Distance backfill from steps.** For setups where an app writes steps but no distance: an opt-in setting under Activities takes your stride length and fills in daily distance records only for days that have steps and no distance from any source. Derived records are marked as OpenVitals entries and are removed again if you turn the feature off. - **Portuguese.** The app now speaks Portuguese, and Spanish, Italian, Estonian and German are complete again at 100%. - **The dashboard keeps tiles with recent history.** A tile only sinks below the fold when its metric has no data today and none in recent days - Sleep no longer drops just because tonight has not happened yet. A new "Sort empty tiles last" display setting makes the behaviour a choice. - **Cycle screens allow screenshots.** The previous release blocked capture on cycle screens; that also blocked the phone's owner, so it is gone. - The base unit option is named "System" everywhere, matching the rest of the app (#247). - **Year-long heart-rate reads no longer risk coming back empty.** Daily heart-rate and resting-heart-rate history is read in provider-safe slices, the same fix the nutrition series received earlier. - **Duplicated blood-pressure records are collapsed in the report.** The same reading written twice to Health Connect - an import run twice, a second app echoing data back - counts once; genuine repeat measurements are kept. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304445 --> - Aug 4, 2026 2.5.0-debugReleased 2026-08-04. OpenVitals is native Kotlin again. Every feature the 2.x line added has been rebuilt on the Android-native app, and this release adds what it was rebuilt for: a second phone across the table, a folder of CSV files, and a clearer story for the watch on your wrist — all of it without an account and without the internet. Your data and settings from the previous version are imported the first time you open it. - **Sync health data with another phone over Bluetooth.** Two phones, a code you confirm on both, and a report of what moved. No account, and no internet is used at any point. Records keep their original source: an activity that Gadgetbridge wrote on one phone still says so on the other. - **Import health data from CSV files** through a guided wizard that maps your own columns onto the records they belong to. - **Units that follow your device.** The unit setting now defaults to your Android measurement-system preference, and every quantity can override it on its own — kilometres for distance, pounds for weight, and Celsius for temperature can all be true at once. - **Quick-add a drink from the reminder.** One tap on the notification logs it — the app never opens — and the countdown to the next reminder is anchored to your last drink rather than to the clock. Reminders now survive a reboot and a change of timezone. - **Record a run or ride without GPS.** The barometer still counts your climb and the phone still counts your steps, so an indoor or tunnelled session is a real activity rather than a gap. - **A guided heart-rate recovery test,** recorded as part of the session it follows.
More…
- **TCX and indoor-workout file import,** for treadmill runs, trainer rides and strength sessions — files with no route, which is not the same thing as a broken file. - **The Body Energy home-screen widget draws its day again,** with the start and end values labelled on the curve. - **Settings additions:** Body profile is now a section of its own, carrying your height and the measurements Health Connect resolves; high and low heart-rate alert thresholds; a stepper for the hydration goal; and a toggle for the mindfulness integration. - **Smartwatches sync through Health Connect.** OpenVitals does not pair with watches: Gadgetbridge or your vendor's app syncs the watch into Health Connect, and OpenVitals reads everything there — steps, heart rate, HRV, sleep and workouts — with the original source shown on each record. Bluetooth sensors are unaffected: heart-rate straps and cadence and power sensors still stream live into a recording. - **Your previous version's data comes across on first launch.** Goals, units, theme, caffeine and body profile, custom drinks, paired sensors, reminders, offline map packs and home-widget selections are imported automatically the first time 2.5.0 opens. Nothing from the old version is deleted. - **Elevation is more accurate.** GPS noise no longer banks itself as climb: altitudes are smoothed and thresholded the way the barometer path always was, so a climb below the noise floor honestly reports zero. - **The dashboard only offers tiles your device can fill.** A metric your phone cannot provide gets no tile instead of an empty one, and edit mode still lists it so adding it back is never a dead end. - **Chart settings live together.** Rolling dates moved next to aggregate charts under Display. - **Sleep no longer double-counts overlapping stages.** When a source records the same stretch as both light and deep sleep, the deeper stage wins and the total can never exceed your time in bed. - **Year views load again on large libraries.** Yearly calories, steps and heart metrics are served from the app's daily-history cache and read in slices, instead of one oversized Health Connect request that could silently come back empty. - **The dashboard syncs once per open,** with one status banner instead of two. - **The Body Energy widget no longer forgets its morning.** A transient permission hiccup used to reset the day's start to 50; the widget now keeps the value carried over from yesterday. - **Elevation on backfilled activities** now runs through the same smoothing as a live recording and an imported route. - **The skin-temperature card no longer blanks** when the newest reading carries no change — it reads the newest reading that actually has one, the same data its chart draws. - **An unchanged battery reading no longer re-stamps its time,** so a device that reports the same percent does not look freshly updated. - **A permission error now offers a way to grant access** instead of a dead-end message: the real request inside Health Connect, or Health Connect's settings outside it. The app keeps the same package name and signing certificate, so this installs as a normal update. Distribution flow: - Codeberg release with signed APK, signed debug APK, and signed Android App Bundle assets. - Direct Google Play production upload from the approved Woodpecker deployment. <!-- OpenVitals-Version-Code: 1070304442 -->