一、Android应用获取有线网络DNS列表
/** * 获取DNS列表 */ private List<String> getDnsList() { List<String> dnsList = new ArrayList(); if (this.mIEthernetManager == null) { return dnsList; } else { try { IpConfiguration config = this.mIEthernetManager.getConfiguration(); Iterator i$; InetAddress nameserver; if (config.getIpAssignment() == IpConfiguration.IpAssignment.STATIC) { int state = this.mIEthernetManager.getState(); if (state != 3) { return dnsList; } i$ = config.getStaticIpConfiguration().dnsServers.iterator(); while(i$.hasNext()) { nameserver = (InetAddress)i$.next(); dnsList.add(nameserver.getHostAddress()); } } else { if (this.mIConnectivityManager == null) { return dnsList; } LinkProperties lp = this.mIConnectivityManager.getLinkPropertiesForType(9); if (lp == null) { return dnsList; } i$ = lp.getDnsServers().iterator(); while(i$.hasNext()) { nameserver = (InetAddress)i$.next(); dnsList.add(nameserver.getHostAddress()); } } return dnsList; } catch (NullPointerException | RemoteException var6) { var6.printStackTrace(); return dnsList; } } }
二、framework层修改DNS列表IPv4/IPv6的优先级
路由器同时支持IPv4和IPv6的情况下,Android系统会优先使用IPv6,DNS信息中可能会显示类似 "fe80:xx:xx"的格式,这就是IPv6的DNS格式。
修改DNS列表,把IPv4放在首位返回:
frameworksasecorejavaandroid etLinkProperties.java
/** * Returns all the {@link InetAddress} for DNS servers on this link. * * @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on * this link. */ public List<InetAddress> getDnsServers() { //Sheldon add patch begin //在列表中查找到有IPv4 DNS且不在首位时,将其交换到首位,应用层获取到的列表第一个便是IPv4的DNS int index = 0; boolean isSortDone = true; for (InetAddress addr : mDnses) { boolean isIpv4 = (addr instanceof Inet4Address); if(index==0 && !isIpv4){ isSortDone = false; } //Log.v(TAG, "Get DNS : " + addr.getHostAddress() + ", isIpv4 : " + isIpv4 + ", index = " + index); if(!isSortDone && isIpv4){ Collections.swap(mDnses,0,index); Log.d(TAG, "Put ipv4 dns first ~"); isSortDone = true; } index++; } //Sheldon add patch end return Collections.unmodifiableList(mDnses); }
另外,如果想默认关闭IPv6只使用IPv4可以进行如下修改:
frameworksopt etethernetjavacomandroidserverethernetEthernetNetworkFactory.java
public void startIpManager() { ...... } else { provisioningConfiguration = mIpManager.buildProvisioningConfiguration() .withProvisioningTimeoutMs(0) .withoutIPv6() //默认配置去除IPv6 .build(); } mIpManager.startProvisioning(provisioningConfiguration); }