Skip to content

OpenVitals 2.10.0

github-actions[bot] edited this page Nov 9, 2026 · 1 revision

Released 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.

Added

  • 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.

Changed

  • 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.
  • 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.

Fixed

  • 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.

Generated from docs/releases/2.10.0.md. Edit it there; changes made here are overwritten.

Home

Features

How-to

App

Reference

Engineering

Proposals

Releases

Project

Clone this wiki locally