Field-reported on the alpha APK: the Samsung/Pixel row failed with
'Health permissions were denied' without ever showing a dialog, and the
Google Health connect reported the same error despite a successful OAuth.
- MainActivity now extends FlutterFragmentActivity: package:health v13
casts the host activity to androidx ComponentActivity to call
registerForActivityResult, so with plain FlutterActivity the permission
launcher stayed null and requestAuthorization() silently returned false
(HealthPlugin.kt:317 'Permission launcher not found')
- add the androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE intent-filter
required by the health package README on the main activity
- drop STEPS / READ_STEPS from the Android permission set: steps are never
fetched anywhere and the README ties step access to ACTIVITY_RECOGNITION,
which this app does not declare (weight, total + active calories, blood
glucose remain, all declared in the manifest)
- syncFromHealth treats a native permission denial as fatal only when no
cloud partner holds a grant, so a Google Health-connected sync proceeds
without the OS permission (native reads degrade to empty)
- tests: biometric controller covers native-denial + cloud-ready sync
(cloudReady fake override); suite 185/185, analyze clean, debug APK
builds (also clears the standing flutter build apk --debug gate)
- BUILD_STATE: record both fixes, check off the Android OAuth client and
connect gates, add the Health Connect on-device verification gate
Implements architecture section 4.7: IHealthGateway now exposes the Phase 3B contract (HealthProviderType, HealthConnectionStatus, HealthDataPayload, checkStatus/requestAuthorization/fetchLatestBiometrics/disconnect) with defaults derived from the existing primitives. Drivers and test fakes switch from implements to extends so Dart inherits the default bodies.
- Mobile driver: BLOOD_GLUCOSE added to iOS/Android read sets (mmol/L to mg/dL normalization); checkStatus probes hasPermissions plus Health Connect SDK readiness; samsungHealth aliases the Health Connect binding on Android (federated Samsung/Pixel feeds); disconnect clears the cached SDK probe.
- Fallback driver: safe dummy states on Windows/Web/macOS (manualFallback connected, enterpriseFhir notConfigured, native unsupportedPlatform); fetchLatestBiometrics serves the encrypted drift cache; zero platform-channel calls.
- Settings: IntegrationsController rewritten from toggles to status orchestration (refreshStatuses, connect/disconnect round-trips, denial to permissionDenied plus snackbar); SettingsScreen gains a Health Integrations card with Apple Health, Health Connect (Samsung & Pixel), and SMART on FHIR rows showing live status badges and Connect/Disconnect buttons with desktop-safe disabled states.
- Manifests: Android adds READ_BLOOD_GLUCOSE, healthdata package query, ACTION_SHOW_PERMISSIONS_RATIONALE intent, and ViewPermissionUsageActivity alias; iOS adds NSHealthShareUsageDescription and NSHealthUpdateUsageDescription.
- Tests: +13 (fallback dummy-state matrix, integrations controller transitions, Settings desktop disabled-states and mobile connect/disconnect round trip); existing fake switched to extends; navigation test updated for the renamed card title.
Verified: build_runner 191 outputs; flutter analyze clean; flutter test 148/148; flutter build windows debug succeeded.