如何从 Java 程序找到 Android 中的 DNS 服务器?

发布于 2024-07-08 07:37:33 字数 348 浏览 5 评论 0原文

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

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

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

谁能告诉我如何从 Java 获取这些设置,而不是使用 Runtime.exec() 生成 shell 并解析 getprop 的输出?

The java.net.InetAddress.GetByName(String host) method can only return A records so to lookup other record types I need to be able to send DNS queries using the dnsjava library.

However that normally relies on being able to parse /etc/resolv.conf or similar to find the DNS server addresses and that doesn't work on Android.

The current DNS settings on Android can apparently only be obtained from within a shell by using the getprop command.

Can anyone tell me how to get those settings from Java other than by spawning a shell with Runtime.exec() and parsing the output from getprop?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

亚希 2024-07-15 07:37:33

DNS 协议 并没有那么复杂 - 你不能只使用原始的 DNS 访问吗套接字(TCP 或 UDP)? 快速浏览一下 dnsjava doco 后,它似乎提供了低级 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 结构具有以下 IP 地址:该接口的 dns1 和 dns2。 令人惊讶的是,DNS 是 int,因此意味着仅 IP4。

The DNS protocol is not that complex - can't you just do the DNS accesses using raw sockets (either TCP or UDP)? After a quick look at the dnsjava doco it seems to provide low level DNS support to assist with this.

The other possible direction is, starting with dnsjava, to remove the dependence on /etc/resolv.conf. I would think about using getprop in your launch script to set properties in the JVM, or to create a localized resolv.conf file in your app's directory from which you can read the information needed. In other words, use getprop to inject information into the JVM instead of attempting to pull it in once the JVM is going. Surely creating a file that dnsjava can use directly should be doable.


Edit - android.net

It looks like android.net.ConnectivityManager will deliver you an array of NetworkInfo's using getAllNetworkInfo(). Then use android.net.NetworkUtils.runDhcp() to get a DhcpInfo for any given network interface - the DhcpInfo structure has the IP address for dns1 and dns2 for that interface. Surprised that the DNS's are int, therefore implying IP4 only, though.

清音悠歌 2024-07-15 07:37:33

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

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

I don't think it's possible for general case. For WiFi I found this:

WiFiManager wifi = (WifiManager) getSystemService(WIFI_SERVICE); 
DhcpInfo info = wifi.getDhcpInfo(); 
森末i 2024-07-15 07:37:33

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

To get system properties of an android system, static methods in this class (android.os.SystemProperties) can be used.
As it is not an open api, you can't compile it against the sdk. Work around is needed to do that, e.g. copy the code from AOSP to get thru the compilation.
As this class is for internal use, do this at your own risk.
Have fun.

∞觅青森が 2024-07-15 07:37:33

无论我们连接什么网络(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 {

                }

输出
输入图片此处描述

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

We should be able to find dns address being irrespective to what network (wifi or ethernet) we are connected. Here is my program.

In your AndroidManifest.xml file

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

Your code:

    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 {

                }

Output
enter image description here

You can't reach to know whether you are connected via wifi or network using WifiManager as WifiManager only deals with wifi. You have to use ConnectivityManager. I updated the code again where I merged WifiManager and ConnectivityManager to produce the result that you wanted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文