πŸ“‘ Connectivity

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}');
FieldNotes
typeNetworkType (none, wifi, mobile, ethernet, vpn, bluetooth, other)
isConnectedtrue unless type is none
ipAddress / ipv6AddressLocal IPv4 / IPv6 (Dart NetworkInterface)
ipAddress / ipv6AddressLocal IPv4 / IPv6 (native when available, otherwise Dart NetworkInterface)
gatewayNative; Android, iOS, macOS and Windows via the sysctl routing table β€” no permission needed β€” null on Linux and Web
macAddressNative; Android and Windows only β€” null on iOS, macOS, Linux and Web
ssid / signalStrengthNative; Android only (and needs a runtime permission grant) β€” null everywhere else
isVpnNative VPN detection; null-safe false when unavailable
isReachableOnly filled when probeReachability: true
timestampWhen the snapshot was taken

Use connection.type.label / connection.type.id. There is no displayName. 请使用 connection.type.label / connection.type.idοΌŒζ²‘ζœ‰ displayName。

Parameters / 参数

ParameterDefaultMeaning
includeNativeDetailstrueAlso read SSID / gateway / MAC / VPN from the native side
probeReachabilityfalseMake a real request and fill isReachable
probeTimeout3sTimeout 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 ?? 'β€”')),
          ],
        );
      },
    );
  }
}