You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Android连接IoT Wi-Fi后HTTP请求报错errno=64求助

解决Flutter Android连接受限IoT WiFi后HTTP请求失败(errno=64)的问题

核心原因

Android系统的网络优先级策略会优先选择有互联网连接的网络,即使你通过WifiIOT切换到了IoT设备的WiFi,应用可能仍在尝试使用原有网络;另外,明文HTTP限制、未正确绑定网络也会触发这类错误。

具体解决方案

1. 绑定IoT WiFi网络到应用进程

Android 10及以上版本,系统不会自动让应用切换到无互联网的WiFi,需要手动将应用进程绑定到目标网络。

实现步骤:

  • 在Android原生代码中添加网络绑定逻辑,通过MethodChannel让Flutter调用:
    // MainActivity.kt
    import android.net.ConnectivityManager
    import android.net.Network
    import android.net.NetworkCapabilities
    import android.net.NetworkRequest
    import io.flutter.embedding.android.FlutterActivity
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.plugin.common.MethodChannel
    
    class MainActivity : FlutterActivity() {
        private val CHANNEL = "com.example.network/bind"
        private var connectivityManager: ConnectivityManager? = null
        private var networkCallback: ConnectivityManager.NetworkCallback? = null
    
        override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
            super.configureFlutterEngine(flutterEngine)
            connectivityManager = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
            MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
                if (call.method == "bindToIoTNetwork") {
                    val ssid = call.argument<String>("ssid")
                    bindToNetwork(ssid, result)
                } else {
                    result.notImplemented()
                }
            }
        }
    
        private fun bindToNetwork(ssid: String?, result: MethodChannel.Result) {
            val networkRequest = NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .build()
    
            networkCallback = object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network) {
                    val capabilities = connectivityManager?.getNetworkCapabilities(network)
                    val wifiSsid = capabilities?.ssid?.removeSurrounding("\"")
                    if (wifiSsid == ssid) {
                        connectivityManager?.bindProcessToNetwork(network)
                        result.success("Successfully bound to network $ssid")
                        connectivityManager?.unregisterNetworkCallback(this)
                    }
                }
            }
            connectivityManager?.registerNetworkCallback(networkRequest, networkCallback!!)
        }
    
        override fun onDestroy() {
            super.onDestroy()
            networkCallback?.let { connectivityManager?.unregisterNetworkCallback(it) }
        }
    }
    
  • 在Flutter中调用该方法(连接WiFi成功后):
    import 'package:flutter/services.dart';
    
    final MethodChannel _channel = MethodChannel('com.example.network/bind');
    
    Future<void> bindToIoTNetwork(String ssid) async {
      try {
        await _channel.invokeMethod('bindToIoTNetwork', {'ssid': ssid});
      } on PlatformException catch (e) {
        print("Failed to bind network: ${e.message}");
      }
    }
    

2. 允许明文HTTP请求

IoT设备通常使用HTTP明文传输,Android 9+默认禁止,需配置允许:

  • 快速配置:在AndroidManifest.xml的<application>标签中添加:
    android:usesCleartextTraffic="true"
    
  • 更安全的针对性配置:创建res/xml/network_security_config.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config cleartextTrafficPermitted="true">
            <domain includeSubdomains="true">192.168.33.1</domain>
        </domain-config>
    </network-security-config>
    
    然后在AndroidManifest.xml的<application>标签引用:
    android:networkSecurityConfig="@xml/network_security_config"
    

3. 确保权限齐全

在AndroidManifest.xml中添加必要权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 12+ 扫描WiFi需要 -->

4. 等待网络完全就绪

WifiIOT的连接成功回调仅表示WiFi关联完成,需等待DHCP获取IP后再发起请求:

  • 使用connectivity_plus插件监听网络状态,确认已连接到目标WiFi:
    import 'package:connectivity_plus/connectivity_plus.dart';
    
    Future<void> waitForNetworkReady() async {
      final connectivityResult = await Connectivity().checkConnectivity();
      if (connectivityResult == ConnectivityResult.wifi) {
        // 等待DHCP分配IP,可根据实际情况调整时长
        await Future.delayed(const Duration(seconds: 2));
      }
    }
    

5. 检查Dio客户端配置

确保Dio未设置代理,避免请求走错误的网络:

import 'package:dio/dio.dart';

final dio = Dio(BaseOptions(
  baseUrl: "http://192.168.33.1",
  proxy: null, // 明确禁用代理
));

// 发起请求
var result = await dio.get("/rpc/Webhook.ListSupported");

内容的提问来源于stack exchange,提问作者Nicolas HOAREAU

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:52:46