flutter_mobile_diagnostics 0.2.0 copy "flutter_mobile_diagnostics: ^0.2.0" to clipboard
flutter_mobile_diagnostics: ^0.2.0 copied to clipboard

Device health diagnostics for Flutter. Identity plus battery, memory, storage, network, Bluetooth, security, and performance with JSON reports.

flutter_mobile_diagnostics #

pub package likes pub points license

A Flutter plugin that answers: how healthy is this device right now, and what context should I attach to a support ticket or crash report?

Collect a typed snapshot of device identity plus seven runtime domains (battery, memory, storage, network, Bluetooth, security, performance). Each domain is scored as healthy, warning, critical, or unknown. The full report serializes to JSON for Sentry, Crashlytics, or your backend.

Android iOS

Screenshots #

Example app overview on Android and iOS:

Android iOS
Device Diagnostics overview on Android Device Diagnostics overview on iOS

Features #

  • One call, full picturegetFullReport() returns identity + all health domains + overall score.
  • Granular getters — fetch only battery, memory, storage, and so on.
  • Actionable status — Dart scoring (HealthInterpreter), not raw maps in the public API.
  • JSON-ready — every model has toJson(); toJsonReport() is a one-liner for crash SDKs.
  • Configurable — thresholds and opt-in security / reachability via DiagnosticsOptions.
  • Live updateswatch() polls battery, memory, and network (v1; EventChannel planned later).
  • Fail gracefully — missing permissions or APIs become unknown, not a crash.
  • Android & iOS — native collectors on both mobile platforms.

This package is not a full APM suite, Bluetooth pairing library, or tamper-proof fraud detector.


Install #

dependencies:
  flutter_mobile_diagnostics: ^0.2.0
flutter pub get

Quick start #

import 'package:flutter_mobile_diagnostics/flutter_mobile_diagnostics.dart';

final diagnostics = MobileDiagnostics();

final report = await diagnostics.getFullReport();

debugPrint('${report.overallStatus}  ${report.overallScore}');
debugPrint('Battery ${report.battery.levelPercent}%');
debugPrint('${report.device.manufacturer} ${report.device.model}');

Attach to a crash or support payload:

final json = await diagnostics.toJsonReport();
// crashReporter.setContext('device_health', json);

API overview #

MobileDiagnostics is cheap to construct. Native work starts on the first method call.

Method Returns Notes
deviceIdentity DeviceIdentity Cached for the session (model, OS, app version, screen, locale, …).
getFullReport({options}) DiagnosticsReport Parallel collection + scoring. Short TTL cache (default 5s).
getBatteryHealth() BatteryHealth Level, charging state, power-save.
getMemoryHealth() MemoryHealth Total / used RAM, low-memory flag.
getStorageHealth() StorageHealth Total / free disk.
getNetworkHealth({options}) NetworkHealth Connectivity type, metered, optional reachability.
getBluetoothHealth() BluetoothHealth Adapter supported / on / unauthorized.
getSecurityHealth({options}) SecurityHealth Lock, emulator, optional root/jailbreak.
getPerformanceHealth() PerformanceHealth Thermal state, CPU cores.
watch({domains, interval}) Stream<DiagnosticsSnapshot> Polls battery / memory / network.
toJsonReport({options}) Map<String, dynamic> getFullReport() + toJson().
MobileDiagnostics.clearCache() void Tests or force refresh.

Options #

final report = await diagnostics.getFullReport(
  options: const DiagnosticsOptions(
    includeSecurityChecks: true,
    includeRootJailbreakCheck: false, // advisory; off by default
    includeNetworkReachability: false, // extra latency; off by default
    batteryWarningThresholdPercent: 20,
    batteryCriticalThresholdPercent: 10,
    memoryWarningThresholdPercent: 75,
    memoryCriticalThresholdPercent: 90,
    storageWarningThresholdMb: 500,
    storageCriticalThresholdMb: 100,
    collectionTimeout: Duration(seconds: 5),
  ),
);

Single domain #

final memory = await diagnostics.getMemoryHealth();
final perf = await diagnostics.getPerformanceHealth();

final canRunHeavyWork = memory.status != HealthStatus.critical &&
    perf.thermalState != ThermalState.critical;

Watch battery / network #

final sub = diagnostics
    .watch(domains: DiagnosticsDomain.watchableDefaults)
    .listen((snapshot) {
  final level = snapshot.battery?.levelPercent;
  if (level != null && level < 15) {
    // show low-battery UX
  }
});
// later: await sub.cancel();

Health scoring #

Native code returns raw metrics. Scoring is pure Dart so Android and iOS share the same rules.

Domain Healthy Warning Critical
Battery ≥ warning % and not in saver Below warning or power saver Below critical and discharging
Memory Below warning % used Warning–critical band ≥ critical % or OS low-memory
Storage Free above warning MB Between critical and warning Free below critical MB
Network Connected Metered-only or reachability failed No connectivity
Bluetooth Supported and on Supported but off — (unknown if unsupported / no permission)
Security Lock set, not emulator, dev mode off No lock, emulator, or dev mode Rooted / jailbroken if that check is enabled
Performance Thermal nominal Fair / serious Thermal critical

Overall status = worst domain (critical > warning > unknown > healthy).

Overall score (0–100) = weighted average: memory 25%, storage 20%, battery 15%, performance 15%, network 10%, security 10%, Bluetooth 5%.

unknown contributes a neutral 50 to the score.


Example JSON #

{
  "device": {
    "manufacturer": "Samsung",
    "model": "SM-G991B",
    "os_name": "Android",
    "os_version": "14",
    "app_version": "1.2.3",
    "is_physical_device": true
  },
  "battery": {
    "level_percent": 78,
    "state": "discharging",
    "status": "healthy"
  },
  "overall_status": "healthy",
  "overall_score": 92.5,
  "collected_at": "2026-08-29T17:14:00.000Z",
  "collection_duration_ms": 145
}

Permissions #

Android #

Merged from the plugin manifest (host apps inherit these):

Permission Why
ACCESS_NETWORK_STATE Network type / metered
ACCESS_WIFI_STATE Wi-Fi related signals
BLUETOOTH (API ≤ 30) Adapter state
BLUETOOTH_CONNECT (API 31+) Adapter state without scanning
INTERNET Optional reachability probe

If Bluetooth permission is denied, Bluetooth health is unauthorized / unknown. The rest of the report still succeeds.

iOS #

Add a usage string if you query Bluetooth adapter state (the example app already does):

<key>NSBluetoothAlwaysUsageDescription</key>
<string>Bluetooth adapter state is used only for device health diagnostics. The app does not scan or pair accessories.</string>

Platform notes #

Supported on Android and iOS only. Availability varies by OS version; missing APIs are omitted or marked unknown.

  • Android / iOS — battery, memory, storage, network, Bluetooth adapter state, security heuristics, thermal / performance signals.
  • Root / jailbreak checks are heuristic and opt-in. They are not forensic or anti-tamper guarantees.

Example app #

The example/ project is a full demo:

  1. Overview — overall score, domain grid, and live monitor
  2. Domain detail — per-getter drill-down
  3. Livewatch()
  4. ReporttoJsonReport()
  5. SettingsDiagnosticsOptions toggles
cd example
flutter run

Testing #

flutter test --coverage
cd example && flutter test --coverage

Swap the platform in unit tests:

FlutterMobileDiagnosticsPlatform.instance = MyFakePlatform();
MobileDiagnostics.clearCache();

Further reading #


License #

BSD 3-Clause. See LICENSE.

0
likes
160
points
183
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Device health diagnostics for Flutter. Identity plus battery, memory, storage, network, Bluetooth, security, and performance with JSON reports.

Repository (GitHub)
View/report issues

Topics

#diagnostics #device #battery #crash-reporting #health

License

BSD-3-Clause (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on flutter_mobile_diagnostics

Packages that implement flutter_mobile_diagnostics