Skip to content

Flutter SDK (unreleased source) ​

Standalone source package healthguard_flutter@0.3.0 is in the main repository at packages/sdk-flutter. It has not been published to pub.dev. Git/path dependencies can be used for testing; pin a reviewed commit for production integration.

yaml
dependencies:
  healthguard_flutter:
    git:
      url: https://github.com/Claud-Lu/healthguard.git
      ref: 0aa9fad6ee1030b12e14566eae7658aec4fb00a0
      path: packages/sdk-flutter
dart
import 'package:healthguard_flutter/healthguard_flutter.dart';
final healthGuard = HealthGuardClient(
  appKey: 'your-app-key',
  endpoint: 'https://collector.example.com/api/events/batch',
  release: 'your-app-version',
  environment: 'production',
);
await healthGuard.initialize();
dio.httpClientAdapter = HealthGuardIoHttpClientAdapter();
dio.interceptors.add(healthGuard.interceptor());
// On shutdown: healthGuard.dispose();

Apps supply configuration and attach the interceptor. Monitoring preserves the original Dio result. Intentional cancellation is not an HTTP alert; handled exceptions use captureException, and handled HTTP failures use captureHttpFailure. Choose one automatic or manual HTTP reporting path per failure.

Persistence and upload are serialized. Queues retain at most 100 events, batches at most 50, and retry defaults to 30 seconds. Original IDs, times and versions are preserved. Use flushPending() after initialization; storage, transport and networkSnapshot adapters can be injected.

The Android plugin has minimum API 21 and declares INTERNET/ACCESS_NETWORK_STATE without requesting location permission. Storage dependencies are constrained to API-21-compatible versions. validated/VPN fields are unavailable on API 21/22; API 23+ can read the default network, and API 24+ monitors default-network changes. Native network state is currently unavailable on other platforms. Dio provides total request duration; unmeasured phase timings are not fabricated.

The network diagnostics and privacy guidance applies. Builds and synthetic events do not replace offline/restart replay, network switching, VPN, old-Android installation or real alert acceptance.

Migrating an existing integration ​

Manual captureHttpFailure accepts occurredAt, eventEnvironment, deviceModel, deviceSystem and fingerprint, retaining the original failure time, device and grouping identity. networkDiagnostics and originalError are allowlisted. Passive snapshot sampledAt records collection time rather than claiming to describe the original request.

additionalContextKeys explicitly selects approved scalar business fields; credentials and nested business payloads remain excluded. Migrate legacy queues and installation identity through HealthGuardStorage: persist the new queue before clearing old storage. Custom transport must verify accepted for the complete batch before returning successfully. Use one automatic or manual reporting path per failure.

Detailed diagnostics in the SDK ​

SDK 0.2.1 exposes NetworkDiagnostics. Apps configure allowedHosts and healthPath, connecting beginRequest, endRequest and collect to their single existing HTTP reporting path. The SDK owns request IDs, start/failure snapshots, network events, in-flight counts, recent successful responses and DNS/TCP/TLS/health probes.

Basic Android snapshots and detailed events share one reference-counted observer. After migration, remove application-native observers and probe implementations; retain SDK initialization, business configuration, handled-error reporting and legacy queue adapters. Do not attach another automatic HTTP reporting interceptor to the same manually reported failure.

Active probes are disabled by default. Explicit targets require HTTPS/443; health paths reject authorities, schemes, queries and fragments. Probes send no auth or business parameters, follow no redirects and never bypass TLS. Per-host single flight, 60-second caching and stage/group timeouts bound traffic. Actual sampling times stay separate from the original request. Intentional cancellation is not an alert.

Original connection acquisition (native IO, optional) ​

HealthGuardIoHttpClientAdapter observes the existing business request's HttpClient.openUrl promise and response headers, retaining pooling, DNS, proxy and TLS behavior. Pass existing HttpClient and certificate policies through createHttpClient/validateCertificate; do not replace a required custom adapter. Valid existing X-Request-ID headers are reused; otherwise a bounded ID is generated and sent.

Acquisition may include pool wait, DNS, TCP, TLS or proxy work; unmeasured subphases stay unavailable. Headers received does not prove the response body completed. Timeout/cancellation freezes evidence, and late abandoned connections are aborted.

For an existing single manual reporting path, configure only the adapter, without another reporting interceptor. Pass error.requestOptions.extra[healthGuardRequestTraceKey] as context.requestTrace and retain context.originalError. Only allowlisted evidence is retained, excluding authentication headers, bodies, IPs and URL queries. Independent probes have separate sample times/cache flags and never supply original-request timings.

Device identity and field-service code (0.3.0 source, Unreleased) ​

The native Android plugin reads Settings.Secure.ANDROID_ID and hashes a version prefix, scope, package name, HealthGuard project appKey and normalized Android ID as NUL-separated UTF-8 with SHA-256. Only hgd1_ plus 64 lowercase hex characters reaches Dart. Raw Android ID is never logged, stored or uploaded. appKey is a namespace, not an encryption secret; the pseudonym remains personal-data-like diagnostic evidence, never an authentication credential.

Android 8+ uses android_user_signing_key_app (device/user/signing-key scope plus app/project isolation). Android 5–7 uses android_user_app_legacy; its underlying ID lacks Android 8 signing isolation and needs OEM validation. Ordinary restarts/updates should preserve the ID within scope; reinstall/data clearing must be tested on target tablets. Factory reset, user/work-profile changes, signing/package/appKey changes, or reinstall after an upgrade from pre-Android-8 can change it. OEM duplication/reset is possible. Do not claim permanent uniqueness.

Errors and failed requests share deviceId, deviceIdStatus, deviceIdSource, deviceIdScope, deviceInfo.model/system, release and sdkVersion, independently of anonymousId and sessionId. Native lookup has a 300ms deadline. Failure produces deviceIdStatus=unavailable and deviceIdReason, omits deviceId and shows Unavailable, while business and reporting continue. No random/model fallback impersonates a stable ID. Offline replay retains original identifiers and releases.

dart
await monitoring.initialize();
// Mount in the consuming app's existing settings/debug navigation:
Navigator.of(context).push(MaterialPageRoute(
  builder: (_) => HealthGuardDeviceDebugPage(client: monitoring),
));
// Or read monitoring.deviceIdentity / monitoring.deviceShortCode.

The display-only shortcode is HG- plus the first 12 uppercase hash characters. It can collide; exact grouping uses the full ID/source/scope. Email, Dashboard, AI handoff and App use the same format. Email release is from the triggering event. Deploy Collector/Dashboard first, then pin a reviewed Git revision in the App; this is not pub.dev publication, service deployment, APK distribution or device acceptance.

Record two physical same-model tablets, restart, normal upgrade, same-signature reinstall and data-clear results with Android/API, package/signature, App version and event evidence. No target tablets are currently connected; lifecycle checks remain pending. Never uninstall or clear real driver data without authorization. Automated unavailable-ID tests do not replace actual device acceptance.

References: Android ID, Android 8 changes.

Released under the MIT License.