Bagaimana cara mendapatkan alamat IP perangkat dari kode?

384

Apakah mungkin untuk mendapatkan alamat IP perangkat menggunakan beberapa kode?

Nilesh Tupe
sumber
5
Jangan lupa bahwa ini adalah kumpulan ukuran N, dan Anda tidak dapat mengasumsikan bahwa N == (0 || 1). Dengan kata lain, jangan berasumsi bahwa suatu perangkat hanya memiliki satu cara untuk berbicara ke jaringan dan jangan menganggap bahwa itu memiliki cara apa pun untuk berbicara dengan jaringan sama sekali.
James Moore
Terkait: stackoverflow.com/questions/9481865/…
AlikElzin-kilaka
2
versi non programmatic android.stackexchange.com/questions/2984/…
Ciro Santilli 郝海东 冠状 病 六四 六四 事件 法轮功
Anda harus mendapatkannya dari layanan eksternal ipof.in/txt adalah salah satu layanan tersebut
vivekv
apakah mungkin untuk mendapatkannya secara programatik di android?
Tanmay Sahoo

Jawaban:

434

Ini adalah utilitas pembantu saya untuk membaca alamat IP dan MAC. Implementasinya murni-java, tapi saya punya blok komentar digetMACAddress() mana dapat membaca nilai dari file Linux (Android) khusus. Saya telah menjalankan kode ini hanya pada beberapa perangkat dan Emulator tetapi beri tahu saya di sini jika Anda menemukan hasil yang aneh.

// AndroidManifest.xml permissions
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

// test functions
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 {

    /**
     * Convert byte array to hex string
     * @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();
    }

    /**
     * Get utf8 byte array.
     * @param str which to be converted
     * @return  array of NULL if error was found
     */
    public static byte[] getUTF8Bytes(String str) {
        try { return str.getBytes("UTF-8"); } catch (Exception ex) { return null; }
    }

    /**
     * Load UTF8withBOM or any ansi text file.
     * @param filename which to be converted to string
     * @return String value of File
     * @throws java.io.IOException if error occurs
     */
    public static String loadFileAsString(String filename) throws java.io.IOException {
        final int BUFLEN=1024;
        BufferedInputStream is = new BufferedInputStream(new FileInputStream(filename), 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){} 
        }
    }

    /**
     * Returns MAC address of the given interface name.
     * @param interfaceName eth0, wlan0 or NULL=use first interface 
     * @return  mac address or empty string
     */
    public static String getMACAddress(String interfaceName) {
        try {
            List<NetworkInterface> 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) { } // for now eat exceptions
        return "";
        /*try {
            // this is so Linux hack
            return loadFileAsString("/sys/class/net/" +interfaceName + "/address").toUpperCase().trim();
        } catch (IOException ex) {
            return null;
        }*/
    }

    /**
     * Get IP address from first non-localhost interface
     * @param useIPv4   true=return ipv4, false=return ipv6
     * @return  address or empty string
     */
    public static String getIPAddress(boolean useIPv4) {
        try {
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface intf : interfaces) {
                List<InetAddress> 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('%'); // drop ip6 zone suffix
                                return delim<0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase();
                            }
                        }
                    }
                }
            }
        } catch (Exception ignored) { } // for now eat exceptions
        return "";
    }

}

Penafian: Ide dan kode contoh untuk kelas Utils ini berasal dari beberapa pos SO dan Google. Saya telah membersihkan dan menggabungkan semua contoh.

Siapa
sumber
17
Ini membutuhkan API level 9 dan lebih tinggi karena getHardwareAddress ().
Calvin
2
Masalah - peringatan serat aktif toUpperCase(). Penangkapan Exceptionselalu cerdik (dan metode penolong harus membuang pula dan membiarkan penelepon berurusan dengan Pengecualian - meskipun tidak mengubah ini). Pemformatan: tidak boleh lebih dari 80 baris. Eksekusi bersyarat untuk getHardwareAddress()- patch: github.com/Utumno/AndroidHelpers/commit/… . Apa kamu bilang ?
Mr_and_Mrs_D
5
Jika Anda berada di jaringan lokal (mis. Wifi atau emulator), Anda akan mendapatkan alamat IP pribadi. Anda bisa mendapatkan alamat IP proxy melalui permintaan ke situs web tertentu yang memberikan Anda alamat proxy, misalnya whatismyip.akamai.com
Julien Kronegg
1
Ini berfungsi sempurna untuk saya dengan perangkat nyata menggunakan Wifi. Terima kasih banyak, kawan
Tn. Neo
5
Saya mendapatkan hasil buruk dari ini pada Nexus 6 saat mencoba mendapatkan alamat IP. Saya memiliki NetworkInterface dengan nama "name: dummy0 (dummy0)" yang memberikan alamat dengan format "/ XX :: XXXX: XXXX: XXXX: XXXX% dummy0", ada juga antarmuka jaringan nyata yang sesuai dengan wlan0, tetapi sejak "dummy" terjadi lebih dulu saya selalu mendapatkan alamat dummy itu
Julian Suarez
201

Ini bekerja untuk saya:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
Nilesh Tupe
sumber
10
ini bekerja untuk saya. Namun, diperlukan izin "ACCESS_WIFI_STATE" dan seperti yang ditulis "Umair", penggunaan daftar tidak diperlukan.
pengembang android
13
formatIpAddress sudah usang karena beberapa alasan. Apa yang seharusnya digunakan?
pengembang android
8
Dari dokumen: Gunakan getHostAddress(), yang mendukung alamat IPv4 dan IPv6. Metode ini tidak mendukung alamat IPv6.
Ryan R
7
bagaimana cara menggunakan getHostAddress () dalam mendapatkan server & client ip address @RyanR?
gumuruh
42
apakah ini akan tetap bekerja bahkan jika pengguna menggunakan data, bukan wifi?
PinoyCoder
65

Saya menggunakan kode berikut: Alasan saya menggunakan kode hash adalah karena saya mendapatkan beberapa nilai sampah yang ditambahkan ke alamat ip ketika saya menggunakan getHostAddress. Tetapi hashCodebekerja dengan sangat baik bagi saya karena saya dapat menggunakan Formatter untuk mendapatkan alamat ip dengan format yang benar.

Berikut adalah contoh outputnya:

1.menggunakan getHostAddress:***** IP=fe80::65ca:a13d:ea5a:233d%rmnet_sdio0

2.menggunakan hashCodedan Formatter: ***** IP=238.194.77.212

Seperti yang Anda lihat metode 2 memberi saya apa yang saya butuhkan.

public String getLocalIpAddress() {
    try {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> 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;
}
tambahan
sumber
1
getHostAddress()akan melakukan hal yang sama seperti hal-hal formatter yang Anda tambahkan.
Phil
10
Menggunakan kode hash jelas salah, dan mengembalikan omong kosong. Gunakan InetAddress.getHostAddress () sebagai gantinya.
Pointer Null
ubah bagian ini: if (! inetAddress.isLoopbackAddress ()) {String ip = Formatter.formatIpAddress (inetAddress.hashCode ()); Log.i (TAG, "***** IP =" + ip); kembalikan ip; } dengan ini: if (! inetAddress.isLoopbackAddress () && InetAddressUtils.isIPv4Address (inetAddress.getHostAddress ())) {return inetAddress .getHostAddress (). toString (); } ini akan memberi Anda format ip yang benar
Chuy47
Kode hanya mengembalikan IP pertama, telepon mungkin memiliki alamat celluar, WIFI dan BT pada waktu yang sama
reker
@ Chuy47 dikatakan InetAddressUtils tidak dapat ditemukan
FabioR
61
public static String getLocalIpAddress() {
    try {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> 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;
}

Saya telah menambahkan inetAddressinstanceof Inet4Addressuntuk memeriksa apakah ini adalah alamat ipv4.

evertvandenbruel
sumber
menyelamatkan hari saya! Terima kasih. Ini satu-satunya kode yang berfungsi pada samsung s7 edge
Dhananjay Sarsonia
Ini jawaban nyata, alih-alih di atas yang hanya mendapatkan antarmuka WiFi.
nyconing
Ini benar-benar jawaban yang benar, ini berfungsi baik untuk WiFi dan jaringan seluler, dan menggunakan "getHostAddress" alih-alih pemformatan khusus.
Balázs Gerlei
Namun, ia mendapatkan IP lokal saya, saya memerlukan IP publik saya (karena saya percaya OP juga perlu)
FabioR
53

Meskipun ada jawaban yang benar, saya membagikan jawaban saya di sini dan berharap cara ini akan lebih nyaman.

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));
CYB
sumber
4
Terima kasih! Formatter sudah usang, dan saya benar-benar tidak merasa ingin menulis logika bit sederhana.
William Morrison
4
Bekerja dengan baik, tetapi membutuhkan izin WIFI_STATE:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Brent Faust
1
Saya menggunakan formaater tetapi tidak berfungsi. Sangat bagus! Sangat dihargai. Bisakah Anda menjelaskan apa yang dilakukan di baris terakhir. Saya tahu% d.% D.% D.% D namun yang lain? Terima kasih
Günay Gültekin
1
Nah ini tidak langsung menjawab OP. Karena tidak semua perangkat Android menggunakan WiFi untuk terhubung ke internet. Mungkin memiliki NATed LAN pada Ethernet, atau BT dan tidak koneksi
NATED
31

Kode di bawah ini dapat membantu Anda .. Jangan lupa untuk menambahkan izin ..

public String getLocalIpAddress(){
   try {
       for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();  
       en.hasMoreElements();) {
       NetworkInterface intf = en.nextElement();
           for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
           InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress()) {
                return inetAddress.getHostAddress();
                }
           }
       }
       } catch (Exception ex) {
          Log.e("IP Address", ex.toString());
      }
      return null;
}

Tambahkan izin di bawah ini dalam file manifes.

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

selamat coding !!

Satyam
sumber
6
Hai ini mengembalikan nilai yang salah seperti: "fe80 :: f225: b7ff: fe8c: d357% wlan0"
Jorgesys
@Jorgesys memeriksa jawaban evertvandenbruel di mana dia menambahkan inetAddress instance dari Inet4Address
temirbek
3
ubah jika kondisi seperti ini untuk mendapatkan ip yang benar: if (! inetAddress.isLoopbackAddress () && inetAddress instance dari Inet4Address)
Rajesh.k
Kode hanya mengembalikan IP pertama, telepon mungkin memiliki celluar, WIFI dan alamat BT pada saat yang sama
reker
Jika Anda memiliki hotspot aktif, Anda mungkin mendapatkan lebih dari satu ip
Harsha
16

Anda tidak perlu menambahkan izin seperti apa masalahnya dengan solusi yang diberikan sejauh ini. Unduh situs web ini sebagai string:

http://www.ip-api.com/json

atau

http://www.telize.com/geoip

Mengunduh situs web sebagai string dapat dilakukan dengan kode java:

http://www.itcuties.com/java/read-url-to-string/

Parsing objek JSON seperti ini:

https://stackoverflow.com/a/18998203/1987258

Atribut json "query" atau "ip" berisi alamat IP.

Daan
sumber
2
ini membutuhkan Koneksi Internet. Masalah besar
David
4
Mengapa itu masalah besar? Tentu saja Anda memerlukan koneksi internet karena alamat IP secara teknis terkait dengan koneksi semacam itu. Jika Anda meninggalkan rumah dan pergi ke restoran, Anda akan menggunakan koneksi internet lain dan dengan demikian alamat IP lainnya. Anda tidak perlu menambahkan sesuatu seperti ACCESS_NETWORK_STATE atau ACCESS_WIFI_STATE. Koneksi internet adalah satu-satunya izin yang Anda butuhkan untuk solusi yang disediakan oleh saya.
Daan
2
Domain yang mana? Jika ip-api.com tidak berfungsi, Anda dapat menggunakan telize.com sebagai cadangan. Kalau tidak, Anda dapat menggunakan api.ipify.org . Ini juga tersedia di sini (bukan json): ip.jsontest.com/?callback=showIP . Banyak aplikasi menggunakan domain yang dijamin tetap online; itu normal. Namun, jika Anda menggunakan fallback maka sangat tidak mungkin akan ada masalah.
Daan
3
Poin asli David masih berdiri. Bagaimana jika Anda berada di jaringan internal yang tidak memiliki akses ke internet.
hiandbaii
2
Saya tidak pernah memikirkan hal itu karena saya tidak tahu tujuan praktis aplikasi yang pasti membutuhkan jaringan tetapi harus bekerja tanpa internet (mungkin ada tetapi saya tidak melihatnya untuk perangkat seluler).
Daan
9
private InetAddress getLocalAddress()throws IOException {

            try {
                for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                    NetworkInterface intf = en.nextElement();
                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        if (!inetAddress.isLoopbackAddress()) {
                            //return inetAddress.getHostAddress().toString();
                            return inetAddress;
                        }
                    }
                }
            } catch (SocketException ex) {
                Log.e("SALMAN", ex.toString());
            }
            return null;
        }
salman khalid
sumber
1
apakah mungkin ini akan mengembalikan ip jaringan pribadi dari antarmuka wifi, seperti 192.168.0.x? atau apakah akan selalu mengembalikan alamat ip eksternal, yang akan digunakan di internet?
Ben H
9

Metode getDeviceIpAddress mengembalikan alamat ip perangkat dan lebih memilih alamat antarmuka wifi jika terhubung.

  @NonNull
    private String getDeviceIpAddress() {
        String actualConnectedToNetwork = null;
        ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connManager != null) {
            NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (mWifi.isConnected()) {
                actualConnectedToNetwork = getWifiIp();
            }
        }
        if (TextUtils.isEmpty(actualConnectedToNetwork)) {
            actualConnectedToNetwork = getNetworkInterfaceIpAddress();
        }
        if (TextUtils.isEmpty(actualConnectedToNetwork)) {
            actualConnectedToNetwork = "127.0.0.1";
        }
        return actualConnectedToNetwork;
    }

    @Nullable
    private String getWifiIp() {
        final WifiManager mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (mWifiManager != null && mWifiManager.isWifiEnabled()) {
            int ip = mWifiManager.getConnectionInfo().getIpAddress();
            return (ip & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "."
                    + ((ip >> 24) & 0xFF);
        }
        return null;
    }


    @Nullable
    public String getNetworkInterfaceIpAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface networkInterface = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = networkInterface.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                        String host = inetAddress.getHostAddress();
                        if (!TextUtils.isEmpty(host)) {
                            return host;
                        }
                    }
                }

            }
        } catch (Exception ex) {
            Log.e("IP Address", "getLocalIpAddress", ex);
        }
        return null;
    }
Ruslan Podurets
sumber
4

Ini adalah pengerjaan ulang dari jawaban ini yang menghapus informasi yang tidak relevan, menambahkan komentar yang bermanfaat, nama variabel lebih jelas, dan meningkatkan logika.

Jangan lupa untuk menyertakan izin berikut:

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

InternetHelper.java:

public class InternetHelper {

    /**
     * Get IP address from first non-localhost interface
     *
     * @param useIPv4 true=return ipv4, false=return ipv6
     * @return address or empty string
     */
    public static String getIPAddress(boolean useIPv4) {
        try {
            List<NetworkInterface> interfaces =
                    Collections.list(NetworkInterface.getNetworkInterfaces());

            for (NetworkInterface interface_ : interfaces) {

                for (InetAddress inetAddress :
                        Collections.list(interface_.getInetAddresses())) {

                    /* a loopback address would be something like 127.0.0.1 (the device
                       itself). we want to return the first non-loopback address. */
                    if (!inetAddress.isLoopbackAddress()) {
                        String ipAddr = inetAddress.getHostAddress();
                        boolean isIPv4 = ipAddr.indexOf(':') < 0;

                        if (isIPv4 && !useIPv4) {
                            continue;
                        }
                        if (useIPv4 && !isIPv4) {
                            int delim = ipAddr.indexOf('%'); // drop ip6 zone suffix
                            ipAddr = delim < 0 ? ipAddr.toUpperCase() :
                                    ipAddr.substring(0, delim).toUpperCase();
                        }
                        return ipAddr;
                    }
                }

            }
        } catch (Exception ignored) { } // if we can't connect, just return empty string
        return "";
    }

    /**
     * Get IPv4 address from first non-localhost interface
     *
     * @return address or empty string
     */
    public static String getIPAddress() {
        return getIPAddress(true);
    }

}
Jon McClung
sumber
4

versi minimalis kotlin

fun getIpv4HostAddress(): String {
    NetworkInterface.getNetworkInterfaces()?.toList()?.map { networkInterface ->
        networkInterface.inetAddresses?.toList()?.find {
            !it.isLoopbackAddress && it is Inet4Address
        }?.let { return it.hostAddress }
    }
    return ""
}
Raphael C
sumber
3
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString();
mridul
sumber
3

Cukup gunakan Volley untuk mendapatkan ip dari situs ini

RequestQueue queue = Volley.newRequestQueue(this);    
String urlip = "http://checkip.amazonaws.com/";

    StringRequest stringRequest = new StringRequest(Request.Method.GET, urlip, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            txtIP.setText(response);

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            txtIP.setText("didnt work");
        }
    });

    queue.add(stringRequest);
Sohel Mahmud
sumber
2

Baru-baru ini, alamat IP masih dikembalikan oleh getLocalIpAddress()meskipun terputus dari jaringan (tidak ada indikator layanan). Ini berarti alamat IP yang ditampilkan dalam Pengaturan> Tentang telepon> Status berbeda dari apa yang dipikirkan aplikasi.

Saya telah menerapkan solusi dengan menambahkan kode ini sebelumnya:

ConnectivityManager cm = getConnectivityManager();
NetworkInfo net = cm.getActiveNetworkInfo();
if ((null == net) || !net.isConnectedOrConnecting()) {
    return null;
}

Apakah itu membunyikan bel untuk siapa pun?

slash33
sumber
2

di Kotlin, tanpa Formatter

private fun getIPAddress(useIPv4 : Boolean): String {
    try {
        var interfaces = Collections.list(NetworkInterface.getNetworkInterfaces())
        for (intf in interfaces) {
            var addrs = Collections.list(intf.getInetAddresses());
            for (addr in addrs) {
                if (!addr.isLoopbackAddress()) {
                    var sAddr = addr.getHostAddress();
                    var isIPv4: Boolean
                    isIPv4 = sAddr.indexOf(':')<0
                    if (useIPv4) {
                        if (isIPv4)
                            return sAddr;
                    } else {
                        if (!isIPv4) {
                            var delim = sAddr.indexOf('%') // drop ip6 zone suffix
                            if (delim < 0) {
                                return sAddr.toUpperCase()
                            }
                            else {
                                return sAddr.substring(0, delim).toUpperCase()
                            }
                        }
                    }
                }
            }
        }
    } catch (e: java.lang.Exception) { }
    return ""
}
zeina
sumber
2

Dalam aktivitas Anda, fungsi berikut getIpAddress(context)mengembalikan alamat IP telepon:

public static String getIpAddress(Context context) {
    WifiManager wifiManager = (WifiManager) context.getApplicationContext()
                .getSystemService(WIFI_SERVICE);

    String ipAddress = intToInetAddress(wifiManager.getDhcpInfo().ipAddress).toString();

    ipAddress = ipAddress.substring(1);

    return ipAddress;
}

public static InetAddress intToInetAddress(int hostAddress) {
    byte[] addressBytes = { (byte)(0xff & hostAddress),
                (byte)(0xff & (hostAddress >> 8)),
                (byte)(0xff & (hostAddress >> 16)),
                (byte)(0xff & (hostAddress >> 24)) };

    try {
        return InetAddress.getByAddress(addressBytes);
    } catch (UnknownHostException e) {
        throw new AssertionError();
    }
}
matdev
sumber
Saya mendapatkan
0,0.0.0
Apakah ponsel Anda terhubung ke jaringan wifi? Nilai mana yang dikembalikan jika Anda memanggil wifiManager.getConnectionInfo (). GetSSID ()?
matdev
Apakah ini akan berfungsi untuk perangkat yang terhubung ke Data Seluler, bukan WiFi?
Sergey
Tidak, metode ini hanya berfungsi jika perangkat terhubung ke WiFi
matdev
1

Ini adalah versi kotlin dari @Nilesh dan @anargund

  fun getIpAddress(): String {
    var ip = ""
    try {
        val wm = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
        ip = Formatter.formatIpAddress(wm.connectionInfo.ipAddress)
    } catch (e: java.lang.Exception) {

    }

    if (ip.isEmpty()) {
        try {
            val en = NetworkInterface.getNetworkInterfaces()
            while (en.hasMoreElements()) {
                val networkInterface = en.nextElement()
                val enumIpAddr = networkInterface.inetAddresses
                while (enumIpAddr.hasMoreElements()) {
                    val inetAddress = enumIpAddr.nextElement()
                    if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
                        val host = inetAddress.getHostAddress()
                        if (host.isNotEmpty()) {
                            ip =  host
                            break;
                        }
                    }
                }

            }
        } catch (e: java.lang.Exception) {

        }
    }

   if (ip.isEmpty())
      ip = "127.0.0.1"
    return ip
}
Sumit
sumber
1
Jika ini gaya kode Anda dalam proyek nyata, saya sarankan Anda membaca "kode bersih" oleh robert martin
Ahmed Adel Ismail
1

Perangkat mungkin memiliki beberapa alamat IP, dan yang digunakan dalam aplikasi tertentu mungkin bukan IP yang akan dilihat oleh server yang menerima permintaan. Memang, beberapa pengguna menggunakan VPN atau proxy seperti Cloudflare Warp .

Jika tujuan Anda adalah untuk mendapatkan alamat IP seperti yang ditunjukkan oleh server yang menerima permintaan dari perangkat Anda, maka yang terbaik adalah meminta layanan geolokasi IP seperti Ipregistry (penafian: Saya bekerja untuk perusahaan) dengan klien Java-nya:

https://github.com/ipregistry/ipregistry-java

IpregistryClient client = new IpregistryClient("tryout");
RequesterIpInfo requesterIpInfo = client.lookup();
requesterIpInfo.getIp();

Selain sangat mudah digunakan, Anda mendapatkan informasi tambahan seperti negara, bahasa, mata uang, zona waktu untuk IP perangkat dan Anda dapat mengidentifikasi apakah pengguna menggunakan proxy.

Laurent
sumber
1

Ini adalah cara termudah dan sederhana yang pernah ada di internet ... Pertama-tama, tambahkan izin ini ke file manifes Anda ...

  1. "INTERNET"

  2. "ACCESS_NETWORK_STATE"

tambahkan ini dalam file Aktivitas onCreate ..

    getPublicIP();

Sekarang Tambahkan fungsi ini ke MainActivity.class Anda.

    private void getPublicIP() {
ArrayList<String> urls=new ArrayList<String>(); //to read each line

        new Thread(new Runnable(){
            public void run(){
                //TextView t; //to show the result, please declare and find it inside onCreate()

                try {
                    // Create a URL for the desired page
                    URL url = new URL("https://api.ipify.org/"); //My text file location
                    //First open the connection
                    HttpURLConnection conn=(HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(60000); // timing out in a minute

                    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

                    //t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate()
                    String str;
                    while ((str = in.readLine()) != null) {
                        urls.add(str);
                    }
                    in.close();
                } catch (Exception e) {
                    Log.d("MyTag",e.toString());
                }

                //since we are in background thread, to post results we have to go back to ui thread. do the following for that

                PermissionsActivity.this.runOnUiThread(new Runnable(){
                    public void run(){
                        try {
                            Toast.makeText(PermissionsActivity.this, "Public IP:"+urls.get(0), Toast.LENGTH_SHORT).show();
                        }
                        catch (Exception e){
                            Toast.makeText(PermissionsActivity.this, "TurnOn wiffi to get public ip", Toast.LENGTH_SHORT).show();
                        }
                    }
                });

            }
        }).start();

    }

Zia Muhammad
sumber
urls.get (0) berisi alamat IP publik Anda.
Zia Muhammad
Anda harus mendeklarasikan dalam file aktivitas Anda seperti ini: ArrayList <String> urls = new ArrayList <String> (); // untuk membaca setiap baris
Zia Muhammad
0

Jika Anda memiliki shell; ifconfig eth0 bekerja untuk perangkat x86 juga

RzR
sumber
0

Silakan periksa kode ini ... Menggunakan kode ini. kita akan mendapatkan ip dari internet seluler ...

for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress()) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
venkat
sumber
0

Saya tidak melakukan Android, tetapi saya akan mengatasinya dengan cara yang sama sekali berbeda.

Kirim kueri ke Google, sesuatu seperti: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

Dan merujuk ke bidang HTML di mana respons diposting. Anda juga dapat meminta langsung ke sumbernya.

Google paling suka berada di sana lebih lama dari Aplikasi Anda.

Hanya ingat, bisa jadi pengguna Anda tidak memiliki internet saat ini, apa yang Anda inginkan terjadi!

Semoga berhasil

Makab
sumber
Menarik! Dan saya bertaruh bahwa Google memiliki semacam panggilan API yang akan mengembalikan IP Anda, yang akan lebih stabil daripada memindai HTML.
Scott Biggs
0

Kamu bisa melakukan ini

String stringUrl = "https://ipinfo.io/ip";
//String stringUrl = "http://whatismyip.akamai.com/";
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(MainActivity.instance);
//String url ="http://www.google.com";

// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, stringUrl,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                // Display the first 500 characters of the response string.
                Log.e(MGLogTag, "GET IP : " + response);

            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        IP = "That didn't work!";
    }
});

// Add the request to the RequestQueue.
queue.add(stringRequest);
Raphaël Maguet
sumber
0
 //    @NonNull
    public static String getIPAddress() {
        if (TextUtils.isEmpty(deviceIpAddress))
            new PublicIPAddress().execute();
        return deviceIpAddress;
    }

    public static String deviceIpAddress = "";

    public static class PublicIPAddress extends AsyncTask<String, Void, String> {
        InetAddress localhost = null;

        protected String doInBackground(String... urls) {
            try {
                localhost = InetAddress.getLocalHost();
                URL url_name = new URL("http://bot.whatismyipaddress.com");
                BufferedReader sc = new BufferedReader(new InputStreamReader(url_name.openStream()));
                deviceIpAddress = sc.readLine().trim();
            } catch (Exception e) {
                deviceIpAddress = "";
            }
            return deviceIpAddress;
        }

        protected void onPostExecute(String string) {
            Lg.d("deviceIpAddress", string);
        }
    }
Ashish Kumar
sumber
0

Sejujurnya saya hanya sedikit terbiasa dengan keamanan kode, jadi ini mungkin hack-ish. Tetapi bagi saya ini adalah cara paling serbaguna untuk melakukannya:

package com.my_objects.ip;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class MyIpByHost 
{
  public static void main(String a[])
  {
   try 
    {
      InetAddress host = InetAddress.getByName("nameOfDevice or webAddress");
      System.out.println(host.getHostAddress());
    } 
   catch (UnknownHostException e) 
    {
      e.printStackTrace();
    }
} }
Tyler Depies-Bobrowitz
sumber
0

Kompilasi beberapa ide untuk mendapatkan ip wifi dari WifiManagerdalam solusi kotlin yang lebih baik:

private fun getWifiIp(context: Context): String? {
  return context.getSystemService<WifiManager>().let {
     when {
      it == null -> "No wifi available"
      !it.isWifiEnabled -> "Wifi is disabled"
      it.connectionInfo == null -> "Wifi not connected"
      else -> {
        val ip = it.connectionInfo.ipAddress
        ((ip and 0xFF).toString() + "." + (ip shr 8 and 0xFF) + "." + (ip shr 16 and 0xFF) + "." + (ip shr 24 and 0xFF))
      }
    }
  }
}

Atau Anda bisa mendapatkan alamat IP dari perangkat loopback ip4 melalui NetworkInterface:

fun getNetworkIp4LoopbackIps(): Map<String, String> = try {
  NetworkInterface.getNetworkInterfaces()
    .asSequence()
    .associate { it.displayName to it.ip4LoopbackIps() }
    .filterValues { it.isNotEmpty() }
} catch (ex: Exception) {
  emptyMap()
}

private fun NetworkInterface.ip4LoopbackIps() =
  inetAddresses.asSequence()
    .filter { !it.isLoopbackAddress && it is Inet4Address }
    .map { it.hostAddress }
    .filter { it.isNotEmpty() }
    .joinToString()
Moritz
sumber
-2

Berdasarkan apa yang telah saya uji, inilah proposal saya

import java.net.*;
import java.util.*;

public class hostUtil
{
   public static String HOST_NAME = null;
   public static String HOST_IPADDRESS = null;

   public static String getThisHostName ()
   {
      if (HOST_NAME == null) obtainHostInfo ();
      return HOST_NAME;
   }

   public static String getThisIpAddress ()
   {
      if (HOST_IPADDRESS == null) obtainHostInfo ();
      return HOST_IPADDRESS;
   }

   protected static void obtainHostInfo ()
   {
      HOST_IPADDRESS = "127.0.0.1";
      HOST_NAME = "localhost";

      try
      {
         InetAddress primera = InetAddress.getLocalHost();
         String hostname = InetAddress.getLocalHost().getHostName ();

         if (!primera.isLoopbackAddress () &&
             !hostname.equalsIgnoreCase ("localhost") &&
              primera.getHostAddress ().indexOf (':') == -1)
         {
            // Got it without delay!!
            HOST_IPADDRESS = primera.getHostAddress ();
            HOST_NAME = hostname;
            //System.out.println ("First try! " + HOST_NAME + " IP " + HOST_IPADDRESS);
            return;
         }
         for (Enumeration<NetworkInterface> netArr = NetworkInterface.getNetworkInterfaces(); netArr.hasMoreElements();)
         {
            NetworkInterface netInte = netArr.nextElement ();
            for (Enumeration<InetAddress> addArr = netInte.getInetAddresses (); addArr.hasMoreElements ();)
            {
               InetAddress laAdd = addArr.nextElement ();
               String ipstring = laAdd.getHostAddress ();
               String hostName = laAdd.getHostName ();

               if (laAdd.isLoopbackAddress()) continue;
               if (hostName.equalsIgnoreCase ("localhost")) continue;
               if (ipstring.indexOf (':') >= 0) continue;

               HOST_IPADDRESS = ipstring;
               HOST_NAME = hostName;
               break;
            }
         }
      } catch (Exception ex) {}
   }
}
elxala
sumber