2013-05-24 91 views
30

Làm cách nào để nhận địa chỉ IP của điện thoại khi được kết nối dưới wifi?Nhận địa chỉ ip wifi của tôi Android

Tôi đã tìm thấy một phương thức here nhưng nó trả về một cái gì đó như 24.182.239.255 ngay cả khi tôi đang ở dưới wifi và tôi mong đợi một cái gì đó như 192.168.1.10.

Tôi muốn một cái gì đó như:

if (you are under wifi) 
    String ip4 = getWifiIP() 
else 
    String ip4 = getIPAddress with the method linked before 

Rất cám ơn!

+0

Bạn dường như mong đợi IP riêng tư. Điều này sẽ giúp. http://stackoverflow.com/questions/6064510/how-to-get-ip-address-of-the-device –

Trả lời

37

Nếu bạn muốn nhận địa chỉ IP riêng của thiết bị khi được kết nối với Wi-Fi, bạn có thể thử điều này.

WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE); 
WifiInfo wifiInfo = wifiMgr.getConnectionInfo(); 
int ip = wifiInfo.getIpAddress(); 
String ipAddress = Formatter.formatIpAddress(ip); 

Hãy chắc chắn thêm quyền

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 

đến biểu hiện của bạn.

+11

định dạngIpAddress() không được chấp nhận. Xem giải pháp của Digital Rounin bên dưới, sử dụng InetAddress.getHostAddress() để thay thế. – Emmanuel

+1

chỉ dành cho tân binh: nó phải là getSystemService (Context.WIFI_SERVICE) – 10101010

+0

Endiannes là một xem xét quan trọng, mã trên sẽ trả về IP đảo ngược trên phần cứng Little Endian. Kiểm tra câu trả lời của Rounin kỹ thuật số dưới đây để biết phương pháp đúng. Hoặc http://stackoverflow.com/questions/29937433/gethostaddress-returns-a-reversed-ip-adress cho phương thức ngắn hơn (trả về ip dưới dạng int nhưng theo đúng thứ tự). –

61

Vì vậy, một cái gì đó để xem xét là Formatter.formatIpAddress(int) đang được chấp nhận:

Phương pháp này đã được tán thành trong mức API 12. Sử dụng getHostAddress(), mà hỗ trợ cả IPv4 và địa chỉ IPv6. Phương thức này không hỗ trợ địa chỉ IPv6.

Vì vậy, việc sử dụng formatIpAddress(int) có thể không phải là giải pháp dài hạn tốt, mặc dù nó sẽ hoạt động.

Dưới đây là một giải pháp tiềm năng nếu bạn đang tìm kiếm để hoàn toàn trên có được địa chỉ IP cho giao diện WiFi:

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; 
} 

Như đã nêu trong phản ứng trước đó, bạn cần phải thiết lập như sau trong AndroidManifest.xml của bạn:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 

Lưu ý rằng đây chỉ là giải pháp mẫu. Bạn nên dành thời gian để kiểm tra các giá trị null và như vậy để đảm bảo rằng UX là trơn tru.

Điều trớ trêu là một mặt Google không dùng nữa formatIpAddress(int), nhưng vẫn có getIpAddress() vẫn trả về giá trị số nguyên. Địa chỉ IP là một int cũng quy định nó cho việc tuân thủ IPv6.

Tiếp theo là sự thật rằng sự kết thúc có thể hoặc không có thể là một vấn đề. Tôi đã chỉ thử nghiệm ba thiết bị và tất cả chúng đều là người nhỏ tuổi. Nó có vẻ như endianness có thể khác nhau tùy thuộc vào phần cứng, mặc dù chúng tôi đang chạy trong máy ảo này vẫn có thể là một vấn đề. Vì vậy, để được ở bên an toàn, tôi đã thêm một kiểm tra cuối cùng trong mã.

getByAddress(byte[]) dường như muốn giá trị số nguyên là số cuối lớn. Từ nghiên cứu này nó xuất hiện rằng thứ tự byte mạng là lớn-endian. Làm cho tinh thần vì một địa chỉ như 192.168.12.22 là một số lớn.


Kiểm tra HammerNet Dự án GitHub. Nó thực thi mã trên cùng với một loạt các kiểm tra sanity, khả năng xử lý mặc định cho AVD, kiểm tra đơn vị, và những thứ khác. Tôi đã phải thực hiện điều này cho một ứng dụng của tôi và quyết định mở nguồn thư viện.

+0

không thể nhập BigInteger trong Android Studio. tôi biết nó kỳ lạ nhưng nó đã xảy ra như vậy. – 10101010

+2

Chuyển đổi độ tin cậy thực sự rất quan trọng đối với Nexus 5 và nhiều thiết bị hơn. Cảm ơn ! – Danpe

+1

"WifiManager wifiManager = (WifiManager) context.getApplicationContext(). GetSystemService (Context.WIFI_SERVICE)" Vẫn còn tốt hơn một chút. – Denis

7

Điều này sẽ giúp bạn có được WiFi IPv4, IPv6 hoặc cả hai.

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; 
} 

Cách sử dụng:

final Inet4Address inet4Address = getWifiInetAddress(context, Inet4Address.class); 
final Inet6Address inet6Address = getWifiInetAddress(context, Inet6Address.class); 

Và đừng quên:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
1

Nếu adb được cài đặt trong thiết bị đầu cuối thì làm:

Runtime.getRuntime.exec("adb", "shell", "getprop", "dhcp.wlan0.ipaddress"); 
1

Dựa trên vụ tai nạn của tôi nhật ký, nó xuất hiện không phải mọi thiết bị đều trả về địa chỉ mac WiFi.

Đây là phiên bản sạch hơn của thư trả lời phổ biến nhất.

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? 
} 
+0

'wifiInfo' là gì, mã của bạn chưa hoàn thành – behelit

-1

Formatter.formatIpAddress (int) bị phản đối:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE); 
String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString(); 
+0

Đúng. Nó sẽ không hỗ trợ IPv6. – aclokay

0

Add Sau Permission.

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 

WifiManager initialize on onTạo.

WifiManager wifiMgr = (WifiManager) getContext().getSystemService(context.WIFI_SERVICE); 

Sử dụng chức năng sau.

public void WI-FI_IP() { 
    WifiInfo wifiInfo = wifiMgr.getConnectionInfo(); 
    int ip = wifiInfo.getIpAddress(); 
    String ipAddress = Formatter.formatIpAddress(ip); 
    } 
Các vấn đề liên quan