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を使用してオフラインであることをユーザーに通知するため。
あなたはすでにあなたがやりたいことをするためのコードを書いています。あなたはそれをページ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
は変更されるたびに新しい結果で更新されます。つまり、手動でクエリを実行しなくても、変更をリッスンできます。
ドキュメントの抜粋:
接続プラグインによって公開されたストリームにサブスクライブすることで、ネットワーク状態の変化をリッスンすることもできます
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"),
),
);
},
)),
);
}
}
私はこのパッケージを実装したばかりです 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(),
)
);
}