【问题标题】:How do I find the DNS servers in Android from a Java program?如何从 Java 程序中找到 Android 中的 DNS 服务器?
【发布时间】:2010-09-19 23:29:39
【问题描述】:

java.net.InetAddress.GetByName(String host) 方法只能返回 A 记录,因此要查找其他记录类型,我需要能够使用 dnsjava 库发送 DNS 查询。

但是,这通常依赖于能够解析 /etc/resolv.conf 或类似的东西来查找 DNS 服务器地址,而这在 Android 上不起作用。

Android 上的当前 DNS 设置显然只能通过使用 getprop 命令从 shell 中获取。

除了使用Runtime.exec() 生成一个shell 并解析getprop 的输出之外,谁能告诉我如何从Java 中获取这些设置?

【问题讨论】:

  • AFAIK 没有其他方法可以像 Runtime.exec("getprop") 那样获取 WiFi 移动连接的当前 DNS 服务器。

标签: android dns java


【解决方案1】:

DNS protocol 没有那么复杂 - 你不能只使用原始套接字(TCP 或 UDP)进行 DNS 访问吗?快速浏览一下 dnsjava 文档后,它似乎提供了低级 DNS 支持来帮助解决这个问题。

另一个可能的方向是,从 dnsjava 开始,去除对/etc/resolv.conf 的依赖。我会考虑在您的启动脚本中使用 getprop 来设置 JVM 中的属性,或者在您的应用程序目录中创建一个本地化的 resolv.conf 文件,您可以从中读取所需的信息。换句话说,使用 getprop 将信息注入 JVM,而不是在 JVM 运行后尝试将其拉入。当然创建一个 dnsjava 可以直接使用的文件应该是可行的。


编辑 - android.net

看起来android.net.ConnectivityManager 将使用getAllNetworkInfo() 为您提供一系列NetworkInfo。然后使用android.net.NetworkUtils.runDhcp() 获取任何给定网络接口的 DhcpInfo - DhcpInfo 结构具有该接口的 dns1 和 dns2 的 IP 地址。令人惊讶的是 DNS 是 int,因此仅暗示 IP4。

【讨论】:

  • 这意味着在手机的启动序列中插入一些东西,这是普通应用程序无法做到的,并且也无法应对随着不同访问方式来来去去的DNS服务器的变化。
【解决方案2】:

我认为一般情况下不可能。对于 WiFi,我发现了这个:

WiFiManager wifi = (WifiManager) getSystemService(WIFI_SERVICE); 
DhcpInfo info = wifi.getDhcpInfo(); 

【讨论】:

    【解决方案3】:

    要获取android系统的系统属性,可以使用这个类(android.os.SystemProperties)中的静态方法。 因为它不是一个开放的 api,所以你不能针对 sdk 编译它。需要解决这个问题,例如从 AOSP 复制代码以通过编译。 由于本课程供内部使用,因此请自行承担风险。 玩得开心。

    【讨论】:

      【解决方案4】:

      我们应该能够找到与我们连接的网络(wifi 或以太网)无关的 dns 地址。这是我的程序。

      在您的 AndroidManifest.xml 文件中

      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
      

      您的代码:

          ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Service.CONNECTIVITY_SERVICE);
      
                      /* you can print your active network via using below */
                      Log.i("myNetworkType: ", connectivityManager.getActiveNetworkInfo().getTypeName());
                      WifiManager wifiManager= (WifiManager) getApplicationContext().getSystemService(getApplicationContext().WIFI_SERVICE);
      
      
                      Log.i("routes ", connectivityManager.getLinkProperties(connectivityManager.getActiveNetwork()).getRoutes().toString());
                      Log.i("domains ", connectivityManager.getLinkProperties(connectivityManager.getActiveNetwork()).getDomains().toString());
                      Log.i("ip address ", connectivityManager.getLinkProperties(connectivityManager.getActiveNetwork()).getLinkAddresses().toString());
                      Log.i("dns address ", connectivityManager.getLinkProperties(connectivityManager.getActiveNetwork()).getDnsServers().toString());
      
      
      
                      if(connectivityManager.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI) {
                          Log.i("myType ", "wifi");
                          DhcpInfo d =wifiManager.getDhcpInfo();
                          Log.i("info", d.toString()+"");
                      }
                      else if(connectivityManager.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_ETHERNET) {
      /* there is no EthernetManager class, there is only WifiManager. so, I used this below trick to get my IP range, dns, gateway address etc */
      
                          Log.i("myType ", "Ethernet");
                          Log.i("routes ", connectivityManager.getLinkProperties(connectivityManager.getActiveNetwork()).getRoutes().toString());
                          Log.i("domains ", connectivityManager.getLinkProperties(connectivityManager.getActiveNetwork()).getDomains().toString());
                          Log.i("ip address ", connectivityManager.getLinkProperties(connectivityManager.getActiveNetwork()).getLinkAddresses().toString());
                          Log.i("dns address ", connectivityManager.getLinkProperties(connectivityManager.getActiveNetwork()).getDnsServers().toString());
      
                      }
                      else {
      
                      }
      

      输出

      您无法知道您是通过 wifi 连接还是使用 WifiManager 的网络连接,因为 WifiManager 仅处理 wifi。你必须使用ConnectivityManager。我再次更新了代码,合并WifiManagerConnectivityManager 以产生您想要的结果。

      【讨论】:

        猜你喜欢
        • 2011-09-10
        • 2010-09-08
        • 1970-01-01
        • 2013-08-10
        • 2011-05-12
        • 1970-01-01
        • 2023-03-14
        • 2017-08-07
        • 1970-01-01
        相关资源
        最近更新 更多