在wifi下连接时如何获取手机的IP地址?
我在这里找到了一个方法,但即使我在 wifi 下,它也会返回类似 24.182.239.255 的内容,并且我期望类似 192.168.1.10 的内容。
我想要类似的东西:
if (you are under wifi)
String ip4 = getWifiIP()
else
String ip4 = getIPAddress with the method linked before
非常感谢!
在wifi下连接时如何获取手机的IP地址?
我在这里找到了一个方法,但即使我在 wifi 下,它也会返回类似 24.182.239.255 的内容,并且我期望类似 192.168.1.10 的内容。
我想要类似的东西:
if (you are under wifi)
String ip4 = getWifiIP()
else
String ip4 = getIPAddress with the method linked before
非常感谢!
所以要考虑的是Formatter.formatIpAddress(int)已被弃用:
此方法在 API 级别 12 中已弃用。使用支持 IPv4 和 IPv6 地址的 getHostAddress()。此方法不支持 IPv6 地址。
因此,使用formatIpAddress(int)
可能不是一个好的长期解决方案,尽管它会起作用。
如果您绝对希望获得 WiFi 接口的 IP 地址,这是一个潜在的解决方案:
protected String wifiIpAddress(Context context) {
WifiManager wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE);
int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
// Convert little-endian to big-endianif needed
if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
ipAddress = Integer.reverseBytes(ipAddress);
}
byte[] ipByteArray = BigInteger.valueOf(ipAddress).toByteArray();
String ipAddressString;
try {
ipAddressString = InetAddress.getByAddress(ipByteArray).getHostAddress();
} catch (UnknownHostException ex) {
Log.e("WIFIIP", "Unable to get host address.");
ipAddressString = null;
}
return ipAddressString;
}
如之前的回复所述,您需要在AndroidManifest.xml中设置以下内容:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
请注意,这只是一个示例解决方案。您应该花时间检查空值等,以确保 UX 流畅。
具有讽刺意味的是,一方面 Google 正在弃用formatIpAddress(int)
,但getIpAddress()仍然返回一个整数值。作为 int 的 IP 地址也排除了它与 IPv6 兼容。
接下来是字节顺序可能是也可能不是问题的事实。我只测试了三个设备,它们都是小端的。看起来字节序可能因硬件而异,即使我们在虚拟机中运行,这仍然是一个问题。所以为了安全起见,我在代码中添加了一个字节序检查。
getByAddress(byte[])似乎希望整数值是大端。从对此的研究看来,网络字节顺序是大端的。这是有道理的,因为像 192.168.12.22 这样的地址是一个大端数。
查看HammerNet GitHub 项目。它实现了上面的代码以及一堆健全性检查、处理 AVD 的默认值、单元测试和其他东西的能力。我不得不为我的一个应用程序实现这一点,并决定开源该库。
如果您想在连接到 Wi-Fi 时获取设备的私有 IP 地址,可以试试这个。
WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
int ip = wifiInfo.getIpAddress();
String ipAddress = Formatter.formatIpAddress(ip);
一定要添加权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
到你的清单。
这将为您提供 WiFi IPv4、IPv6 或两者。
public static Enumeration<InetAddress> getWifiInetAddresses(final Context context) {
final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
final WifiInfo wifiInfo = wifiManager.getConnectionInfo();
final String macAddress = wifiInfo.getMacAddress();
final String[] macParts = macAddress.split(":");
final byte[] macBytes = new byte[macParts.length];
for (int i = 0; i< macParts.length; i++) {
macBytes[i] = (byte)Integer.parseInt(macParts[i], 16);
}
try {
final Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
while (e.hasMoreElements()) {
final NetworkInterface networkInterface = e.nextElement();
if (Arrays.equals(networkInterface.getHardwareAddress(), macBytes)) {
return networkInterface.getInetAddresses();
}
}
} catch (SocketException e) {
Log.wtf("WIFIIP", "Unable to NetworkInterface.getNetworkInterfaces()");
}
return null;
}
@SuppressWarnings("unchecked")
public static<T extends InetAddress> T getWifiInetAddress(final Context context, final Class<T> inetClass) {
final Enumeration<InetAddress> e = getWifiInetAddresses(context);
while (e.hasMoreElements()) {
final InetAddress inetAddress = e.nextElement();
if (inetAddress.getClass() == inetClass) {
return (T)inetAddress;
}
}
return null;
}
用法:
final Inet4Address inet4Address = getWifiInetAddress(context, Inet4Address.class);
final Inet6Address inet6Address = getWifiInetAddress(context, Inet6Address.class);
不要忘记:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
找到了这个不错的答案,https://gist.github.com/stickupkid/1250733
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ipString = String.format(“%d.%d.%d.%d”, (ip & 0xff), (ip >> 8 & 0xff), (ip >> 16 & 0xff), (ip >> 24 & 0xff));
根据我的崩溃日志,似乎并非每个设备都返回 WiFi mac 地址。
这是最受欢迎的回复的更简洁版本。
final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
final ByteBuffer byteBuffer = ByteBuffer.allocate(4);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
byteBuffer.putInt(wifiInfo.getIpAddress());
try {
final InetAddress inetAddress = InetAddress.getByAddress(null, byteBuffer.array());
} catch (UnknownHostException e) {
//TODO: Return null?
}
如果 adb 安装在终端中,则执行以下操作:
Runtime.getRuntime.exec("adb", "shell", "getprop", "dhcp.wlan0.ipaddress");
添加以下权限。
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
WifiManager 在 onCreate 中初始化。
WifiManager wifiMgr = (WifiManager) getContext().getSystemService(context.WIFI_SERVICE);
使用以下功能。
public void WI-FI_IP() {
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
int ip = wifiInfo.getIpAddress();
String ipAddress = Formatter.formatIpAddress(ip);
}
以下代码来自 AOSP 设置。它获取活动链接的 ip,无论是 wifi 还是移动设备。这是最常见的方式。
/**
* Returns the default link's IP addresses, if any, taking into account IPv4 and IPv6 style
* addresses.
* @param context the application context
* @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 null
if (!iter.hasNext()) return null;
// Concatenate all available addresses, comma separated
String addresses = "";
while (iter.hasNext()) {
addresses += iter.next().getHostAddress();
if (iter.hasNext()) addresses += "\n";
}
return addresses;
}
Formatter.formatIpAddress(int) 已弃用:
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString();