.NET Maui实现指定WiFi网络跨平台连接与断开方案问询
.NET Maui 自动连接WiFi热点并恢复原网络方案
由于.NET Maui没有内置跨平台WiFi连接API,我们需要通过**依赖服务(Dependency Service)**结合Android/iOS平台原生API实现需求,核心分为「定义共享接口」「Android平台实现」「iOS平台实现」「Maui共享层调用」四个部分。
1. 定义共享接口
在Maui项目的共享代码中创建IWiFiConnector接口,统一跨平台调用契约:
public interface IWiFiConnector { // 获取当前连接的WiFi SSID(用于保存原网络) Task<string> GetCurrentConnectedSsid(); // 连接指定热点(SSID+密码,支持未保存的热点) Task<bool> ConnectToHotspot(string ssid, string password, bool isWpa2 = true); // 断开当前热点并恢复到之前连接的网络 Task<bool> DisconnectAndRestore(string originalSsid); }
2. Android平台实现
权限配置
在Platforms/Android/AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- Android 12+ 新增权限 --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" />
运行时需要动态申请ACCESS_FINE_LOCATION和NEARBY_WIFI_DEVICES(Android 12+)权限,可通过Maui的Permissions类实现。
原生代码实现
创建Platforms/Android/WiFiConnector.cs:
[assembly: Dependency(typeof(WiFiConnector))] namespace YourAppName.Platforms.Android; public class WiFiConnector : IWiFiConnector { private readonly WifiManager _wifiManager; public WiFiConnector() { _wifiManager = (WifiManager)Android.App.Application.Context.GetSystemService(Context.WifiService); } public async Task<string> GetCurrentConnectedSsid() { var info = _wifiManager.ConnectionInfo; var ssid = info.Ssid?.Replace("\"", ""); // 移除SSID的引号 return await Task.FromResult(string.IsNullOrEmpty(ssid) ? null : ssid); } public async Task<bool> ConnectToHotspot(string ssid, string password, bool isWpa2 = true) { if (Build.VERSION.SdkInt >= BuildVersionCodes.Q) { // Android 10+ 用WifiNetworkSpecifier var specifier = new WifiNetworkSpecifier.Builder() .SetSsid(ssid) .SetWpa2Passphrase(password) .Build(); var request = new NetworkRequest.Builder() .AddTransportType(TransportType.Wifi) .SetNetworkSpecifier(specifier) .Build(); var callback = new NetworkCallback(); _wifiManager.RequestNetwork(request, callback); // 等待连接结果(实际可通过回调优化) await Task.Delay(3000); var currentSsid = await GetCurrentConnectedSsid(); return currentSsid == ssid; } else { // Android 9及以下 用WifiConfiguration var config = new WifiConfiguration { Ssid = $"\"{ssid}\"", PreSharedKey = $"\"{password}\"" }; if (isWpa2) { config.AllowedKeyManagement.Set((int)KeyManagementType.WpaPsk); } var networkId = _wifiManager.AddNetwork(config); _wifiManager.Disconnect(); var connected = _wifiManager.EnableNetwork(networkId, true); _wifiManager.Reconnect(); await Task.Delay(2000); return connected && await GetCurrentConnectedSsid() == ssid; } } public async Task<bool> DisconnectAndRestore(string originalSsid) { if (string.IsNullOrEmpty(originalSsid)) return false; _wifiManager.Disconnect(); // 查找原网络的配置并启用 var configs = _wifiManager.ConfiguredNetworks; var originalConfig = configs?.FirstOrDefault(c => c.Ssid.Replace("\"", "") == originalSsid); if (originalConfig != null) { _wifiManager.EnableNetwork(originalConfig.NetworkId, true); _wifiManager.Reconnect(); await Task.Delay(2000); return await GetCurrentConnectedSsid() == originalSsid; } // 如果原网络未保存,让系统自动选择可用网络 _wifiManager.StartScan(); await Task.Delay(1000); return true; } // 辅助类:监听网络连接状态 private class NetworkCallback : ConnectivityManager.NetworkCallback { public bool IsConnected { get; private set; } public override void OnAvailable(Network network) { base.OnAvailable(network); IsConnected = true; } public override void OnLost(Network network) { base.OnLost(network); IsConnected = false; } } }
3. iOS平台实现
Entitlement配置
iOS对WiFi操作有严格权限限制,需在Platforms/iOS/YourAppName.Entitlements.plist中添加两项权限:
<key>com.apple.developer.networking.wifi-info</key> <true/> <key>com.apple.developer.networking.HotspotConfiguration</key> <true/>
注意:这两项权限需要在Apple开发者后台的App ID中开启,否则提交审核会失败。
原生代码实现
创建Platforms/iOS/WiFiConnector.cs:
[assembly: Dependency(typeof(WiFiConnector))] namespace YourAppName.Platforms.iOS; public class WiFiConnector : IWiFiConnector { private readonly NEHotspotConfigurationManager _configManager; public WiFiConnector() { _configManager = NEHotspotConfigurationManager.SharedManager; } public async Task<string> GetCurrentConnectedSsid() { var info = CNCopyCurrentNetworkInfo(null); if (info == null) return null; var ssid = info.ObjectForKey(new NSString("SSID")) as NSString; return await Task.FromResult(ssid?.ToString()); } public async Task<bool> ConnectToHotspot(string ssid, string password, bool isWpa2 = true) { var config = new NEHotspotConfiguration(ssid, password, isWpa2) { JoinOnce = false // 设置为true则连接后不保存到系统WiFi列表,false则保存 }; var tcs = new TaskCompletionSource<bool>(); _configManager.ApplyConfiguration(config, error => { if (error != null) { tcs.SetResult(false); return; } tcs.SetResult(true); }); var success = await tcs.Task; if (success) { await Task.Delay(2000); var currentSsid = await GetCurrentConnectedSsid(); success = currentSsid == ssid; } return success; } public async Task<bool> DisconnectAndRestore(string originalSsid) { // 移除当前热点配置,系统会自动切换到之前的可用网络 _configManager.RemoveConfiguration(originalSsid); await Task.Delay(2000); var currentSsid = await GetCurrentConnectedSsid(); return currentSsid == originalSsid; } // 导入iOS私有API [DllImport("/System/Library/Frameworks/CoreWLAN.framework/CoreWLAN")] private static extern IntPtr CNCopyCurrentNetworkInfo(IntPtr interfaceName); }
4. Maui共享层调用
在UI层(比如MainPage.xaml.cs)中调用依赖服务,实现按钮逻辑:
private string _originalSsid; private async void ConnectButton_Clicked(object sender, EventArgs e) { // 先获取当前连接的网络 _originalSsid = await DependencyService.Get<IWiFiConnector>().GetCurrentConnectedSsid(); // 显示加载状态 ConnectButton.IsEnabled = false; LoadingIndicator.IsRunning = true; // 连接目标热点 var success = await DependencyService.Get<IWiFiConnector>().ConnectToHotspot("TargetSSID", "TargetPassword"); // 更新UI LoadingIndicator.IsRunning = false; ConnectButton.IsEnabled = true; if (success) { StatusLabel.Text = "已连接到目标热点"; DisconnectButton.IsEnabled = true; } else { StatusLabel.Text = "连接失败"; } } private async void DisconnectButton_Clicked(object sender, EventArgs e) { DisconnectButton.IsEnabled = false; LoadingIndicator.IsRunning = true; var success = await DependencyService.Get<IWiFiConnector>().DisconnectAndRestore(_originalSsid); LoadingIndicator.IsRunning = false; DisconnectButton.IsEnabled = false; StatusLabel.Text = success ? "已恢复到原网络" : "恢复失败"; }
关键注意事项
- Android:不同版本API差异大,需做好兼容;动态权限必须提前申请,否则无法扫描或连接WiFi。
- iOS:必须配置正确的Entitlements,且需通过Apple开发者后台开启权限;
JoinOnce参数根据需求选择,若不需要保存热点到系统列表则设为true。 - 跨平台测试:需在真实设备上测试,模拟器可能不支持WiFi操作。
内容的提问来源于stack exchange,提问作者Oli
相关产品推荐
相关产品推荐

