Android 获取网卡ip地址(静态+动态模式,解决有时获取到 IPV6 地址问题)
网上搜索得到的大多方法都是如下方式
添加权限
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
常规方法
public static String getIpAddress() {try {NetworkInterface networkInterface;InetAddress inetAddress;for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {networkInterface = en.nextElement();for (Enumeration<InetAddress> enumIpAddr = networkInterface.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {inetAddress = enumIpAddr.nextElement();Log.i("LogUtil","inetAddress=="+inetAddress.getHostAddress());if (!inetAddress.isLoopbackAddress() && !inetAddress.isLinkLocalAddress()) {return inetAddress.getHostAddress();}}}return "";} catch (SocketException ex) {ex.printStackTrace();return "";}
}
此种方法经我测试当以太网设置为 静态IP 时,获取的 ip 地址为 ipv6 格式(当然首先你的路由器首先得支持 ipv6),这样对于我们常见的 ping 包操作或者上报服务器 ip地址就会有错误的风险
通过翻看 Android 系统的 Setting 源码,查看系统是如何获取 ip 地址的
packages\apps\MtkSettings\src\com\android\settings\deviceinfo\Status.java
packages\apps\MtkSettings\src\com\android\settings\Utils.java
private void setIpAddressStatus() {String ipAddress = Utils.getDefaultIpAddresses(this.mCM);if (ipAddress != null) {mIpAddress.setSummary(ipAddress);} else {mIpAddress.setSummary(mUnavailable);}}/*** Returns the default link's IP addresses, if any, taking into account IPv4 and IPv6 style* addresses.* @return the formatted and newline-separated IP addresses, or null if none.*/public static String getDefaultIpAddresses(ConnectivityManager cm) {LinkProperties prop = cm.getActiveLinkProperties();return formatIpAddresses(prop);}private static String formatIpAddresses(LinkProperties prop) {if (prop == null) return null;Iterator<InetAddress> iter = prop.getAllAddresses().iterator();// If there are no entries, return nullif (!iter.hasNext()) return null;// Concatenate all available addresses, comma separatedString addresses = "";while (iter.hasNext()) {addresses += iter.next().getHostAddress();if (iter.hasNext()) addresses += "\n";}return addresses;}
直接将上述的两个静态方法复制出来你会发现 getActiveLinkProperties() 和 getAllAddresses() 方法都是 hide 的,我们可以通过反射来调用他们
修改后
public static String getDefaultIpAddresses(Context mContext) {ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);//LinkProperties prop = cm.getActiveLinkProperties();LinkProperties prop = null;String addres = null;try {prop = (LinkProperties) cm.getClass().getMethod("getActiveLinkProperties").invoke(cm);addres = formatIpAddresses(prop);}catch (Exception e) {e.printStackTrace();}return addres;}private static String formatIpAddresses(LinkProperties prop) throws NoSuchMethodException,InvocationTargetException, IllegalAccessException {if (prop == null) return null;//Iterator iter = prop.getAllAddresses().iterator(); List<InetAddress> addressesList = (List<InetAddress>) prop.getClass().getMethod("getAllAddresses").invoke(prop);Iterator<InetAddress> iter = addressesList.iterator();// If there are no entries, return nullif (!iter.hasNext()) return null;// Concatenate all available addresses, comma separatedString addresses = "";while (iter.hasNext()) {InetAddress inetAddress = iter.next();//过滤 ipv6 的地址if (inetAddress instanceof Inet4Address && !inetAddress.isLoopbackAddress() && !inetAddress.isLinkLocalAddress()) {LogUtils.d("inetAddress=="+inetAddress.getHostAddress());addresses = inetAddress.getHostAddress();break;}//addresses += iter.next().getHostAddress();//if (iter.hasNext()) addresses += "\n";}LogUtils.d("addresses=="+addresses);return addresses;}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
