Connectivity / θΏιζ§
NetworkDiagnostic.checkConnection() captures a single snapshot of the current
network; onConnectivityChanged emits a fresh snapshot on every transport
change.
NetworkDiagnostic.checkConnection() ζθ·ε½εη½η»ηδΈζ¬‘εΏ«η
§οΌonConnectivityChanged
ε¨ζ―ζ¬‘δΌ θΎζΉεΌεεζΆζ¨ιζ°εΏ«η
§γ
Snapshot / εΏ«η §
final connection = await NetworkDiagnostic.checkConnection();
print('type : ${connection.type.label}'); // Wi-Fi / Mobile / Ethernet β¦
print('connected : ${connection.isConnected}');
print('ipv4 : ${connection.ipAddress}');
print('ipv6 : ${connection.ipv6Address}');
print('gateway : ${connection.gateway}');
print('ssid : ${connection.ssid}');
print('rssi : ${connection.signalStrength} dBm');
print('mac : ${connection.macAddress}');
print('vpn : ${connection.isVpn}');
print('timestamp : ${connection.timestamp}');| Field | Notes |
|---|---|
type | NetworkType (none, wifi, mobile, ethernet, vpn, bluetooth, other) |
isConnected | true unless type is none |
ipAddress / ipv6Address | Local IPv4 / IPv6 (Dart NetworkInterface) |
ipAddress / ipv6Address | Local IPv4 / IPv6 (native when available, otherwise Dart NetworkInterface) |
gateway | Native; Android, iOS, macOS and Windows via the sysctl routing table β no permission needed β null on Linux and Web |
macAddress | Native; Android and Windows only β null on iOS, macOS, Linux and Web |
ssid / signalStrength | Native; Android only (and needs a runtime permission grant) β null everywhere else |
isVpn | Native VPN detection; null-safe false when unavailable |
isReachable | Only filled when probeReachability: true |
timestamp | When the snapshot was taken |
Use
connection.type.label/connection.type.id. There is nodisplayName. θ―·δ½Ώη¨connection.type.label/connection.type.idοΌζ²‘ζdisplayNameγ
Parameters / εζ°
| Parameter | Default | Meaning |
|---|---|---|
includeNativeDetails | true | Also read SSID / gateway / MAC / VPN from the native side |
probeReachability | false | Make a real request and fill isReachable |
probeTimeout | 3s | Timeout of that reachability probe |
// Skip the native channel (cheapest call β good on hot paths).
final quick = await NetworkDiagnostic.checkConnection(includeNativeDetails: false);
// Prove the internet is actually reachable, not just that a NIC is up.
final verified = await NetworkDiagnostic.checkConnection(
probeReachability: true,
probeTimeout: const Duration(seconds: 5),
);
if (verified.isReachable == false) {
print('Interface is up but the internet is unreachable.');
}Change stream / εεηε¬
final subscription = NetworkDiagnostic.onConnectivityChanged.listen(
(info) => print('now on ${info.type.id} Β· ${info.ipAddress}'),
);
// Later:
await subscription.cancel();In a widget:
StreamBuilder<NetworkConnectionInfo>(
stream: NetworkDiagnostic.onConnectivityChanged,
builder: (context, snapshot) {
final info = snapshot.data;
if (info == null) return const Text('Checkingβ¦');
return Text('${info.type.label} Β· ${info.isConnected}');
},
)Connectivity-only: minimal example / δ» θΏιζ§οΌζε°η€ΊδΎ
If all you need is βam I online, on what transport, what IP, and react to
changesβ, you only need this page β no init() required.
ε¦ζεͺιθ¦γε¨δΈε¨η·γθ΅°δ»δΉηΆ²η»γIP ζ―ε€ε°γεζ’ζΆιη₯γοΌεͺηζ¬ι‘΅ε³ε―ββ
ζ ι init()γ
class ConnectivityScreen extends StatelessWidget {
const ConnectivityScreen({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<NetworkConnectionInfo>(
stream: NetworkDiagnostic.onConnectivityChanged,
builder: (context, snap) {
final c = snap.data;
if (c == null) {
return const Center(child: CircularProgressIndicator());
}
return ListView(
children: [
ListTile(title: const Text('Type / η±»ε'), trailing: Text(c.type.label)),
ListTile(title: const Text('Online / ε¨ηΊΏ'), trailing: Text('${c.isConnected}')),
ListTile(title: const Text('IPv4'), trailing: Text(c.ipAddress ?? 'β')),
ListTile(title: const Text('IPv6'), trailing: Text(c.ipv6Address ?? 'β')),
],
);
},
);
}
}