如何在flutter应用程序中实现全局连接检查?

问题描述 投票:0回答:1

我想让我的 flutter 应用程序能够检查连接状态,并在 wifi 和移动网络关闭时提示警告。但是,我想在整个应用程序中进行全局设置,这意味着应用程序将不断侦听网络更改,直到应用程序退出。我不知道如何实现这一目标。我使用 Provider 作为我的项目的状态管理。我用来检查网络状态的包是 internet_connection_checker 和connectivity_plus。

main.dart

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:provider/provider.dart';
import 'package:test/page/error.dart';
import 'package:test/routes.dart';
import 'package:test/service/connection_manager.dart';
import 'package:test/service/firebase_service.dart';
import 'package:test/firebase_options.dart';
import 'package:test/globals.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';


Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  await FirebaseService().initNotifications();
  await FirebaseService().initFirebaseRemoteConfig();

  int mainCount = 1;

  try {
    await deviceManager.getCurrentLocation();
    print('Main() is executed for $mainCount time(s)');
    mainCount ++;
  } catch(e) {
      print('Error getting current location: $e');
      try {
        await deviceManager.getLastestLocation();
      } catch (e) {
        print('Error getting latest location: $e');
      }
    }


  FlutterError.onError = (FlutterErrorDetails details) {
    runApp(const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: AppErrorScreen(),
    ));
  };


  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ConnectionManager()),
        ChangeNotifierProvider(create: (_) => Globals()),
      ],
      child: MyApp(),
    ),
  );
}



class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: AppRoute().route,
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      debugShowCheckedModeBanner: false,
    );
  }
}

连接.dart

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:connectivity_plus/connectivity_plus.dart';

class ConnectionManager with ChangeNotifier {
  final Connectivity _connectivity = Connectivity();
  bool _isConnected = false;
  late StreamSubscription<List<ConnectivityResult>> _subscription;

  bool get isConnected => _isConnected;

  ConnectionManager() {
    _subscription = _connectivity.onConnectivityChanged.listen(_updateConnectionStatus);
    _checkInitialConnection();
  }





  Future<void> _checkInitialConnection() async {
    final List<ConnectivityResult> connectivityResult = await _connectivity.checkConnectivity();
    // await _updateConnectionStatus(connectivityResult);
  }

  Future<void> _updateConnectionStatus(List<ConnectivityResult> result) async {
    bool isConnected = false;

    if (result != ConnectivityResult.none) {
      try {
        final lookupResult = await InternetAddress.lookup('google.com');
        isConnected = lookupResult.isNotEmpty;
      } on SocketException catch (_) {
        isConnected = false;
      }
    }

    _isConnected = isConnected;
    notifyListeners();
  }

我尝试将连接检查功能放入流中,但是我是流媒体新手,我不太确定如何在应用程序中实现它。

flutter asynchronous connection flutter-state flutter-streambuilder
1个回答
0
投票

你可以这样使用它

套餐

 connectivity_plus: "5.0.0"
 internet_connection_checker:

代码

import 'package:flutter/material.dart';
import 'package:next_app_prototype/features/home/presentation/pages/home_page.dart';
import 'package:provider/provider.dart';
import 'dart:async';
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ConnectionManager()),
      ],
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Home'),
        ),
        body: Consumer<ConnectionManager>(
          builder: (context, connectionManager, child) {
            if (!connectionManager.isConnected) {
              WidgetsBinding.instance.addPostFrameCallback((_) {
                showDialog(
                  context: context,
                  builder: (context) => AlertDialog(
                    title: const Text('No Internet Connection'),
                    content: const Text('Please check your internet settings.'),
                    actions: <Widget>[
                      TextButton(
                        onPressed: () => Navigator.of(context).pop(),
                        child: const Text('OK'),
                      ),
                    ],
                  ),
                );
              });
            }

            return const HomeScreen();
          },
        ),
      ),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return const Center(child: Text('Home Page'));
  }
}

class ConnectionManager with ChangeNotifier {
  final Connectivity _connectivity = Connectivity();
  bool _isConnected = true;
  late StreamSubscription<ConnectivityResult> _subscription;
  late StreamSubscription<InternetConnectionStatus> _internetSubscription;

  bool get isConnected => _isConnected;

  ConnectionManager() {
    _subscription = _connectivity.onConnectivityChanged.listen(_updateConnectivityStatus);
    _internetSubscription = InternetConnectionChecker().onStatusChange.listen(_updateInternetStatus);
    _checkInitialConnection();
  }

  Future<void> _checkInitialConnection() async {
    final connectivityResult = await _connectivity.checkConnectivity();
    await _updateConnectivityStatus(connectivityResult);
    final internetResult = await InternetConnectionChecker().hasConnection;
    _updateInternetStatus(internetResult ? InternetConnectionStatus.connected : InternetConnectionStatus.disconnected);
  }

  Future<void> _updateConnectivityStatus(ConnectivityResult result) async {
    _isConnected = result != ConnectivityResult.none;
    if (_isConnected) {
      try {
        final lookupResult = await InternetAddress.lookup('google.com');
        _isConnected = lookupResult.isNotEmpty && lookupResult[0].rawAddress.isNotEmpty;
      } on SocketException catch (_) {
        _isConnected = false;
      }
    }
    notifyListeners();
  }

  Future<void> _updateInternetStatus(InternetConnectionStatus status) async {
    _isConnected = status == InternetConnectionStatus.connected;
    notifyListeners();
  }

  @override
  void dispose() {
    _subscription.cancel();
    _internetSubscription.cancel();
    super.dispose();
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.