flutter_app_doctor 0.1.0 copy "flutter_app_doctor: ^0.1.0" to clipboard
flutter_app_doctor: ^0.1.0 copied to clipboard

Runtime health checks for Flutter apps. Diagnoses connectivity, DNS, captive portals, API reachability, latency, storage, permissions, emulators, build mode, jank and clock skew into one structured, s [...]

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_app_doctor/flutter_app_doctor.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  // Frame timings only exist while the engine is drawing, so the collector has
  // to be running before a diagnostic asks about them.
  FrameStatsCollector.instance.start();

  // Configure once at startup; every later FlutterDoctor.run() picks this up.
  FlutterDoctor.configure(
    DoctorConfig(
      endpoints: <ApiEndpoint>[
        ApiEndpoint(
          Uri.parse('https://pub.flutter-io.cn/api/packages/http'),
          name: 'pub.flutter-io.cn API',
        ),
        ApiEndpoint(
          // Deliberately broken, to show how a failure reads.
          Uri.parse('https://api.this-host-does-not-exist.invalid/health'),
          name: 'Missing backend',
          isCritical: false,
        ),
      ],
      appInfoProvider: const StaticAppInfoProvider(
        AppInfo(
          appName: 'flutter_app_doctor example',
          version: '1.0.0',
          buildNumber: '1',
          packageName: 'dev.example.flutter_app_doctor_example',
        ),
      ),
      permissionProvider: CallbackPermissionProvider(() async {
        // Real apps would query permission_handler here.
        return const <PermissionReport>[
          PermissionReport(name: 'notifications', state: PermissionState.granted),
          PermissionReport(
            name: 'camera',
            state: PermissionState.denied,
            isRequired: false,
            rationale: 'Used for scanning receipts.',
          ),
        ];
      }),
    ),
  );

  runApp(const ExampleApp());
}

/// Demo host for the diagnostics screen.
class ExampleApp extends StatelessWidget {
  /// Creates the demo app.
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) => MaterialApp(
    title: 'flutter_app_doctor',
    theme: ThemeData(
      colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF0553B1)),
    ),
    darkTheme: ThemeData(
      colorScheme: ColorScheme.fromSeed(
        seedColor: const Color(0xFF0553B1),
        brightness: Brightness.dark,
      ),
    ),
    home: const HomePage(),
  );
}

/// Landing screen with the two ways to consume a report.
class HomePage extends StatefulWidget {
  /// Creates the landing screen.
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String? _console;
  bool _running = false;

  Future<void> _printToConsole() async {
    setState(() => _running = true);
    final DoctorReport report = await FlutterDoctor.run();
    debugPrint(report.summary);
    if (!mounted) return;
    setState(() {
      _running = false;
      _console = report.summary;
    });
  }

  @override
  Widget build(BuildContext context) => Scaffold(
    appBar: AppBar(title: const Text('flutter_app_doctor')),
    body: Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          FilledButton.icon(
            onPressed: _running ? null : _printToConsole,
            icon: const Icon(Icons.terminal),
            label: const Text('Run and print the summary'),
          ),
          const SizedBox(height: 8),
          OutlinedButton.icon(
            onPressed: () => Navigator.of(context).push(
              MaterialPageRoute<void>(
                builder: (_) => const FlutterDoctorScreen(),
              ),
            ),
            icon: const Icon(Icons.health_and_safety_outlined),
            label: const Text('Open the diagnostics screen'),
          ),
          const SizedBox(height: 16),
          Expanded(
            child: Card(
              child: Padding(
                padding: const EdgeInsets.all(12),
                child: SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  child: SingleChildScrollView(
                    child: SelectableText(
                      _console ??
                          'Run a diagnostic to see the plain-text report '
                              'here.\n\nThe "Missing backend" endpoint is '
                              'intentionally unreachable so you can see how a '
                              'failure and its remedy are rendered.',
                      style: const TextStyle(
                        fontFamily: 'monospace',
                        fontFamilyFallback: <String>['Menlo', 'Courier New'],
                        fontSize: 12,
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    ),
  );
}
1
likes
150
points
82
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Runtime health checks for Flutter apps. Diagnoses connectivity, DNS, captive portals, API reachability, latency, storage, permissions, emulators, build mode, jank and clock skew into one structured, shareable report.

Repository (GitHub)
View/report issues

Topics

#diagnostics #health-check #networking #debugging #support

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_app_doctor