如何从 Java 程序中找到 Android 中的 DNS 服务器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/249916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I find the DNS servers in Android from a Java program?
提问by Alnitak
The java.net.InetAddress.GetByName(String host)method can only return Arecords so to lookup other record types I need to be able to send DNS queries using the dnsjavalibrary.
该java.net.InetAddress.GetByName(String host)方法只能返回A记录,以便查找我需要能够使用dnsjava库发送 DNS 查询的其他记录类型。
However that normally relies on being able to parse /etc/resolv.confor similar to find the DNS server addresses and that doesn't work on Android.
然而,这通常依赖于能够解析/etc/resolv.conf或类似的方式来查找 DNS 服务器地址,而这在 Android 上不起作用。
The current DNS settings on Android can apparently only be obtained from within a shell by using the getpropcommand.
Android 上的当前 DNS 设置显然只能通过使用getprop命令从 shell 中获取。
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?
谁能告诉我怎么去从Java这些设置除了通过生成一个外壳,Runtime.exec()并从解析输出getprop?
采纳答案by Lawrence Dol
The DNS protocolis 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.
该DNS协议不是那么复杂-你不能只做使用原始套接字(TCP或UDP)的DNS访问?快速浏览一下 dnsjava doco 后,它似乎提供了低级别的 DNS 支持来帮助解决这个问题。
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.conffile 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.
另一个可能的方向是,从 dnsjava 开始,消除对/etc/resolv.conf. 我会考虑在您的启动脚本中使用 getprop 来设置 JVM 中的属性,或者resolv.conf在您的应用程序目录中创建一个本地化文件,您可以从中读取所需的信息。换句话说,使用 getprop 将信息注入 JVM,而不是在 JVM 运行后尝试将其拉入。当然,创建一个 dnsjava 可以直接使用的文件应该是可行的。
Edit - android.net
编辑 - android.net
It looks like android.net.ConnectivityManagerwill deliver you an array of NetworkInfo's using getAllNetworkInfo(). Then use android.net.NetworkUtils.runDhcp()to get a DhcpInfofor any given network interface - the DhcpInfostructure has the IP address for dns1 and dns2 for that interface. Surprised that the DNS's are int, therefore implying IP4 only, though.
看起来android.net.ConnectivityManager会使用getAllNetworkInfo(). 然后用android.net.NetworkUtils.runDhcp()获得DhcpInfo对于任何给定的网络界面- DhcpInfo结构具有IP地址,DNS1和DNS2该接口。令人惊讶的是,DNS 是 int,因此仅暗示 IP4。
回答by Eugene Yokota
I don't think it's possible for general case. For WiFi I found this:
我认为一般情况下这是不可能的。对于 WiFi,我发现了这个:
WiFiManager wifi = (WifiManager) getSystemService(WIFI_SERVICE);
DhcpInfo info = wifi.getDhcpInfo();
回答by accuya
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.
要获取 android 系统的系统属性,可以使用此类 ( android.os.SystemProperties) 中的静态方法。由于它不是一个开放的 api,因此您无法针对 sdk 对其进行编译。需要解决方法来做到这一点,例如从 AOSP 复制代码以通过编译。由于此类是供内部使用的,因此请自行承担风险。玩得开心。
回答by Uddhav Gautam
We should be able to find dns address being irrespective to what network (wifi or ethernet) we are connected. Here is my program.
无论我们连接的是什么网络(wifi 或以太网),我们都应该能够找到 dns 地址。这是我的程序。
In your AndroidManifest.xmlfile
在您的AndroidManifest.xml文件中
<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 {
}
You can't reach to know whether you are connected via wifi or network using WifiManageras WifiManageronly deals with wifi. You have to use ConnectivityManager. I updated the code again where I merged WifiManagerand ConnectivityManagerto produce the result that you wanted.
您无法知道您是通过 wifi 连接还是使用网络连接,WifiManager因为WifiManager仅使用 wifi 处理。你必须使用ConnectivityManager. 我再次更新了我合并的代码WifiManager并ConnectivityManager产生了你想要的结果。


