239 lines
6.1 KiB
Dart
239 lines
6.1 KiB
Dart
import 'package:flutter/foundation.dart';
|
||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||
import 'dart:async';
|
||
|
||
/// 网络连接状态枚举
|
||
enum NetworkStatus {
|
||
connected,
|
||
disconnected,
|
||
unknown,
|
||
}
|
||
|
||
/// 网络连接类型枚举
|
||
enum NetworkType {
|
||
wifi,
|
||
mobile,
|
||
ethernet,
|
||
none,
|
||
unknown,
|
||
}
|
||
|
||
/// 网络状态数据模型
|
||
class NetworkState {
|
||
final NetworkStatus status;
|
||
final NetworkType type;
|
||
final bool isOnline;
|
||
final DateTime lastChecked;
|
||
|
||
const NetworkState({
|
||
required this.status,
|
||
required this.type,
|
||
required this.isOnline,
|
||
required this.lastChecked,
|
||
});
|
||
|
||
NetworkState copyWith({
|
||
NetworkStatus? status,
|
||
NetworkType? type,
|
||
bool? isOnline,
|
||
DateTime? lastChecked,
|
||
}) {
|
||
return NetworkState(
|
||
status: status ?? this.status,
|
||
type: type ?? this.type,
|
||
isOnline: isOnline ?? this.isOnline,
|
||
lastChecked: lastChecked ?? this.lastChecked,
|
||
);
|
||
}
|
||
|
||
@override
|
||
bool operator ==(Object other) {
|
||
if (identical(this, other)) return true;
|
||
return other is NetworkState &&
|
||
other.status == status &&
|
||
other.type == type &&
|
||
other.isOnline == isOnline;
|
||
}
|
||
|
||
@override
|
||
int get hashCode {
|
||
return status.hashCode ^
|
||
type.hashCode ^
|
||
isOnline.hashCode;
|
||
}
|
||
|
||
@override
|
||
String toString() {
|
||
return 'NetworkState(status: $status, type: $type, isOnline: $isOnline, lastChecked: $lastChecked)';
|
||
}
|
||
}
|
||
|
||
/// 网络状态管理Provider
|
||
class NetworkNotifier extends StateNotifier<NetworkState> {
|
||
late StreamSubscription<List<ConnectivityResult>> _connectivitySubscription;
|
||
final Connectivity _connectivity = Connectivity();
|
||
|
||
NetworkNotifier()
|
||
: super(NetworkState(
|
||
status: NetworkStatus.unknown,
|
||
type: NetworkType.unknown,
|
||
isOnline: false,
|
||
lastChecked: DateTime.now(),
|
||
)) {
|
||
_initializeNetworkMonitoring();
|
||
}
|
||
|
||
/// 初始化网络监控
|
||
void _initializeNetworkMonitoring() {
|
||
// 监听网络连接状态变化
|
||
_connectivitySubscription = _connectivity.onConnectivityChanged.listen(
|
||
(List<ConnectivityResult> results) {
|
||
_updateNetworkState(results);
|
||
},
|
||
);
|
||
|
||
// 初始检查网络状态
|
||
_checkInitialConnectivity();
|
||
}
|
||
|
||
/// 检查初始网络连接状态
|
||
Future<void> _checkInitialConnectivity() async {
|
||
try {
|
||
final results = await _connectivity.checkConnectivity();
|
||
_updateNetworkState(results);
|
||
} catch (e) {
|
||
if (kDebugMode) {
|
||
print('Error checking initial connectivity: $e');
|
||
}
|
||
state = state.copyWith(
|
||
status: NetworkStatus.unknown,
|
||
type: NetworkType.unknown,
|
||
isOnline: false,
|
||
lastChecked: DateTime.now(),
|
||
);
|
||
}
|
||
}
|
||
|
||
/// 更新网络状态
|
||
void _updateNetworkState(List<ConnectivityResult> results) {
|
||
// 取第一个有效的连接结果,如果列表为空则认为无连接
|
||
final result = results.isNotEmpty ? results.first : ConnectivityResult.none;
|
||
final networkType = _mapConnectivityResultToNetworkType(result);
|
||
final isOnline = result != ConnectivityResult.none;
|
||
final status = isOnline ? NetworkStatus.connected : NetworkStatus.disconnected;
|
||
|
||
state = NetworkState(
|
||
status: status,
|
||
type: networkType,
|
||
isOnline: isOnline,
|
||
lastChecked: DateTime.now(),
|
||
);
|
||
|
||
if (kDebugMode) {
|
||
print('Network state updated: $state');
|
||
}
|
||
}
|
||
|
||
/// 将ConnectivityResult映射到NetworkType
|
||
NetworkType _mapConnectivityResultToNetworkType(ConnectivityResult result) {
|
||
switch (result) {
|
||
case ConnectivityResult.wifi:
|
||
return NetworkType.wifi;
|
||
case ConnectivityResult.mobile:
|
||
return NetworkType.mobile;
|
||
case ConnectivityResult.ethernet:
|
||
return NetworkType.ethernet;
|
||
case ConnectivityResult.none:
|
||
return NetworkType.none;
|
||
default:
|
||
return NetworkType.unknown;
|
||
}
|
||
}
|
||
|
||
/// 手动刷新网络状态
|
||
Future<void> refreshNetworkStatus() async {
|
||
try {
|
||
final results = await _connectivity.checkConnectivity();
|
||
_updateNetworkState(results);
|
||
} catch (e) {
|
||
if (kDebugMode) {
|
||
print('Error refreshing network status: $e');
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 检查是否有网络连接
|
||
bool get isConnected => state.isOnline;
|
||
|
||
/// 检查是否为WiFi连接
|
||
bool get isWifiConnected => state.type == NetworkType.wifi && state.isOnline;
|
||
|
||
/// 检查是否为移动网络连接
|
||
bool get isMobileConnected => state.type == NetworkType.mobile && state.isOnline;
|
||
|
||
/// 获取网络类型描述
|
||
String get networkTypeDescription {
|
||
switch (state.type) {
|
||
case NetworkType.wifi:
|
||
return 'WiFi';
|
||
case NetworkType.mobile:
|
||
return '移动网络';
|
||
case NetworkType.ethernet:
|
||
return '以太网';
|
||
case NetworkType.none:
|
||
return '无网络';
|
||
case NetworkType.unknown:
|
||
return '未知网络';
|
||
}
|
||
}
|
||
|
||
/// 获取网络状态描述
|
||
String get statusDescription {
|
||
switch (state.status) {
|
||
case NetworkStatus.connected:
|
||
return '已连接';
|
||
case NetworkStatus.disconnected:
|
||
return '已断开';
|
||
case NetworkStatus.unknown:
|
||
return '未知状态';
|
||
}
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_connectivitySubscription.cancel();
|
||
super.dispose();
|
||
}
|
||
}
|
||
|
||
/// 网络状态Provider
|
||
final networkProvider = StateNotifierProvider<NetworkNotifier, NetworkState>(
|
||
(ref) => NetworkNotifier(),
|
||
);
|
||
|
||
/// 网络连接状态Provider(简化版)
|
||
final isConnectedProvider = Provider<bool>(
|
||
(ref) => ref.watch(networkProvider).isOnline,
|
||
);
|
||
|
||
/// 网络类型Provider
|
||
final networkTypeProvider = Provider<NetworkType>(
|
||
(ref) => ref.watch(networkProvider).type,
|
||
);
|
||
|
||
/// WiFi连接状态Provider
|
||
final isWifiConnectedProvider = Provider<bool>(
|
||
(ref) {
|
||
final networkState = ref.watch(networkProvider);
|
||
return networkState.type == NetworkType.wifi && networkState.isOnline;
|
||
},
|
||
);
|
||
|
||
/// 移动网络连接状态Provider
|
||
final isMobileConnectedProvider = Provider<bool>(
|
||
(ref) {
|
||
final networkState = ref.watch(networkProvider);
|
||
return networkState.type == NetworkType.mobile && networkState.isOnline;
|
||
},
|
||
); |