Skip to content

Releases

OpenVitals Nightly

OpenVitals Nightly Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 06 Oct 13:48

OpenVitals Nightly

Mutable nightly build from commit 5a360a1.

This release keeps a stable download page. The APK and checksum assets are replaced by the next nightly build.

Assets:

  • Signed nightly APK (armeabi-v7a,arm64-v8a)
  • Signed Debug APK (armeabi-v7a,arm64-v8a)
  • Signed app bundle (AAB), for a Google Play upload by hand
  • SHA-256 checksums

OpenVitals v2.16.0

Choose a tag to compare

@github-actions github-actions released this 06 Nov 07:43

Released 2026-11-06.

This release reads the cycle from the records a watch or ring leaves behind, and says plainly what they can and cannot tell. Once the current cycle holds a positive LH test, a confirmed temperature rise or a mucus peak, the next-period estimate counts from that day and the card names it. The thermal chart draws the night skin temperature a watch or ring writes to Health Connect beside the morning readings, and finds a rise in it afterwards, from the whole cycle, never in advance. A new card lines up each night's resting pulse, HRV and breathing rate by cycle day, with the studies behind it, and the cycle settings let you declare a hormonal method, which the skin temperature card takes into account. None of it marks a fertile or a safe day. On the wrist, the Wear OS watch app gains tiles for heart rate, steps and floors with the day's curve, and a weigh-in on the Xiaomi S400 Pro scale no longer saves as 204.7 kg.

Added

  • The next-period estimate counts from a recorded ovulation sign. Once the current cycle holds a positive LH test, the first high day of a confirmed temperature shift or a mucus peak, the estimate counts from that day instead of from the last period start, since the days from such a sign to the next period vary less than whole cycles do. Each sign has its own interval, learned from your earlier cycles that hold the same sign and shrunk toward a published figure until there are enough of them. An LH test up to five days, or a mucus peak up to three days, before the first high day confirms the shift, and the card says a second sign agrees; signs that disagree fall back to the calendar estimate, and the card says so. The card names what the range counts from. It is still an estimate of the next period: it never marks fertile or infertile days.
  • Night skin temperature in the thermal chart, with a shift found afterwards. Beside the morning readings, the chart shows the night skin temperature a watch or ring writes to Health Connect, as a change from the device's own baseline. Two chips, Morning (BBT) and Night (skin), switch each series on and off; each has its own colour and its own axis, and the two are never mixed. From 15 nights on, OpenVitals looks for a rise after the fact: the first night where it and the next two each lie at least 0.2 °C above at least five of the six nights before. The line under the chart says what was found and which rule found it, or that the nights are too few, too gappy or the signal too weak to judge, as happens when a device smooths what it passes on. The wording is "no shift detected", never a statement about ovulation, and the shift feeds no estimate. Skin temperature is read when the vitals permissions already allow it; otherwise the chip says so and points to the Health Connect permissions in Settings.
  • What skin temperature can and cannot say. Under the thermal chart, a card explains that watches and rings measure skin temperature at night, that after ovulation it tends to be a little higher, and that OpenVitals reads a rise only afterwards and does not use skin temperature for its estimates. A toggle shows the numbers and the studies behind them, each with a link. When a hormonal method is set, or was stopped within the last two months, the card says in plain words why the pattern may be missing; a declared PCOS context adds a note that no study of temperature-based ovulation detection in PCOS was found. It is information, not a method of birth control, fertility prediction or medical advice.
  • Night pulse, HRV and breathing across your cycle. A card on the cycle screen draws the current cycle's overnight resting pulse, HRV (RMSSD) and breathing rate by cycle day. Each night's value is the median of the readings inside its sleep session, placed on the day you woke up; a resting pulse the device only wrote as a daily value is drawn hollow and labelled as such. Each signal has its own colour, axis and chip, takes one device for the whole cycle, and is named as missing when the watch does not record it or the permission is not granted; one button asks for the sleep, resting heart rate, HRV and respiratory rate permissions, which are not part of the cycle permissions. "Why this is shown" opens the studies, how the night value is made, and the caveats: sleep, alcohol and hormonal contraception move these lines too. The card is information only: it says nothing about ovulation, fertility or contraception, and changes no estimate.
  • A declared hormonal method. Settings, Cycle, has a Hormonal contraception card: pill, hormonal IUD, implant, ring or patch, injection or another hormonal method, with an optional day it was stopped. Copper IUDs, condoms and diaphragms use no hormones and are not listed. An enabled pill scheme counts as the pill. The method travels with the cycle journal export and with the cycle category of a phone-to-phone sync, and a phone that has declared none takes the other's. Today it changes only the skin temperature card.
  • Watch tiles for heart rate, steps and floors. The Wear OS watch app offers three tiles, added from the watch's tile list. Each shows today's value in the colour the phone app uses for that metric, and the day's curve from midnight to midnight, drawn up to now: the heart rate as quarter-hour means, broken where the watch stored none, the steps and floors as a running total. The heart rate tile shows the newest sample with its age, a dash once it is older than an hour, and the day's lowest and highest under the curve; the floors tile shows the metres that counted. The steps are the ones the watch counted itself, so they can fall short of the phone app's total, which adds the phone's own steps and other apps'. A value whose permission is off, or whose sensor the watch lacks, shows as a dash with the reason. A tile starts no sensor and reads only what the watch app recorded; a tap opens the watch app. Verified on a TicWatch Pro 5 with Wear OS 4.

Fixed

  • Xiaomi S400 Pro weigh-ins saved as 204.7 kg. The S400 Pro marks the frame it sends without a weight by setting every weight bit, where the S400 clears them. Read literally that is 204.7 kg, so the last frame of a weigh-in replaced the measured weight, and its impedance was taken for the other frequency, which made the body composition wrong too. Both markers now mean no weight, and the frame adds its impedance to the weigh-in instead of replacing it. Reported, with the fix, in #323.

The app keeps the same package name and signing certificate, so this installs as a normal update.

Distribution flow:

  • GitHub release with signed APK, signed debug APK, and signed Android App Bundle assets.
  • Direct Google Play production upload from the approved production run of the release workflow.

OpenVitals v2.15.2

Choose a tag to compare

@github-actions github-actions released this 01 Nov 18:56

Released 2026-11-01.

This release keeps the dashboard filling when Health Connect runs out of patience. On Android 13, where Health Connect is a separate app with a stricter limit, a fresh install could show "no data" on every tile and a toast asking to wait a minute, forever; the app now spaces its calls, needs far fewer of them, counts down in a banner and asks again for the missing tiles by itself. Sync with another phone gains an Overwrite existing records option for records Health Connect holds but does not count, the CSV importer reads blood pressure logs and the app's own workout exports, and a Wear OS watch now sends the floors it climbed and a resting heart rate for each night, and rests its heart rate sensor while off the wrist. Every report, crash draft and log the app can hand out holds counts, types and reasons, never your values.

Added

  • Overwrite existing records in a phone-to-phone sync. Health Connect can hold a record and still leave it out of its totals: a record restored from a backup or a phone transfer keeps the app that first wrote it as its source, and when that app is not on the new phone the dashboard reads zero steps while the sync counts the record as already there. A new checkbox on the "What to accept" step, off by default, makes this phone write every record the other phone sends under OpenVitals, which Health Connect does count. The choice is local to the phone that ticks it, a record arriving twice in one session is still written once, and the report says when it was on.
  • Workouts from a CSV file. The CSV importer recognises the workout export the activity detail screen writes and imports each row as a workout of its own: editable, deletable, and replaced rather than duplicated on a re-import. A file made by hand with the same headers imports the same way, with the date and time settings for local times, so a history rebuilt from other apps' exports comes in one workout a row. Distance, elevation, steps, calories, floors and wheelchair pushes are written beside the session, an average heart rate becomes a flat series, and a type the app cannot name is stored as an other workout and counted.
  • Blood pressure from a CSV file. A systolic and a diastolic column, in mmHg, make one reading per row, with optional body position and cuff location columns read as the words the app itself shows, in its language or in English. A position or cuff the file leaves out, or names in an unknown word, takes a default chosen on the mapping step and remembered for the next import. A reading outside what Health Connect accepts, or whose systolic is not above the diastolic, is rejected on its own; the weight in the same row still imports. Contributed by Anthon Pang.
  • Floors and elevation from a Wear OS watch. The watch app measures the height climbed from its barometer, one value per minute: a rise counts once it reaches 3 m, so the barometer's wobble does not add up. A sync turns the metres into floors, 3 m each with partial floors kept, and writes the same metres as elevation gained. Height counts only when the watch counted at least 10 steps per floor in that minute and the one before, so elevators and weather fronts drop out. A watch without a barometer records none.
  • A resting heart rate from each night on a Wear OS watch. Each finished night with sleep gives the lowest half-hour average of the heart rate during the night, written to Health Connect at the end of the night. A day that already holds a resting heart rate from elsewhere, such as the vendor's app, keeps that one. This needs the grants to read and write resting heart rate; the watch card asks for them.
  • Live heart rate on the watch's screen in the app. While the watch's device screen is open and the watch is worn, its status card shows the heart rate as it happens. The watch measures it for the phone only while the screen is open, and nothing live is stored.

Changed

  • Health Connect rate limits. When Health Connect refuses a read, the dashboard shows a banner that counts down and then reloads the tiles it could not fill, on its own; the tiles that have data keep it and their place, and the toast is gone. A refusal that repeats waits longer each time: 1, 2, 5, then 15 minutes. On Android 13, where Health Connect is a separate app with a stricter quota, calls are spaced out, a fortnight of heart rate for the cardio load is read in a dozen calls instead of thirty, the Body Energy warm-up computes three days a pass and resumes where it stopped, and the granted permissions are asked once per half minute instead of once per tile. A refused permission check no longer reads as "nothing granted" for the rest of the session, which left a fresh install with every tile empty. The Report an issue draft carries a count of Health Connect calls by kind, so a refusal can be traced from a report. Reported on Android 13.
  • Reports, crash drafts and logs hold structure, not data. Every text the app hands out for troubleshooting was reviewed: the Apple Health, CSV, drip and medical import reports, the sync report, the crash report and the Report an issue draft. They hold counts, record types, units, reasons and masked error text, never a value, a record's time, a name, a file name or a location. The medical report groups what was refused by type and reason instead of printing the records. The crash report is kept seven days at most and deleted once it has gone into an email, a copy or a file; the Report an issue draft carries the app's log, masked, in debug and nightly builds. Copied reports are marked sensitive so Android keeps them out of the copy preview, and a transfer to a new phone leaves the reports behind. The privacy policy is dated October 23, 2026, and asks for your consent once more.
  • Apple Health workouts without their route are listed on the import card, by activity and date, instead of in the report, so each route can be brought in with the route importer.
  • A Wear OS watch off the wrist stops measuring heart rate after a minute, which is what costs the most battery, and starts again as soon as it is back on; turning the screen on or taking it off the charger restarts it too. A watch without an off-body sensor measures all the time.
  • A phone whose key changed is asked about again on the watch. A phone that reinstalled the app, or cleared its data, presents a new key, and the watch refused it until the phone was forgotten on the watch and allowed again. The watch now asks whether to allow the phone again, with the reason, and Allow replaces the old key. Pairing the watch again on the phone keeps the key, so the watch asks nothing.

Fixed

  • Two trackers, one workout. Two watches worn on one walk, or a watch and its vendor app, each file their own session, and a second app may call the outing something else, a walk on one wrist and a hike on the other. Such sessions from different sources are now folded into one whatever their type, so the activity statistics no longer add the distance and time twice. Within one app, two overlapping sessions of different types stay two records.
  • Dashboard edit mode. On a phone whose Health Connect lacks some metrics, a drag across the fixed section could swap two tiles where the grid showed an insert. Both now count the same tiles.

The app keeps the same package name and signing certificate, so this installs as a normal update.

Distribution flow:

  • GitHub release with signed APK, signed debug APK, and signed Android App Bundle assets.
  • Direct Google Play production upload from the approved production run of the release workflow.

OpenVitals v2.15.1

Choose a tag to compare

@github-actions github-actions released this 23 Oct 16:28

Released 2026-10-23.

This release lets the medical records import open a zip of FHIR files, the kind CommonHealth exports, and makes a file that cannot be imported explain why. The new report names each file and what was found in it, never the records themselves, so it can be shared to get a problem fixed without sharing your medical data.

Added

  • A report when a file cannot be imported. When the medical records import refuses a file, the screen now offers a report to copy or save. It says what stopped the import and what the file holds, a zip's files each on a line of their own: the size and kind of each, and for JSON its shape and record types, or the line and column where it stops being valid JSON. It holds no value from the file, only names, sizes and structure; check the file names before you share it. When nothing in a file can be added, the review offers the report of what was held back and why, which, like the report after an import, includes the records.

Fixed

  • A zip of FHIR files can be imported. The medical records import read a zip only as an Apple Health export or a set of CDA documents, so a zip of FHIR JSON files, as CommonHealth exports, was refused as a file OpenVitals can't read. Each JSON, NDJSON or text file in such a zip is now read as a picked FHIR file is, whatever its folders. A file in it that is not FHIR is left out and counted in the review, the report names it with what it holds, and the rest are imported. Reported in #294.

The app keeps the same package name and signing certificate, so this installs as a normal update.

Distribution flow:

  • GitHub release with signed APK, signed debug APK, and signed Android App Bundle assets.
  • Direct Google Play production upload from the approved production run of the release workflow.

OpenVitals v2.15.0

Choose a tag to compare

@github-actions github-actions released this 22 Oct 23:10

Released 2026-10-23.

This release is about typing in what no device sends. A body analysis scale without a connection gets one form for everything it shows, from weight and body fat to body water and bone mass, saved together at one time. Blood glucose and VO2 max get forms of their own, and every kind of medical record Health Connect holds can now be entered by hand, from visits and lab results to prescriptions and vital signs. Medical records are marked as a beta from this release on. A Wear OS watch's steps also become a cadence and an estimate of walking calories.

Added

  • One form for a body analysis scale. The Weight and Body fat tiles in Add entry are now one Body composition tile, for everything such a scale shows: weight, body fat, lean mass, body water, bone mass and basal metabolic rate. Fill in what the scale shows and leave the rest blank. Every value is saved to Health Connect with the same time, and a save writes all of them or none. Body water can be typed as a percentage, taken of the weight on the same form, or in kg or lb. Each value stays its own record afterwards, so the Body screens edit or delete it alone, lean mass, body water, bone mass and BMR included. Asked for in #304.
  • Blood glucose and VO2 max entry. Add entry has a tile for each. Blood glucose is typed in mmol/L or mg/dL, starting from your unit setting, and says whether it was fasting, before or after a meal, which meal, and the sample: finger prick, sensor, plasma, serum or whole blood. VO2 max says how it was measured: a lab test, the Cooper, beep or Rockport test, or the heart rate ratio. Both can be edited and deleted from their detail screens. The new tiles are in the default grid; if you rearranged your tiles, add them from the grid's edit mode.
  • Every kind of medical record can be typed in. Visits, procedures and lab results join vaccines, allergies, medications and conditions, along with prescriptions, vital signs, social history, pregnancy, doctors and their roles, clinics, places, and your own personal details. Each kind offers its statuses, and only something still ahead, such as a planned visit, can be dated after today. A doctor, clinic, lab or place is a record of its own: the form offers the ones already entered as you type the name, and saves a new name as a new record. A lab result keeps a number as a measurement and words such as "Negative" as text. Asked for in #304.
  • Medical records are a beta. The first time the records home opens, a notice says the area is still under development and that bugs may arise, and asks you to use it with care and review the data you import. It shows once.
  • Cadence and walking calories from a Wear OS watch. Each minute of steps the watch sends is also written as a cadence, and, once your weight is known from Health Connect or the body profile, as an estimate of the calories walking cost above rest. The estimate uses a cadence equation for level walking (Moore et al., 2021), so hills and stairs are not counted. A minute inside a workout Health Connect holds gets no estimate, so a recorded walk is not counted twice. Without a weight, or without Health Connect access for cadence or calories, the sync card says what is missing and offers the access; the rest of the sync goes on. Contributed by Ludwig Ettner.

Changed

  • The medical records import counts a measurement where Health Connect files it. The review step follows Health Connect's own rules for observations: pregnancy first, then social history and vital signs, then lab results. A body weight is now counted under vital signs, and an observation Health Connect would refuse is held back in the review instead of failing during the import.

Fixed

  • The sleep home-screen widget showed Health Connect's daily total, which can disagree with the sleep stages. It now shows the time asleep, as the dashboard card does.
  • Lab result flags. A lab result flagged with a bare H, L, N or A now reads High, Low, Normal or Abnormal, imported results included.

The app keeps the same package name and signing certificate, so this installs as a normal update.

Distribution flow:

  • GitHub release with signed APK, signed debug APK, and signed Android App Bundle assets.
  • Direct Google Play production upload from the approved production run of the release workflow.

OpenVitals v2.14.5

Choose a tag to compare

@github-actions github-actions released this 18 Oct 17:19

Released 2026-10-18.

This release lets a large Apple Health import run to the end. Health Connect refuses some values outright, such as a basal metabolic rate above 10,000 kcal a day, and one such sample anywhere in an export stopped the whole import with an error, however far it had got. That sample is now left out and listed in the import report, and the import carries on.

Fixed

  • An Apple Health import that stopped on one value. A single sample Health Connect cannot store stopped the import with an error. The case reported was an app that logged a whole day's basal metabolic rate as a one-hour sample, which reads as more than 35,000 kcal a day. Such a sample is now counted as failed, with the reason in the import report, and the import carries on. The same goes for any other measurement or logged meal outside what Health Connect accepts, and for a systolic blood pressure above 200 mmHg. Importing the same file again with the same categories picks up where the import stopped, and records already imported are not written twice.

The app keeps the same package name and signing certificate, so this installs as a normal update.

Distribution flow:

  • GitHub release with signed APK, signed debug APK, and signed Android App Bundle assets.
  • Google Play update to follow, once 2.13.0 has cleared Play review.

OpenVitals v2.14.4

Choose a tag to compare

@github-actions github-actions released this 18 Oct 11:14

Released 2026-10-18.

This release makes a workout's FIT export carry the whole workout. The FIT and TCX files held heart rate and the session totals and nothing else, so a ride opened in a FIT viewer showed a heart-rate line. They now carry the speed and cadence the workout screen shows, and a workout with a GPS route can be saved as a FIT with the route in it. Routes imported from a file or synced from a Garmin watch also keep every point instead of being cut to 2,000.

Added

  • A FIT file with the GPS route. A workout with a route can be saved or shared as a FIT that carries the route, the altitude and the distance covered, beside heart rate, speed and cadence: the whole recording in one file. The Export workout card now groups its formats under "With the GPS route" (GPX, KMZ, FIT) and "Without the GPS route" (TCX, CSV, FIT). The files without the route still hold no location at all.

Changed

  • Imported routes keep every point. A route file or a Garmin watch activity with more than 2,000 GPS points was cut to 2,000, evenly spaced, so a three-hour ride recorded every second kept a point about every five seconds. Every point is now kept, and the map, the splits and the route analysis use them all. A route too large for Health Connect to store in one record is still thinned until it fits. With elevation correction on, the climb of a long import is now computed from every point.

Fixed

  • FIT and TCX exports with more than heart rate. The workout export wrote only the heart-rate samples and the session totals, so FIT viewers showed nothing else. FIT and TCX now carry the speed and cadence samples the workout screen shows, and the FIT summary gives average and maximum speed and cadence. Every FIT also marks where the timer starts and stops, and the local time of the workout.

The app keeps the same package name and signing certificate, so this installs as a normal update.

Distribution flow:

  • GitHub release with signed APK, signed debug APK, and signed Android App Bundle assets.
  • Google Play update to follow, once 2.13.0 has cleared Play review.

OpenVitals v2.14.3

Choose a tag to compare

@github-actions github-actions released this 17 Oct 09:37

Released 2026-10-17.

This release brings lab results from providers that still serve the older FHIR DSTU2 format, LabCorp among them, into Health Connect: their records are converted on import, family names included, and the results held inside a diagnostic report are imported instead of being dropped with it. The activity form offers every exercise type Health Connect knows, and a FIT file's yoga, pilates or climbing session keeps its sport. The cycle screen reaches the whole recorded history, and the CSV import counts rows, records and journal days apart.

Added

  • Every exercise type on the activity form. The form listed 22 types, so a yoga session could be shown but not created. It now lists every session type Health Connect has, each with the fields that fit it: a route sport with GPS and distance, a machine or pool with a distance and no route, or a timed session with an optional heart rate strap. A FIT file names the sport too: yoga, pilates, stretching, breathwork, elliptical, stair climbing, pool and open water swimming, the racket and ball sports, hockey, scuba diving, HIIT, martial arts, dancing, rock climbing and ice skating import as themselves instead of "Other workout".
  • The whole cycle history. The cycle screen read the last eighteen months, so the history, its detail sheet and the long-term statistics stopped at about nineteen cycles however far back the records went. It now reads the whole recorded history. The history card shows the newest twelve cycles and Load 10 more reveals older ones, without rescaling the bars. The prediction still uses only the last six cycles.
  • Where the maximum heart rate comes from. The cardio load explanation gives Banister's weighting for men and for women, and says where the maximum heart rate comes from: the body profile, else the highest heart rate measured when that is high enough to count, else the age formula, Gulati's for women and Tanaka's for everyone else. Both papers are linked there and from Body Energy's sources. Contributed by Ludwig Ettner.

Changed

  • CSV import results as three tallies. "Written 754. Already present 69. Rejected 1." read like a sum that never matched the rows read. The result card now keeps three tallies apart: the rows of the file, which add up (read, imported, rejected, nothing to import); the Health Connect records written, and how many of those replaced an earlier import; and, for a drip export, the cycle journal days with an entry and how many changed on this phone. When Health Connect could not be read for a record's type before writing, the card counts those records apart and says the replaced count is a lower bound. The report file lays out the same totals.
  • The age estimate of the maximum heart rate stands on its own. With an age on the body profile and no measured maximum high enough to count, the estimate is now the age formula alone. It used to be raised to the highest heart rate measured plus 10, or the resting heart rate plus 70, whichever was higher. Cardio load and intensity minutes follow.

Fixed

  • Lab results in the older FHIR format. LabCorp still serves FHIR DSTU2, and CommonHealth passes it on unchanged. A plain FHIR file does not say its version, so those records went to Health Connect as R4 and were refused ("Expected array for field: category"). The importer now recognises a DSTU2 record by its shape and converts it to R4, encounters and locations included; a record that reads the same in both versions is left alone.
  • Family names in DSTU2 records. DSTU2 holds family names as a list and R4 as one string, so Health Connect refused LabCorp's patient records. The converter joined the list in a patient's and a practitioner's names only; it now does so in every name, a contact's included.
  • Results inside a diagnostic report. Health Connect stores the results of a report, not the report. A report was left out whole, the results it contained with it, and a file of reports said it held nothing Health Connect stores. Every result a report contains is now imported as a record of its own. It takes the report's patient, visit, time and performer where it has none, and the laboratory category when the report comes from a lab section, so Health Connect can sort LabCorp's results, whose test codes are not LOINC. A file holding only reports whose results are elsewhere now says to import the Observation files instead.
  • drip import accounts for every row. A temperature, mucus or cervix observation marked excluded in drip is listed under the rejections as "Excluded in the source app", with the values it held, instead of disappearing without a word. A day with only journal content, a day cleared in drip and a day whose mucus says "nothing" are counted, and a note with quotes in it reads as typed.
  • Translations. The last English words left in the German, French, Italian and Polish translations are translated.

The app keeps the same package name and signing certificate, so this installs as a normal update.

Distribution flow:

  • GitHub release with signed APK, signed debug APK, and signed Android App Bundle assets.
  • Google Play update to follow, once 2.13.0 has cleared Play review.

OpenVitals v2.14.2

Choose a tag to compare

@github-actions github-actions released this 14 Oct 21:41

Released 2026-10-14.

This release lets a blood pressure reading carry the pulse the monitor shows: an optional field on the blood pressure form, saved as a heart rate record at the reading's time and shown beside the reading. The Wear OS watch app starts counting steps, one minute at a time, and a sync from the phone writes them into Health Connect. And the age-predicted maximum heart rate for women now follows Gulati's formula instead of Tanaka's, which lowers it and with it the cardio load, intensity minutes, heart rate recovery and Body Energy computed for women.

Added

  • The pulse on the blood pressure form. A home monitor shows the pulse with every reading, so the blood pressure entry takes it as an optional third value, under systolic and diastolic. It is saved as a heart rate record at the time of the reading, so it appears under Heart rate, and it shows beside the reading in the blood pressure list and when the reading is opened for editing. Editing the reading moves or replaces the pulse, clearing the field removes it, and deleting the reading deletes it too. Saving a pulse needs Health Connect write access for heart rate on top of blood pressure; the app asks for it only once a pulse is typed, so a reading without one never asks. A pulse outside 20 to 300 bpm is refused.
  • Step counting on the Wear OS watch. The watch app counts steps with the watch's own step counter, one row per minute. The counter runs in the sensor hub and is read in the same batch as the heart rate, so it adds no wake-ups; a restart of the watch app neither loses nor double-counts steps. The app asks for the Physical activity permission on start. A sync from the phone writes one steps record per minute into Health Connect and reaches five minutes back, because a minute can still grow when late steps arrive; minutes without watch steps are not written, so the phone's own count can fill them. The watch's status card shows how many minutes of steps it holds, or that counting is off or the watch has no step counter. The phone only asks for steps from a watch app that offers them, so an older watch app keeps syncing as before. The watch app remains for testers and is installed by hand.

Changed

  • Maximum heart rate for women. The age-predicted maximum heart rate used Tanaka's formula for everyone. For women it now uses Gulati's, 206 - 0.88 x age, from a study of 5,437 women whose maximum Tanaka's formula overestimated; men and an unknown sex keep Tanaka's, 208 - 0.7 x age. At 40 that is 171 instead of 180 bpm. The maximum feeds cardio load, intensity minutes, heart rate recovery and Body Energy, and all four read the sex from the body profile. Body Energy is rebuilt once after this update and again whenever the sex changes.

The app keeps the same package name and signing certificate, so this installs as a normal update.

Distribution flow:

  • GitHub release with signed APK, signed debug APK, and signed Android App Bundle assets.
  • Google Play update to follow, once 2.13.0 has cleared Play review.

OpenVitals v2.14.1

Choose a tag to compare

@github-actions github-actions released this 14 Oct 18:58

Released 2026-10-14.

This release brings a cycle history kept in drip into OpenVitals: the CSV importer recognises drip's export and needs no column mapping. To hold everything drip records, the cycle journal gains the cervix as felt and a desire scale, both in the day log. A very large CSV, such as a heart rate export of a million rows, no longer stops when Health Connect runs out of quota: the import waits and carries on. Wear OS watches can sync on a schedule, and the cardio load on the Activities screens now matches the dashboard's.

Added

  • Cycle history from drip. Pick a CSV exported by the drip cycle tracker in Settings > Import & export > CSV Importer and OpenVitals recognises it: instead of a column mapping, five switches choose what to bring over. Bleeding becomes period flow and spotting in Health Connect, with bleeding you excluded in drip as spotting; morning temperatures land at their recorded time, with those excluded in drip left out; cervical mucus comes over as texture and feeling; sex as protected, unprotected or unknown, from the contraceptive drip lists. Pain and mood become symptoms, mood and energy levels, the cervix, desire and every note go into the cycle journal on the phone, laid over whatever the day already holds. Days are read in the phone's time zone. Importing the same export again replaces rather than duplicates.
  • The cervix and desire in the cycle journal. The day log's cervical mucus section gains the cervix as felt: opening (closed, medium, open), firmness (firm, soft) and position (low, medium, high). Desire joins pain, mood and energy as a fourth 1 to 5 scale. Both travel with the journal backup and the phone-to-phone sync.
  • Automatic sync for Wear OS watches. The Automatic sync card, so far Garmin-only, shows for a Wear OS watch too. A scheduled run does what a tap on Sync does: it copies the heart rate into Health Connect and writes the night's estimated sleep. Schedules survive a restart of the phone.

Changed

  • CSV import waits out Health Connect's quota. A batch Health Connect refused for quota used to end the import, which a million-row heart rate export hit every time. The import now pauses, 15 seconds the first time and up to 5 minutes later on, shows a countdown, and writes the same batch again; an accepted write resets the pauses. Only half an hour of pausing without a single accepted write stops the run, and Cancel is answered within a second even during a pause. The result and the report count the pauses and the time they took.

Fixed

  • Cardio load on the Activities screens. The Activities screen and the activity overview computed cardio load without the body profile, so a day could show one load on the dashboard and another there. They now read the age, the maximum heart rate set in the profile and the sex that picks the weighting for women, as the dashboard does.

The app keeps the same package name and signing certificate, so this installs as a normal update.

Distribution flow:

  • GitHub release with signed APK, signed debug APK, and signed Android App Bundle assets.
  • Google Play update to follow, once 2.13.0 has cleared Play review.