2013-05-24 15 views
30

Come posso ottenere l'indirizzo IP del mio telefono quando è connesso sotto wifi?Ottieni il mio indirizzo IP wifi Android

Ho trovato un metodo here ma restituisce qualcosa come 24.182.239.255 anche se sono in wifi e mi aspetto qualcosa come 192.168.1.10.

mi piacerebbe qualcosa di simile:

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

Molte grazie!

+0

Sembra che ti aspetti l'IP privato. Questo aiuterà. http://stackoverflow.com/questions/6064510/how-to-get-ip-ad-ress-of-the-device –

risposta

37

Se si desidera ottenere l'indirizzo IP privato del dispositivo quando è connesso al Wi-Fi, è possibile provare questo.

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

Assicurarsi di aggiungere l'autorizzazione

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

al vostro manifesto.

+11

formatIpAddress() è obsoleto. Vedere la soluzione di Digital Rounin di seguito, utilizzando invece InetAddress.getHostAddress(). – Emmanuel

+1

solo per i principianti: dovrebbe essere getSystemService (Context.WIFI_SERVICE) – 10101010

+0

Endiannes è una considerazione importante, il codice sopra riportato restituirà l'IP invertito sull'hardware Little Endian. Controlla la risposta di Digital Rounin sotto per il metodo corretto. Oppure http://stackoverflow.com/questions/29937433/gethostaddress-returns-a-reversed-ip-adress per un metodo più breve (che restituisce l'ip come int ma nell'ordine corretto). –

61

Quindi, qualcosa da considerare è che si sta Formatter.formatIpAddress(int) deprecato:

Questo metodo è stata sconsigliata a livello di API 12. Usa getHostAddress(), che supporta sia IPv4 e indirizzi IPv6. Questo metodo non supporta gli indirizzi IPv6.

Quindi utilizzare formatIpAddress(int) non è una buona soluzione a lungo termine, anche se funzionerà.

Ecco una possibile soluzione se si sta cercando di ottenere assolutamente sull'indirizzo IP per l'interfaccia 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; 
} 

Come indicato nelle risposte precedenti, è necessario impostare quanto segue nel AndroidManifest.xml:

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

si noti che questo è solo un esempio di soluzione. Si dovrebbe prendere tempo per verificare i valori nulli e così via per assicurarsi che l'UX sia scorrevole.

L'ironia è che da un lato Google è deprecating formatIpAddress(int), ma ha ancora getIpAddress() restituisce ancora un valore intero. Anche l'indirizzo IP è un int che lo esclude per essere conforme a IPv6.

Il prossimo è il fatto che endianness può o non può essere un problema. Ho testato solo tre dispositivi e sono stati tutti little-endian. Sembra che l'endianità possa variare a seconda dell'hardware, anche se stiamo girando in VM questo può ancora essere un problema. Quindi, per essere al sicuro, ho aggiunto un controllo endian nel codice.

getByAddress(byte[]) sembra voler che il valore intero sia big endian. Dalla ricerca di questo sembra che l'ordine dei byte di rete è big-endian. Ha senso dal momento che un indirizzo come 192.168.12.22 è un numero big-endian.


Partenza HammerNet progetto GitHub. Implementa il codice sopra insieme a una serie di controlli di integrità, possibilità di gestire i valori predefiniti per AVD, test di unità e altre cose. Ho dovuto implementarlo per una mia app e ho deciso di aprire la libreria.

+0

impossibile importare BigInteger in Android Studio. so che è strano ma è successo così. – 10101010

+2

La conversione endianness è in realtà molto importante per Nexus 5 e altri dispositivi. Grazie ! – Danpe

+1

"WifiManager wifiManager = (WifiManager) context.getApplicationContext(). GetSystemService (Context.WIFI_SERVICE)" È ancora un po 'meglio. – Denis

7

Questo ti consente di ottenere il WiFi IPv4, IPv6 o entrambi.

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

Usage:

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

E non dimenticate:

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

Se adb è installato nel terminale poi fare:

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

Sulla base della mia caduta registri, sembra che non tutti i dispositivi restituiscano l'indirizzo mac WiFi.

Ecco una versione più pulita della risposta più popolare.

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

cos'è 'wifiInfo', il tuo codice è incompleto – behelit

-1

Formatter.formatIpAddress (int) è sconsigliata:

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

Sì. Non supporterà IPv6. – aclokay

0

Add seguente autorizzazione.

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

WifiManager inizializza su onCreate.

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

Utilizzare la seguente funzione.

public void WI-FI_IP() { 
    WifiInfo wifiInfo = wifiMgr.getConnectionInfo(); 
    int ip = wifiInfo.getIpAddress(); 
    String ipAddress = Formatter.formatIpAddress(ip); 
    }