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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:13:13