如何在 flutter.dart 中连续检查互联网访问,未连接

How do you check internet ACCESS continously in flutter.dart, not connection

您如何持续检查互联网访问情况?我能够显示 wifi 是否已连接或移动数据。但是,并非所有连接都可以访问互联网。

 import 'package:connectivity/connectivity.dart';

var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
  // I am connected to a mobile network.
} else if (connectivityResult == ConnectivityResult.wifi) {
  // I am connected to a wifi network.
}

这是我目前使用的代码。 我希望有人可以连续检查互联网访问情况?

你可以使用这个https://pub.dev/packages/connectivity_widget。通过安装此软件包,在您的构建函数中使用此代码。

ConnectivityWidget(
        builder: (context, isOnline) => Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text("${isOnline ? 'Online' : 'Offline'}", style: TextStyle(fontSize: 30, color: isOnline ? Colors.green : Colors.red),),
              SizedBox(height: 20,),
              Text(
                'Number of times we connected to the internet:',
              ),
              Text(
                '$_counter',
                style: Theme.of(context).textTheme.display1,
              ),
            ],
          ),
        )

connectivity package is just for discovering network connectivity. if you want to be sure about internet access you can use data_connection_checker.

您可以使用此替代方案,而无需使用任何包。每当您需要检查互联网连接时调用此函数

Future<bool> internetConnectivity() async {
try {
  final result = await InternetAddress.lookup('google.com');
  if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
    return true;
  }
} on SocketException catch (_) {
  return false;
}
return false;

}

这是构建网络感知应用程序的方法

高级概述

  1. 创建监听连接变化事件的服务,
    例如 wifi、移动和 none(离线)。此服务将发出
    NewtorkStatus(我们自定义的class)每次都变成一个流
    连接性发生变化。

  2. 为上面的 NetworkStatus 流创建消费者
    每次 NetworkStatus 更改时都会收到通知。

  3. 根据网络状态重建主屏幕以显示
    在线或离线内容。

听起来很棘手,但实际上很容易实现,我们将使用 connectivity & provider 包来拯救我们。

首先将我们的项目配置为使用上述依赖项,编辑 pubspec.yaml 以包含依赖项 -

dependencies:
  flutter:
    sdk: flutter
  connectivity: ^3.0.6
  provider: ^6.0.1

运行 $ pub get 你同步所有的依赖。

现在我们将创建我们自己的 NewtorkStatusService 此服务将使用 NetworkStatus 枚举和两个状态 OnlineOffline 来通知连接状态。

network_status_service.dart

enum NetworkStatus { 
  Online, 
  Offline 
}

现在,我们的 NetworkStatusService 将使用 Connectivity 包获取当前连接状态(wifi、移动、none),并基于此发出新的 NetworkStatus 以进行流式传输。我们最终的 NetworkStatusService 看起来像这样 -

network_status_service.dart

import 'dart:async';
import 'package:connectivity/connectivity.dart';

enum NetworkStatus { Online, Offline }

class NetworkStatusService {
  StreamController<NetworkStatus> networkStatusController =
      StreamController<NetworkStatus>();

  NetworkStatusService() {
    Connectivity().onConnectivityChanged.listen((status){
      networkStatusController.add(_getNetworkStatus(status));
    });
  }

  NetworkStatus _getNetworkStatus(ConnectivityResult status) {
    return status == ConnectivityResult.mobile || status == ConnectivityResult.wifi ? NetworkStatus.Online : NetworkStatus.Offline;
  }
}

现在我们将创建我们赢得的自定义小部件,它将 return 基于 NetworkStatus 值的 onlineChildofflineChild。这里我们将使用 provider 包来获取 NetworkStatus。我会看起来像这样 -

network_aware_widget.dart

import 'package:flutter/material.dart';
import 'package:flutter_network_aware_app/services/network_status_service.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';

class NetworkAwareWidget extends StatelessWidget {
  final Widget onlineChild;
  final Widget offlineChild;

  const NetworkAwareWidget({Key? key, required this.onlineChild, required this.offlineChild})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    NetworkStatus networkStatus = Provider.of<NetworkStatus>(context);
    if (networkStatus == NetworkStatus.Online) {
      return onlineChild;
    } else {
      _showToastMessage("Offline");
      return offlineChild;
    }
  }

  void _showToastMessage(String message){
    Fluttertoast.showToast(
        msg: message,
        toastLength: Toast.LENGTH_LONG,
        gravity: ToastGravity.BOTTOM,
        timeInSecForIosWeb: 1
    );
  }
}

这里我也是用FlutterToast来显示吐司消息(只是为了给应用增加一些交互性)

现在是有趣的部分,我们将把所有的部分放在一起,使我们的应用响应 NetworkStatus 值。我们将在 StreamProvider 小部件中使用定制的小部件。 StreamProvider 将订阅 NewtorkStatusService networkStatusController 流,并在每次 NetworkStatus 更改为 OnlineOffline 时触发对子组件的构建。这是它的样子 -

home.dart

import 'package:flutter/material.dart';
import 'package:flutter_network_aware_app/services/network_status_service.dart';
import 'package:flutter_network_aware_app/ui/components/network_aware_widget.dart';
import 'package:provider/provider.dart';

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text("Network Aware App"),
      ),
      body: StreamProvider<NetworkStatus>(
        create: (context) =>
            NetworkStatusService().networkStatusController.stream,
        child: NetworkAwareWidget(
          onlineChild: Container(
            child: Center(
              child: Text(
                "I am online",
                style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.w600),
              ),
            ),
          ),
          offlineChild: Container(
            child: Center(
              child: Text(
                "No internet connection!",
                style: TextStyle(
                    color: Colors.grey[400],
                    fontWeight: FontWeight.w600,
                    fontSize: 20.0),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

如您所见,我们将 NetworkAwareWidget 包装在 NetworkStatusStreamProvider 中。 StreamProvider 还确保在创建时它将订阅 NetworkStatusService 控制器流。

最终我们的应用程序起点 main.dart 看起来像这样 -

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_network_aware_app/ui/screens/home_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        debugShowCheckedModeBanner: false,
        theme: ThemeData.dark().copyWith(primaryColor: Colors.blue),
        home: Home());
  }
}

该应用程序将按如下方式运行 -

我希望这可以帮助您构建自己的网络感知应用程序和组件!