Ist es möglich, die IP-Adresse des Geräts mit einem Code zu erhalten?
Antworten
Zu viele Anzeigen?Dies ist mein Hilfsprogramm zum Lesen von IP- und MAC-Adressen. Die Implementierung ist rein in Java, aber ich habe einen Kommentarblock in getMACAddress()
, der den Wert aus der speziellen Linux (Android)-Datei lesen könnte. Ich habe diesen Code nur auf wenigen Geräten und Emulatoren ausgeführt, aber lassen Sie es mich hier wissen, wenn Sie merkwürdige Ergebnisse finden.
// AndroidManifest.xml Berechtigungen
// Testfunktionen
Utils.getMACAddress("Wlan0");
Utils.getMACAddress("eth0");
Utils.getIPAddress(true); // IPv4
Utils.getIPAddress(false); // IPv6
Utils.java
import java.io.*;
import java.net.*;
import java.util.*;
//import org.apache.http.conn.util.InetAddressUtils;
public class Utils {
/**
* Konvertiere Byte-Array in Hexadezimalzeichenfolge
* @param bytes toConvert
* @return hexValue
*/
public static String bytesToHex(byte[] bytes) {
StringBuilder sbuf = new StringBuilder();
for(int idx=0; idx < bytes.length; idx++) {
int intVal = bytes[idx] & 0xff;
if (intVal < 0x10) sbuf.append("0");
sbuf.append(Integer.toHexString(intVal).toUpperCase());
}
return sbuf.toString();
}
/**
* Byte-Array in UTF-8-Byte-Array umwandeln.
* @param str das konvertiert werden soll
* @return NULL-Array, wenn ein Fehler aufgetreten ist
*/
public static byte[] getUTF8Bytes(String str) {
try { return str.getBytes("UTF-8"); } catch (Exception ex) { return null; }
}
/**
* UTF8withBOM oder jede ANSI-Textdatei laden.
* @param Dateiname, der in String konvertiert werden soll
* @return String-Wert der Datei
* @throws java.io.IOException, wenn ein Fehler auftritt
*/
public static String loadFileAsString(String Dateiname) throws java.io.IOException {
final int BUFLEN=1024;
BufferedInputStream is = new BufferedInputStream(new FileInputStream(Dateiname), BUFLEN);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFLEN);
byte[] bytes = new byte[BUFLEN];
boolean isUTF8=false;
int read,count=0;
while((read=is.read(bytes)) != -1) {
if (count==0 && bytes[0]==(byte)0xEF && bytes[1]==(byte)0xBB && bytes[2]==(byte)0xBF ) {
isUTF8=true;
baos.write(bytes, 3, read-3); // drop UTF8 bom marker
} else {
baos.write(bytes, 0, read);
}
count+=read;
}
return isUTF8 ? new String(baos.toByteArray(), "UTF-8") : new String(baos.toByteArray());
} finally {
try{ is.close(); } catch(Exception ignored){}
}
}
/**
* Gibt die MAC-Adresse des angegebenen Schnittstellennamens zurück.
* @param interfaceName eth0, wlan0 oder NULL=erste Schnittstelle verwenden
* @return MAC-Adresse oder Leerzeichen
*/
public static String getMACAddress(String interfaceName) {
try {
List interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces) {
if (interfaceName != null) {
if (!intf.getName().equalsIgnoreCase(interfaceName)) continue;
}
byte[] mac = intf.getHardwareAddress();
if (mac==null) return "";
StringBuilder buf = new StringBuilder();
for (byte aMac : mac) buf.append(String.format("%02X:",aMac));
if (buf.length()>0) buf.deleteCharAt(buf.length()-1);
return buf.toString();
}
} catch (Exception ignored) { } // vorerst Ausnahmen unterdrücken
return "";
/*try {
// Dies ist also das Linux-Hack
return loadFileAsString("/sys/class/net/" +interfaceName + "/address").toUpperCase().trim();
} catch (IOException ex) {
return null;
}*/
}
/**
* Holt die IP-Adresse von der ersten Nicht-localhost-Schnittstelle
* @param useIPv4 true=IPv4 zurückgeben, false=IPv6 zurückgeben
* @return Adresse oder Leerzeichen
*/
public static String getIPAddress(boolean useIPv4) {
try {
List interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces) {
List addrs = Collections.list(intf.getInetAddresses());
for (InetAddress addr : addrs) {
if (!addr.isLoopbackAddress()) {
String sAddr = addr.getHostAddress();
//boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
boolean isIPv4 = sAddr.indexOf(':')<0;
if (useIPv4) {
if (isIPv4)
return sAddr;
} else {
if (!isIPv4) {
int delim = sAddr.indexOf('%'); // ip6-Zonen-Suffix entfernen
return delim<0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase();
}
}
}
}
}
} catch (Exception ignored) { } // vorerst Ausnahmen unterdrücken
return "";
}
}
Haftungsausschluss: Ideen und Beispielcode zu dieser Utils-Klasse stammen aus mehreren SO-Beiträgen und Google. Ich habe alle Beispiele bereinigt und zusammengeführt.
Mit der Berechtigung ACCESS_WIFI_STATE
in der Datei AndroidManifest.xml
deklariert:
Man kann den WifiManager
verwenden, um die IP-Adresse zu erhalten:
Context context = requireContext().getApplicationContext();
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
public static String getLocalIpAddress() {
try {
for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException ex) {
ex.printStackTrace();
}
return null;
}
Ich habe inetAddress
instanceof Inet4Address
hinzugefügt, um zu überprüfen, ob es sich um eine IPv4-Adresse handelt.
Ich habe folgenden Code verwendet: Der Grund, warum ich hashCode verwendet habe, war, weil mir einige Müllwerte am IP-Adresse angehängt wurden, als ich getHostAddress
verwendet habe. Aber hashCode
hat für mich wirklich gut funktioniert, da ich dann Formatter verwenden kann, um die IP-Adresse mit korrektem Format zu erhalten.
Hier ist das Beispieloutput :
1. Verwendung von getHostAddress
: ***** IP=fe80::65ca:a13d:ea5a:233d%rmnet_sdio0
2. Verwendung von hashCode
und Formatter
: ***** IP=238.194.77.212
Wie Sie sehen können, liefert mir die 2. Methode genau das, was ich brauche.
public String getLocalIpAddress() {
try {
for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
String ip = Formatter.formatIpAddress(inetAddress.hashCode());
Log.i(TAG, "***** IP="+ ip);
return ip;
}
}
}
} catch (SocketException ex) {
Log.e(TAG, ex.toString());
}
return null;
}
Obwohl es eine richtige Antwort gibt, teile ich hier meine Antwort und hoffe, dass es auf diese Weise bequemer ist.
WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInf = wifiMan.getConnectionInfo();
int ipAddress = wifiInf.getIpAddress();
String ip = String.format("%d.%d.%d.%d", (ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));
- See previous answers
- Weitere Antworten anzeigen
6 Stimmen
Vergessen Sie nicht, dass dies eine Sammlung der Größe N ist, und Sie können nicht davon ausgehen, dass N == ( 0 || 1 ). Mit anderen Worten, nehmen Sie nicht an, dass ein Gerät nur eine Möglichkeit hat, mit einem Netzwerk zu kommunizieren, und nehmen Sie nicht an, dass es überhaupt eine Möglichkeit zum Kommunizieren mit einem Netzwerk hat.
0 Stimmen
Verwandte: stackoverflow.com/questions/9481865/…
2 Stimmen
Nicht programmatische Version android.stackexchange.com/questions/2984/…
0 Stimmen
Du solltest es von einem externen Dienst bekommen ipof.in/txt ist ein solcher Dienst.
0 Stimmen
Ist es möglich, dies programmgesteuert in Android zu erhalten?
0 Stimmen
Siehe meine Antwort unter stackoverflow.com/questions/16730711/…