Android物理设备无法通过主机名解析局域网内设备IP地址的问题
解决Android物理设备局域网主机名解析失败的问题
问题概述
开发局域网主机名转IP项目时,PC端运行正常,但Android物理设备调用InetAddress.getByName("LAPJA")抛出UnknownHostException,已添加INTERNET和ACCESS_NETWORK_STATE权限。
核心原因
Android原生DNS解析依赖系统配置,多数家庭路由器的DNS不支持局域网主机名映射;而PC通常通过mDNS(如Bonjour)实现局域网主机名解析,Android对mDNS的原生支持有限,同时高版本系统有额外权限限制。
解决方案
1. 启用mDNS服务发现(推荐)
使用Android自带的NsdManager实现mDNS扫描,直接获取局域网设备的IP:
private NsdManager nsdManager; private NsdManager.DiscoveryListener discoveryListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化NsdManager nsdManager = (NsdManager) getSystemService(Context.NSD_SERVICE); initDiscoveryListener(); // 扫描局域网工作站服务(适配多数主机设备) nsdManager.discoverServices("_workstation._tcp.", NsdManager.PROTOCOL_DNS_SD, discoveryListener); } private void initDiscoveryListener() { discoveryListener = new NsdManager.DiscoveryListener() { @Override public void onDiscoveryStarted(String regType) {} @Override public void onServiceFound(NsdServiceInfo serviceInfo) { // 匹配目标主机名 if ("LAPJA".equals(serviceInfo.getServiceName())) { nsdManager.resolveService(serviceInfo, new NsdManager.ResolveListener() { @Override public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {} @Override public void onServiceResolved(NsdServiceInfo serviceInfo) { String targetIp = serviceInfo.getHost().getHostAddress(); Log.d("MainActivity", "解析到IP: " + targetIp); } }); } } @Override public void onServiceLost(NsdServiceInfo serviceInfo) {} @Override public void onDiscoveryStopped(String serviceType) {} @Override public void onStartDiscoveryFailed(String serviceType, int errorCode) {} @Override public void onStopDiscoveryFailed(String serviceType, int errorCode) {} }; } @Override protected void onDestroy() { super.onDestroy(); // 停止扫描释放资源 if (nsdManager != null && discoveryListener != null) { try { nsdManager.stopDiscovery(discoveryListener); } catch (Exception e) { e.printStackTrace(); } } }
- 额外权限配置:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> - Android 6.0+需动态申请
CHANGE_WIFI_MULTICAST_STATE权限。
2. 修正主机名格式
尝试在主机名后添加.local后缀(mDNS默认域名):
System.out.println(InetAddress.getByName("LAPJA.local").getHostAddress());
3. 补充高版本系统权限
Android 10+(API 29)及以上,局域网扫描需要位置权限:
- 清单文件添加:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> - 代码中动态申请:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1001); }
4. 排查网络环境
- 确认Android设备与目标主机在同一WiFi网络(排除热点跨网段情况)。
- 关闭Android设备的VPN、代理服务,避免干扰局域网解析。
- 在WiFi设置中手动指定路由器IP为DNS服务器。
内容的提问来源于stack exchange,提问作者Dharun
相关产品推荐
相关产品推荐

