Как найти DNS-серверы в Android с помощью Java-программы?
Метод java.net.InetAddress.GetByName(String host)
может возвращать только записи A
, поэтому для поиска других типов записей мне нужно иметь возможность отправлять DNS-запросы с помощью библиотеки dnsjava
.
Однако это обычно зависит от возможности синтаксического анализа /etc/resolv.conf
или аналогичного поиска адресов DNS-сервера и не работает на Android.
Текущие настройки DNS на Android, по-видимому, могут быть получены только внутри оболочки с помощью команды getprop
.
Может ли кто-нибудь сказать мне, как получить эти настройки с Java, кроме как запустив оболочку с помощью Runtime.exec()
и разобрав вывод из getprop
?
Ответы
Ответ 1
DNS-протокол не такой сложный - не можете ли вы просто выполнить DNS-доступ с использованием сырых сокетов (TCP или UDP)? После быстрого просмотра dnsjava doco он, похоже, обеспечивает поддержку DNS низкого уровня, чтобы помочь с этим.
Другим возможным направлением является, начиная с dnsjava, удалить зависимость от /etc/resolv.conf
. Я бы подумал об использовании getprop в вашем запуске script для установки свойств в JVM или для создания локализованного файла resolv.conf
в вашем каталоге приложений, из которого вы можете прочитать необходимую информацию. Другими словами, используйте getprop для ввода информации в JVM вместо того, чтобы пытаться вытащить ее, как только JVM собирается. Конечно, создание файла, который dnsjava может использовать напрямую, должно быть выполнимым.
Изменить - android.net
Похоже, что android.net.ConnectivityManager
предоставит вам массив NetworkInfo с помощью getAllNetworkInfo()
. Затем используйте android.net.NetworkUtils.runDhcp()
, чтобы получить DhcpInfo для любого заданного сетевого интерфейса. Структура DhcpInfo имеет IP-адрес для dns1 и dns2 для этого интерфейса. Удивлен, что DNS является int, поэтому подразумевает только IP4.
Ответ 2
Я не думаю, что это возможно для общего случая. Для Wi-Fi я нашел это:
WiFiManager wifi = (WifiManager) getSystemService(WIFI_SERVICE);
DhcpInfo info = wifi.getDhcpInfo();
Ответ 3
Чтобы получить системные свойства системы android, можно использовать статические методы в этом классе (android.os.SystemProperties).
Поскольку это не открытый api, вы не можете скомпилировать его с помощью sdk. Для этого необходимо работать. скопируйте код из AOSP, чтобы получить компиляцию.
Поскольку этот класс предназначен для внутреннего использования, сделайте это на свой страх и риск.
Получайте удовольствие.
Ответ 4
Мы должны иметь возможность находить адрес dns независимо от того, с какой сетью (Wi-Fi или Ethernet) мы связаны. Вот моя программа.
В файле 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 {
}
Выход
![введите описание изображения здесь]()
Вы не можете узнать, подключены ли вы через Wi-Fi или сеть, используя WifiManager
, поскольку WifiManager
работает только с Wi-Fi. Вы должны использовать ConnectivityManager
. Я снова обновил код, где я объединил WifiManager
и ConnectivityManager
, чтобы получить желаемый результат.