web-dev-qa-db-ja.com

Flutterアプリでインターネットの切断を継続的に確認する

Flutterでモバイルアプリケーションを作成していて、Oracle DBに常に接続してクエリを実行するために、Node.jsで作成されたREST APIを呼び出しています。

これまで、非同期呼び出しまたはログイン操作の前にネットワーク接続を確認するために、connectivity 0.3.2を使用しました。以下の例のように:

    checkConnectivity(context) async{

  String connectionStatus;
  StreamSubscription<ConnectivityResult> _connectivitySubscription;
  final Connectivity _connectivity = new Connectivity();
  try {
    connectionStatus = (await _connectivity.checkConnectivity()).toString();
    _connectivity.onConnectivityChanged.listen((ConnectivityResult result) {
      connectionStatus = result.toString();
      //   print(connectionStatus);
    });
  } on PlatformException catch (e) {
    print(e.toString());
    connectionStatus = 'Failed to get connectivity.';
  }
  if(connectionStatus == "ConnectivityResult.none"){
    components.alertPopup(context, "No Internet Connection available" , "Please check your internet connection and try again");}

}

ユーザーがアプリケーションを使用しているすべての瞬間にインターネットの切断を継続的にチェックする(API呼び出しをまったく行わずにデータを読み取っているだけの場合でも)可能な方法があるかどうかを尋ねたいと思います。

たとえば、SnackBarを使用してオフラインであることをユーザーに通知するため。

5
nike

あなたはすでにあなたがやりたいことをするためのコードを書いています。あなたはそれをページStateまたはInheritedWidgetまたはその他の管理クラス。

final Connectivity _connectivity;
final StreamSubscription<ConnectivityResult> _subscription;

ConstructorForWhateverClassThisIs() {
    _connectivity = new Connectivity();
    _subscription = _connectivity.onConnectivityChanged.listen(onConnectivityChange);
}

void onConnectivityChange(ConnectivityResult result) {
    // TODO: Show snackbar, etc if no connectivity
}

void dispose() {
    // Always remember to cancel your subscriptions when you're done.
    subscription.cancel();
}

documentation によると、onConnectivityChangedは変更されるたびに新しい結果で更新されます。つまり、手動でクエリを実行しなくても、変更をリッスンできます。

ドキュメントの抜粋:

接続プラグインによって公開されたストリームにサブスクライブすることで、ネットワーク状態の変化をリッスンすることもできます

2
Alex Meuer

pubspec.yamlに、次の行を追加します。

flutter_offline: "^0.3.0"

インポート

import 'package:flutter_offline/flutter_offline.Dart';

例:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
          appBar: AppBar(
            title: Text("Connection status"),
          ),
          body: Builder(
            builder: (BuildContext context) {
              return OfflineBuilder(
                connectivityBuilder: (BuildContext context,
                    ConnectivityResult connectivity, Widget child) {
                  final bool connected =
                      connectivity != ConnectivityResult.none;
                  return Stack(
                    fit: StackFit.expand,
                    children: [
                      child,
                      Positioned(
                        left: 0.0,
                        right: 0.0,
                        height: 32.0,
                        child: AnimatedContainer(
                          duration: const Duration(milliseconds: 300),
                          color:
                              connected ? Colors.green : Colors.red,
                          child: connected
                              ? Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: <Widget>[
                                    Text(
                                      "YOU ARE OFFLINE",
                                      style: TextStyle(color: Colors.white),
                                    ),
                                  ],
                                )
                              : Row(
                                  mainAxisAlignment: MainAxisAlignment.center,
                                  children: <Widget>[
                                    Text(
                                      "YOU ARE OFFLINE",
                                      style: TextStyle(color: Colors.white),
                                    ),
                                    SizedBox(
                                      width: 8.0,
                                    ),
                                    SizedBox(
                                      width: 12.0,
                                      height: 12.0,
                                      child: CircularProgressIndicator(
                                        strokeWidth: 2.0,
                                        valueColor:
                                            AlwaysStoppedAnimation<Color>(
                                                Colors.white),
                                      ),
                                    ),
                                  ],
                                ),
                        ),
                      ),
                    ],
                  );
                },
                child: Center(
                  child: Text("ONLINE Or OFFLINE"),
                ),
              );
            },
          )),
    );
  }
}
0
ayoub boumzebra

私はこのパッケージを実装したばかりです https://pub.dartlang.org/packages/flutter_offline この問題を本当に簡単に処理します。

最初のステップは、パッケージのインポートですimport'package:flutter_offline/flutter_offline.Dart ';

次の例に示すように、プロジェクトに含めてライブラリの使用を開始します。

その後、ウィジェットbuild(BuildContext context){にOfflineBuilderを含めると、ユーザーがアプリをまったく操作していない(またはデータを読み取っているだけである)場合でも、ConnectivityResultからすべてのストリーム変更が読み取られ、接続ステータスが変更されます。

    @override
  Widget build(BuildContext context) {
    return OfflineBuilder(

        debounceDuration: Duration.zero,
        connectivityBuilder: (
            BuildContext context,
            ConnectivityResult connectivity,
            Widget child,
            ) {
          if (connectivity == ConnectivityResult.none) {

            return Scaffold(
              appBar: AppBar(
                title: const Text('Home'),
              ),
              body: Center(child: Text('Please check your internet connection!')),
            );
          }
          return child;
        },


        child: Scaffold(
          resizeToAvoidBottomPadding: false,
          appBar: AppBar(
              title: Text("Home")
          ),
          body: new Column(
            children: <Widget>[
              new Container(
                decoration: new BoxDecoration(color: Theme.of(context).cardColor),
                child: _buildTxtSearchBox(),
              ),
              new Divider(height: 10.0),
              new FloatingActionButton.extended(
                icon: Icon(Icons.camera_alt),
                label: Text("Barcode"),
                onPressed: _scanQR,
              ),
              new Container(
                // padding: EdgeInsets.only(left: 24.0, right: 24.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Column(
                      children: [
                        Icon(Icons.hotel, color: Colors.blueGrey[600]),
                      ],
                    ),
                    Column(
                      children: [
                        Icon(Icons.hotel, color: Colors.blue[400]),
                      ],
                    ),
                  ],
                ),

                alignment: Alignment(0.0, 0.0),
              ),
            ],
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
          drawer: MenuDrawer(),
        )
    );
  }
0
nike