Android10+热点设备通过WifiManager获取IP连接失败求助
问题解决方案
核心问题拆解
- Android 10+ 收紧了
WifiManager.getConnectionInfo()的访问权限,必须获取位置权限且开启位置服务,否则拿不到有效IP getIpAddress()是已过时的方法,返回的整数IP转换时容易出错,而且热点宿主设备用它根本拿不到自己的热点IP- 8080端口可能被系统限制,或是热点设备间的防火墙/网络策略阻断了连接
具体修复步骤
1. 替换过时的IP获取逻辑
别再用WifiManager.getConnectionInfo().getIpAddress()了,改用遍历网络接口的方式获取IP:
public static String getLocalIp() { try { for (Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces(); netInterfaces.hasMoreElements();) { NetworkInterface intf = netInterfaces.nextElement(); for (Enumeration<InetAddress> ipAddresses = intf.getInetAddresses(); ipAddresses.hasMoreElements();) { InetAddress addr = ipAddresses.nextElement(); if (!addr.isLoopbackAddress() && addr instanceof Inet4Address) { return addr.getHostAddress(); } } } } catch (SocketException e) { e.printStackTrace(); } return null; }
热点宿主设备要获取自己的热点IP,得遍历热点对应的网络接口(通常是ap0或wlan0),或者通过ConnectivityManager拿当前网络的LinkProperties:
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); Network activeNet = connMgr.getActiveNetwork(); LinkProperties linkProps = connMgr.getLinkProperties(activeNet); if (linkProps != null) { for (InetAddress addr : linkProps.getLinkAddresses()) { if (addr instanceof Inet4Address && !addr.isLoopbackAddress()) { String hotspotHostIp = addr.getHostAddress(); // 用这个IP作为热点主机的服务地址 } } }
2. 补全必要权限
在AndroidManifest.xml里加这些权限:
<!-- Android 10+必须,否则拿不到网络信息 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 基础网络权限 --> <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" /> <!-- Android 12+ 额外需要 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
还要动态申请位置权限,并且提醒用户打开设备的位置服务:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> { if (!isGranted) { // 弹窗提示用户开启位置权限,否则无法获取IP } }).launch(Manifest.permission.ACCESS_FINE_LOCATION); }
3. 端口与网络连通性排查
- 换个端口测试,比如12345,避免8080被系统占用或限制
- 热点宿主的服务器要绑定到
0.0.0.0,确保能接收所有客户端的连接:
ServerSocket server = new ServerSocket(8080); // 绑定0.0.0.0会监听所有可用网络接口,包括热点
- 关闭两台设备的防火墙、安全软件,防止连接被拦截
4. 后台运行兼容性(Android 10+)
如果应用需要在后台获取IP,还要申请后台位置权限:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
同样要动态申请这个权限,别滥用就行。
内容的提问来源于stack exchange,提问作者Arnab Paul Joy
相关产品推荐
相关产品推荐

