Repository navigation
Permissions
OpenVitals asks for permissions by purpose. The local app removes inherited network permissions during manifest merge and should not ship app-level INTERNET, network-state, or Wi-Fi-state permissions.
This page mirrors the current permission surface declared in app/src/main/AndroidManifest.xml.
Used to show records in the dashboard, metric detail screens, readiness, statistics, achievements, and insights:
android.permission.health.READ_STEPSandroid.permission.health.READ_DISTANCEandroid.permission.health.READ_EXERCISEandroid.permission.health.READ_EXERCISE_ROUTESandroid.permission.health.READ_SLEEPandroid.permission.health.READ_HEART_RATEandroid.permission.health.READ_RESTING_HEART_RATEandroid.permission.health.READ_HEART_RATE_VARIABILITYandroid.permission.health.READ_WEIGHTandroid.permission.health.READ_HEIGHTandroid.permission.health.READ_BODY_FATandroid.permission.health.READ_LEAN_BODY_MASSandroid.permission.health.READ_BASAL_METABOLIC_RATEandroid.permission.health.READ_BONE_MASSandroid.permission.health.READ_BODY_WATER_MASSandroid.permission.health.READ_FLOORS_CLIMBEDandroid.permission.health.READ_ACTIVE_CALORIES_BURNEDandroid.permission.health.READ_ELEVATION_GAINEDandroid.permission.health.READ_WHEELCHAIR_PUSHESandroid.permission.health.READ_TOTAL_CALORIES_BURNEDandroid.permission.health.READ_SPEEDandroid.permission.health.READ_POWERandroid.permission.health.READ_STEPS_CADENCEandroid.permission.health.READ_CYCLING_PEDALING_CADENCEandroid.permission.health.READ_PLANNED_EXERCISEandroid.permission.health.READ_HYDRATIONandroid.permission.health.READ_NUTRITIONandroid.permission.health.READ_MINDFULNESSandroid.permission.health.READ_BLOOD_PRESSUREandroid.permission.health.READ_OXYGEN_SATURATIONandroid.permission.health.READ_RESPIRATORY_RATEandroid.permission.health.READ_BODY_TEMPERATUREandroid.permission.health.READ_VO2_MAXandroid.permission.health.READ_BLOOD_GLUCOSEandroid.permission.health.READ_SKIN_TEMPERATURE
Cycle data is sensitive. These permissions are grouped separately in onboarding and Settings so users can grant or skip them explicitly:
android.permission.health.READ_MENSTRUATIONandroid.permission.health.READ_OVULATION_TESTandroid.permission.health.READ_CERVICAL_MUCUSandroid.permission.health.READ_BASAL_BODY_TEMPERATUREandroid.permission.health.READ_INTERMENSTRUAL_BLEEDINGandroid.permission.health.READ_SEXUAL_ACTIVITY
Declared for explicit save, edit/delete, recording, and supported import workflows. Write permissions should be requested only when a workflow needs them:
android.permission.health.WRITE_STEPSandroid.permission.health.WRITE_EXERCISEandroid.permission.health.WRITE_SLEEPandroid.permission.health.WRITE_EXERCISE_ROUTEandroid.permission.health.WRITE_DISTANCEandroid.permission.health.WRITE_ELEVATION_GAINEDandroid.permission.health.WRITE_ACTIVE_CALORIES_BURNEDandroid.permission.health.WRITE_TOTAL_CALORIES_BURNEDandroid.permission.health.WRITE_HEART_RATEandroid.permission.health.WRITE_RESTING_HEART_RATEandroid.permission.health.WRITE_HEART_RATE_VARIABILITYandroid.permission.health.WRITE_WEIGHTandroid.permission.health.WRITE_HEIGHTandroid.permission.health.WRITE_BODY_FATandroid.permission.health.WRITE_LEAN_BODY_MASSandroid.permission.health.WRITE_BASAL_METABOLIC_RATEandroid.permission.health.WRITE_BONE_MASSandroid.permission.health.WRITE_BODY_WATER_MASSandroid.permission.health.WRITE_FLOORS_CLIMBEDandroid.permission.health.WRITE_WHEELCHAIR_PUSHESandroid.permission.health.WRITE_SPEEDandroid.permission.health.WRITE_POWERandroid.permission.health.WRITE_STEPS_CADENCEandroid.permission.health.WRITE_CYCLING_PEDALING_CADENCEandroid.permission.health.WRITE_PLANNED_EXERCISEandroid.permission.health.WRITE_HYDRATIONandroid.permission.health.WRITE_NUTRITIONandroid.permission.health.WRITE_MINDFULNESSandroid.permission.health.WRITE_BLOOD_PRESSUREandroid.permission.health.WRITE_OXYGEN_SATURATIONandroid.permission.health.WRITE_RESPIRATORY_RATEandroid.permission.health.WRITE_BODY_TEMPERATUREandroid.permission.health.WRITE_VO2_MAXandroid.permission.health.WRITE_BLOOD_GLUCOSEandroid.permission.health.WRITE_MENSTRUATIONandroid.permission.health.WRITE_OVULATION_TESTandroid.permission.health.WRITE_CERVICAL_MUCUSandroid.permission.health.WRITE_BASAL_BODY_TEMPERATUREandroid.permission.health.WRITE_INTERMENSTRUAL_BLEEDINGandroid.permission.health.WRITE_SEXUAL_ACTIVITY
Health Connect medical records are FHIR resources: vaccines, allergies, conditions, lab results, and more. These permissions exist only on Android 14 and newer with the Health Connect medical records feature. Elsewhere OpenVitals never asks for them.
They are asked for in one request, only inside the medical records area, and never together with fitness permissions. Health Connect then shows its own medical records permission screen. A screen with some categories declined still works: it lists the records OpenVitals wrote, which write access lets it read. Health Connect stops asking for a permission the user refused twice. The records home then leaves it out of the re-ask, and offers Health Connect's settings when nothing else is left.
android.permission.health.READ_MEDICAL_DATA_VACCINESandroid.permission.health.READ_MEDICAL_DATA_ALLERGIES_INTOLERANCESandroid.permission.health.READ_MEDICAL_DATA_CONDITIONSandroid.permission.health.READ_MEDICAL_DATA_MEDICATIONSandroid.permission.health.READ_MEDICAL_DATA_LABORATORY_RESULTSandroid.permission.health.READ_MEDICAL_DATA_PROCEDURESandroid.permission.health.READ_MEDICAL_DATA_VISITSandroid.permission.health.READ_MEDICAL_DATA_VITAL_SIGNSandroid.permission.health.READ_MEDICAL_DATA_PREGNANCYandroid.permission.health.READ_MEDICAL_DATA_SOCIAL_HISTORYandroid.permission.health.READ_MEDICAL_DATA_PERSONAL_DETAILSandroid.permission.health.READ_MEDICAL_DATA_PRACTITIONER_DETAILS-
android.permission.health.WRITE_MEDICAL_DATA: used only for imports, manual entries, and phone-to-phone sync the user starts.
-
android.permission.health.READ_HEALTH_DATA_HISTORY: used when the user grants access to older records. -
android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND: used where supported for background Health Connect reads.
-
android.permission.ACCESS_FINE_LOCATION: required for reliable GPS activity recording. -
android.permission.ACCESS_COARSE_LOCATION: declared with location access for Android permission compatibility. -
android.permission.ACTIVITY_RECOGNITION: used where Android requires activity-recognition access for recorded activity workflows. -
android.permission.HIGH_SAMPLING_RATE_SENSORS: supports higher-rate sensor access for activity recording on devices that expose it. -
android.permission.POST_NOTIFICATIONS: used for activity recording, Apple Health import progress, phone-to-phone sync progress, and reminder notifications. -
android.permission.RECEIVE_BOOT_COMPLETED: used to reschedule reminders after reboot or app update. -
android.permission.CAMERA: used only to scan the QR code of a SMART Health Card in the medical records import. Requested when the user taps Scan a QR code. Each frame is read on the device and dropped; none is saved or sent. A photo of the code can be picked instead.
OpenVitals uses Bluetooth for two separate things: Bluetooth LE sensors during activity recording and phone-to-phone sync. They share the same nearby-device permissions:
-
android.permission.BLUETOOTH_SCAN: used to find Bluetooth LE sensors and to discover a nearby phone for sync. It is declared withneverForLocation, so OpenVitals does not derive location from Bluetooth scan results. -
android.permission.BLUETOOTH_CONNECT: used to connect to a Bluetooth LE sensor and to open the sync connection to another phone. -
android.permission.BLUETOOTH_ADVERTISE: used only by phone-to-phone sync on Android 12 and newer, so this phone can be made discoverable while the other phone looks for it. -
android.permission.BLUETOOTHandandroid.permission.BLUETOOTH_ADMIN: declared for Android 11 and older only (maxSdkVersion="30"). Those versions need them to scan, to connect and to list bonded devices. There, a Bluetooth LE scan also needs the location permission, so the add-sensor flow asks for it.
Nearby-device Bluetooth permissions never add internet access. Phone-to-phone sync uses Bluetooth Classic (RFCOMM) rather than Wi-Fi precisely because any Wi-Fi or TCP socket on Android would require the INTERNET permission, which OpenVitals does not declare.
-
android.permission.FOREGROUND_SERVICE: base permission for foreground work. -
android.permission.WAKE_LOCK: keeps the CPU running during an activity recording while the screen is off, so timers and sensors keep time. Held while recording and during a timed rest, released on pause and at the end. Android grants it without a prompt. -
android.permission.FOREGROUND_SERVICE_LOCATION: marks the recording service as location-based. -
android.permission.FOREGROUND_SERVICE_HEALTH: marks the recording service as health-related where Android supports it. -
android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE: used by activity recording with connected Bluetooth LE sensors and by the keep-alive service that runs during a phone-to-phone sync transfer. -
android.permission.FOREGROUND_SERVICE_DATA_SYNC: marks long-running Apple Health imports as user-started data sync work.
OpenVitals treats the foreground slot as effectively single. Activity recording, an Apple Health import, and a phone-to-phone sync contend for it, so the app does not run them at the same time. No service starts without a tap.
The manifest explicitly removes inherited network permissions from dependencies:
android.permission.INTERNETandroid.permission.ACCESS_NETWORK_STATEandroid.permission.ACCESS_WIFI_STATE
The android.hardware.wifi feature is removed the same way.
These removals preserve the local app's internet-free boundary, and every device feature added since is built to keep it: phone-to-phone sync runs over Bluetooth Classic. Watches and scales are handled by the separate OpenWatch app, so OpenVitals declares no companion-device, notification-access or calendar permission. It deliberately does not request QUERY_ALL_PACKAGES.
OpenVitals can receive GPX, KML, KMZ, FIT, and TCX files through Android open/share intents so imported activities can be reviewed and saved to Health Connect. It can also import PMTiles and Mapsforge map packs from Settings for offline activity maps.
The app uses a local file provider to export route files, such as GPX or KMZ, to other apps.
Generated from docs/app/permissions.md. Edit it there; changes made here are overwritten.
This wiki mirrors the Markdown in Hale-MTU/OpenVitals on every push to main.
Features
- Features
- Achievements
- Activity And Training Plans
- Activity Metrics
- Apple Health Import
- Beverage Logging And Caffeine
- Bluetooth LE Sensors
- Body Energy
- Body Metrics
- CoMaps Navigation Context
- CSV Import
- Cycle Tracking
- Daily Readiness
- Elevation Correction
- Feature Map
- FIT Files Import
- Food Logging
- GPX/KML/KMZ/TCX Route Import
- Health Connect Metrics Dashboard
- Health Report Export
- Heart And Vitals
- Heart Rate Recovery
- Home Screen Widgets
- Hydration
- Manual Entry Of Metrics
- Medical Records
- Metric Detail Customization
- Mindfulness
- Non Health Connect Metrics Dashboard
- Nutrition
- Offline Maps Support
- Onboarding And Permissions
- Preloaded Beverage Nutrition Reference
- Privacy, Support, And Diagnostics
- Recording Of Activity
- Reminders
- Settings And Preferences
- Sleep Score And Recovery
- Sleep Tracking
- Statistics
- Sync With Another Phone
How-to
App
- App Guide
- FAQ
- Getting Started
- Health Connect
- Install
- Local And Connected Editions
- Permissions
- Privacy
- Screenshots
- Support
Reference
- Design Reference
- Reference
- Design Guidelines for Offline & Sync
- OpenVitals UI Notes
- Reference: Data Capture
- Reference: Data Display
- Reference: Health Connect Matchmaking
- Reference: Health Connect Onboarding
- Reference: Health Connect Permissions
- Reference: Health Connect UX
- Reference: Promoting Health Connect
Engineering
- Code Analysis
- Engineering
- Flutter ↔ Kotlin test-parity matrix
- apple-health-import
- Architecture
- body-cycle-recovery
- Design system conformance
- Development
- Feature Playbook
- Flutter -> Kotlin test parity: domain/data/core/contract/state/navigation/di/bootstrap/l10n/widget_test
- Flutter → Kotlin test-parity matrix: features section
- Flutter → Kotlin test-parity matrix: ui / goldens / integration / fixtures
- Flutter-to-Kotlin test-parity matrix — dashboard + devicesync
- manual-entry
- Translations
Proposals
- Proposals
- Activity Start Flow Analysis
- Activity Start Flow Simplification Proposals
- Caffeine Detail And Future Sleep Insights
- Cycle Tracking: Design and Status
- Medical Records Through Health Connect
- Medical Records: What Is Left
Releases
- OpenVitals 2.16.0
- OpenVitals 2.15.2
- OpenVitals 2.15.1
- OpenVitals 2.15.0
- OpenVitals 2.14.5
- OpenVitals 2.14.4
- OpenVitals 2.14.3
- OpenVitals 2.14.2
- OpenVitals 2.14.1
- OpenVitals 2.14.0
- OpenVitals 2.13.0
- OpenVitals 2.12.0
- OpenVitals 2.11.2
- OpenVitals 2.11.1
- OpenVitals 2.11.0
- OpenVitals 2.10.1
- OpenVitals 2.10.0
- OpenVitals 2.9.1
- OpenVitals 2.9.0
- OpenVitals 2.8.0
- OpenVitals 2.7.3
- OpenVitals 2.7.2
- OpenVitals 2.7.1
- OpenVitals 2.7.0
- OpenVitals 2.6.6
- OpenVitals 2.6.5
- OpenVitals 2.6.4
- OpenVitals 2.6.3
- OpenVitals 2.6.2
- OpenVitals 2.6.1
- OpenVitals 2.6.0
- OpenVitals 2.5.0
- OpenVitals 2.4.1
- OpenVitals 2.4.0
- OpenVitals 2.3.2
- OpenVitals 2.3.1
- OpenVitals 2.3.0
- OpenVitals 2.2.8
- OpenVitals 2.2.7
- OpenVitals 2.2.6
- OpenVitals 2.2.5
- OpenVitals 2.2.4
- OpenVitals 2.2.3
- OpenVitals 2.2.2
- OpenVitals 2.2.1
- OpenVitals 2.2.0
- OpenVitals 2.1.0
- OpenVitals 2.0.4
- OpenVitals 2.0.3
- OpenVitals 2.0.2
- OpenVitals 2.0.1
- OpenVitals 1.9.0
- OpenVitals 1.8.0
- OpenVitals 1.7.7
- OpenVitals 1.7.6
- OpenVitals 1.7.5
- OpenVitals 1.7.4
- OpenVitals 1.7.3
- OpenVitals 1.7.2
- OpenVitals 1.7.1
- OpenVitals 1.7.0
- OpenVitals 1.6.3
- OpenVitals 1.6.2
- OpenVitals 1.6.1
- OpenVitals 1.6.0
- OpenVitals 1.5.1
- OpenVitals 1.5.0
Project