จะรับที่อยู่ IP ของอุปกรณ์จากรหัสได้อย่างไร


383

เป็นไปได้ที่จะได้รับที่อยู่ IP ของอุปกรณ์โดยใช้รหัสบางส่วน?


5
อย่าลืมว่านี่คือชุดของขนาด N และคุณไม่สามารถคาดเดาได้ว่า N == (0 || 1) กล่าวอีกนัยหนึ่งไม่ได้คิดว่าอุปกรณ์มีเพียงวิธีเดียวในการพูดคุยกับเครือข่ายและไม่คิดว่ามันจะมีวิธีการพูดคุยกับเครือข่ายเลย
James Moore

ที่เกี่ยวข้อง: stackoverflow.com/questions/9481865/…
AlikElzin-kilaka

2
ไม่ใช่รุ่นเขียนโปรแกรมandroid.stackexchange.com/questions/2984/...
Ciro Santilli郝海东冠状病六四事件法轮功

คุณควรได้รับจากบริการภายนอกipof.in/txtเป็นบริการหนึ่งดังกล่าว
vivekv

เป็นไปได้ไหมที่จะตั้งโปรแกรมไว้ใน Android?
Tanmay Sahoo

คำตอบ:


434

นี่คือผู้ช่วยของฉันที่ใช้อ่าน IP และที่อยู่ MAC การใช้งานเป็น pure-java แต่ฉันมีบล็อกความคิดเห็นgetMACAddress()ที่สามารถอ่านค่าจากไฟล์พิเศษ Linux (Android) ฉันเรียกใช้รหัสนี้ในอุปกรณ์และ Emulator ไม่กี่เครื่อง แต่แจ้งให้เราทราบที่นี่หากคุณพบผลลัพธ์ที่แปลก

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

}

ข้อจำกัดความรับผิดชอบ: แนวคิดและรหัสตัวอย่างของคลาส Utils มาจากการโพสต์ SO และ Google หลายครั้ง ฉันได้ทำความสะอาดและผสานตัวอย่างทั้งหมดแล้ว


17
ต้องใช้ API ระดับ 9 ขึ้นไปเนื่องจาก getHardwareAddress ()
Calvin

2
ปัญหา - toUpperCase()คำเตือนบนผ้าสำลี การจับExceptionเป็นสิ่งที่หลบอยู่เสมอ (และวิธีการของผู้ช่วยควรโยนต่อไปและให้ผู้โทรจัดการกับข้อยกเว้น - ไม่ได้แก้ไขสิ่งนี้) การจัดรูปแบบ: ไม่ควรเกิน 80 บรรทัด การดำเนินการตามเงื่อนไขสำหรับgetHardwareAddress()- แพทช์: github.com/Utumno/AndroidHelpers/commit/... คุณพูดอะไร ?
Mr_and_Mrs_D

5
หากคุณอยู่ในเครือข่ายท้องถิ่น (เช่น Wifi หรือโปรแกรมจำลอง) คุณจะได้รับที่อยู่ IP ส่วนตัว คุณจะได้รับที่อยู่ IP พร็อกซีผ่านการร้องขอไปยังเว็บไซต์ที่เฉพาะเจาะจงซึ่งจะช่วยให้คุณอยู่พร็อกซี่เช่นwhatismyip.akamai.com
Julien Kronegg

1
มันใช้งานได้ดีสำหรับฉันกับอุปกรณ์จริงโดยใช้ Wifi ขอบคุณมากครับ
นาย Neo

5
ฉันได้รับผลลัพธ์ที่ไม่ดีจากสิ่งนี้ใน Nexus 6 เมื่อพยายามรับที่อยู่ IP ฉันมี NetworkInterface ที่มีชื่อ "ชื่อ: dummy0 (dummy0)" ที่ให้ที่อยู่ด้วยรูปแบบ "/ XX :: XXXX: XXXX: XXXX: XXXX% dummy0" นอกจากนี้ยังมีอินเทอร์เฟซเครือข่ายจริงที่สอดคล้องกับ wlan0 แต่ ตั้งแต่ "ดัมมี่" เกิดขึ้นครั้งแรกฉันมักจะได้รับที่อยู่จำลองที่
Julian Suarez

201

สิ่งนี้ใช้ได้กับฉัน:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());

10
อันนี้ใช้ได้สำหรับฉัน อย่างไรก็ตามจำเป็นต้องได้รับอนุญาต "ACCESS_WIFI_STATE" และตามที่เขียนไว้ว่า "Umair" การใช้รายการนั้นไม่จำเป็น
นักพัฒนา Android

13
formatIpAddress เลิกใช้แล้วด้วยเหตุผลบางประการ ควรใช้อะไรแทน
นักพัฒนา Android

8
จากเอกสาร: ใช้getHostAddress()ซึ่งรองรับทั้งที่อยู่ IPv4 และ IPv6 วิธีนี้ไม่รองรับที่อยู่ IPv6
Ryan R

7
วิธีใช้ getHostAddress () ในการรับที่อยู่ IP ของเซิร์ฟเวอร์และไคลเอนต์ @RyanR?
gumuruh

42
จะยังใช้งานได้แม้ว่าผู้ใช้จะใช้ข้อมูลแทน wifi หรือไม่
PinoyCoder

65

ฉันใช้รหัสต่อไปนี้: เหตุผลที่ฉันใช้ hashCode เป็นเพราะผมได้รับค่าขยะบางผนวกเข้ากับที่อยู่ IP getHostAddressเมื่อผมใช้ แต่hashCodeทำงานได้ดีมากสำหรับฉันแล้วฉันสามารถใช้ Formatter เพื่อรับที่อยู่ IP ด้วยการจัดรูปแบบที่ถูกต้อง

นี่คือตัวอย่างเอาต์พุต:

getHostAddress1. ใช้:***** IP=fe80::65ca:a13d:ea5a:233d%rmnet_sdio0

2. การใช้hashCodeและFormatter: ***** IP=238.194.77.212

อย่างที่คุณเห็นวิธีที่ 2 ให้สิ่งที่ฉันต้องการอย่างแน่นอน

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

1
getHostAddress()จะทำเช่นเดียวกับสิ่งที่ฟอร์แมตเตอร์ที่คุณเพิ่ม
Phil

10
การใช้ hashCode นั้นผิดปกติและส่งคืนไร้สาระ ใช้ InetAddress.getHostAddress () แทน
ตัวชี้ Null

เปลี่ยนส่วนนี้: if (! inetAddress.isLoopbackAddress ()) {String ip = Formatter.formatIpAddress (inetAddress.hashCode ()); Log.i (TAG, "***** IP =" + ip); คืนค่า ip } ด้วยสิ่งนี้: ถ้า (! inetAddress.isLoopbackAddress () && InetAddressUtils.isIPv4Address (inetAddress.getHostAddress ()) {{กลับ inetAddress .getHostAddress (); toString (); } สิ่งนี้จะให้รูปแบบ ip ที่ถูกต้อง
Chuy47

รหัสเท่านั้นกลับ IP แรกโทรศัพท์อาจมี celluar, WIFI และ BT อยู่ในเวลาเดียวกัน
Reker

@ Chuy47 มีข้อความระบุว่าไม่พบ InetAddressUtils
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;
}

ฉันได้เพิ่มinetAddressinstanceof Inet4Addressเพื่อตรวจสอบว่าเป็นที่อยู่ ipv4 หรือไม่


บันทึกวันของฉัน! ขอบคุณ มันเป็นรหัสเดียวที่ทำงานบน samsung s7 edge
Dhananjay Sarsonia

นี่คือคำตอบที่แท้จริงแทนที่จะเป็นด้านบนซึ่งเพิ่งได้รับอินเทอร์เฟซ WiFi เท่านั้น
nyconing

นี่ควรเป็นคำตอบที่ถูกต้องใช้ได้กับทั้ง WiFi และเครือข่ายมือถือและใช้ "getHostAddress" แทนการจัดรูปแบบที่กำหนดเอง
Balázs Gerlei

อย่างไรก็ตามจะได้รับ IP ในท้องถิ่นของฉันฉันต้องการ IP สาธารณะของฉัน (เพราะฉันเชื่อว่า OP ต้องการเช่นกัน)
FabioR

53

แม้ว่าจะมีคำตอบที่ถูกต้อง แต่ฉันแบ่งปันคำตอบของฉันที่นี่และหวังว่าวิธีนี้จะสะดวกยิ่งขึ้น

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

4
ขอบคุณ! ตัวจัดรูปแบบเลิกใช้แล้วและฉันไม่รู้สึกอยากเขียนตรรกะแบบง่าย ๆ
William Morrison

4
ใช้งานได้ดี แต่ต้องได้รับอนุญาต WIFI_STATE:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Brent Faust

1
ฉันใช้ formaater แต่มันใช้งานไม่ได้ มันเยี่ยมมาก! ชื่นชมจริงๆ. คุณช่วยอธิบายสิ่งที่ทำในบรรทัดสุดท้ายได้ไหม ฉันรู้% d.% d.% d.% d ยังคนอื่น ๆ ? ขอบคุณ
GünayGültekin

1
ไม่นี่ไม่ตอบโดยตรงไปยัง OP เพราะไม่ใช่อุปกรณ์ Android ทั้งหมดที่ใช้ WiFi เพื่อเชื่อมต่ออินเทอร์เน็ต มันอาจจะมีจากเศษ LAN บนอีเธอร์เน็ตหรือ BT และไม่ได้เชื่อมต่อ WAN จากเศษ ฯลฯ
nyconing

31

โค้ดด้านล่างอาจช่วยคุณได้ .. อย่าลืมเพิ่มสิทธิ์ ..

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

เพิ่มการอนุญาตด้านล่างในไฟล์รายการ

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

การเข้ารหัสที่มีความสุข !!


6
เฮ้นี่คืนค่าที่ไม่ถูกต้องเช่น: "fe80 :: f225: b7ff: fe8c: d357% wlan0"
Jorgesys

@Jorgesys ตรวจสอบคำตอบของ evertvandenbruel ที่เขาเพิ่ม inetAddress instanceof Inet4Address
temirbek

3
เปลี่ยนหากเงื่อนไขเช่นนี้เพื่อรับ ip ที่ถูกต้อง: if (! inetAddress.isLoopbackAddress () && inetAddress instanceof Inet4Address)
Rajesh.k

รหัสเท่านั้นกลับ IP แรกโทรศัพท์อาจมี celluar, WIFI และ BT อยู่ในเวลาเดียวกัน
Reker

หากคุณเปิดฮอตสปอตคุณอาจได้รับมากกว่าหนึ่ง ip
Harsha

16

คุณไม่จำเป็นต้องเพิ่มการอนุญาตเช่นเดียวกับกรณีที่มีวิธีการแก้ไขที่ให้ไว้ ดาวน์โหลดเว็บไซต์นี้เป็นสตริง:

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

หรือ

http://www.telize.com/geoip

การดาวน์โหลดเว็บไซต์เป็นสตริงสามารถทำได้ด้วยรหัส java:

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

แยกวิเคราะห์วัตถุ JSON ดังนี้:

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

แอตทริบิวต์ json "query" หรือ "ip" มีที่อยู่ IP


2
สิ่งนี้ต้องการการเชื่อมต่ออินเทอร์เน็ต ปัญหาใหญ่
เดวิด

4
ทำไมเป็นปัญหาใหญ่ แน่นอนว่าคุณต้องมีการเชื่อมต่ออินเทอร์เน็ตเพราะที่อยู่ IP นั้นเกี่ยวข้องกับการเชื่อมโยงทางเทคนิค หากคุณออกจากบ้านและไปที่ร้านอาหารคุณจะใช้การเชื่อมต่ออินเทอร์เน็ตอื่นและที่อยู่ IP อื่น คุณไม่ต้องการสิ่งที่จะเพิ่มเช่น ACCESS_NETWORK_STATE หรือ ACCESS_WIFI_STATE การเชื่อมต่ออินเทอร์เน็ตเป็นการอนุญาตเพียงอย่างเดียวที่คุณต้องการสำหรับวิธีการแก้ปัญหาโดยฉัน
Daan

2
โดเมนใด หาก ip-api.com ไม่ทำงานคุณสามารถใช้ telize.com เป็นทางเลือก มิฉะนั้นคุณสามารถใช้api.ipify.org นอกจากนี้ยังมีที่นี่ (ไม่ JSON): ip.jsontest.com/?callback=showIP แอพจำนวนมากใช้โดเมนที่รับประกันว่าจะออนไลน์ นั่นเป็นเรื่องปกติ อย่างไรก็ตามหากคุณใช้ทางเลือกนั้นจะไม่น่าเป็นไปได้อย่างมากว่าจะมีปัญหา
Daan

3
จุดเริ่มต้นของเดวิดยังคงอยู่ จะทำอย่างไรถ้าคุณอยู่ในเครือข่ายภายในที่ไม่สามารถเข้าถึงอินเทอร์เน็ตได้
hiandbaii

2
ฉันไม่เคยคิดเกี่ยวกับเรื่องนี้เพราะฉันไม่รู้วัตถุประสงค์ที่เป็นประโยชน์ของแอพที่ต้องการเครือข่าย แต่ควรทำงานโดยไม่ใช้อินเทอร์เน็ต (อาจมี แต่ฉันไม่เห็นมันสำหรับอุปกรณ์มือถือ)
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;
        }

1
เป็นไปได้ไหมว่าสิ่งนี้จะส่งคืนเครือข่ายส่วนตัว ip จากอินเทอร์เฟซ wifi เช่น 192.168.0.x หรือมันมักจะส่งคืนที่อยู่ IP ภายนอกที่จะใช้บนอินเทอร์เน็ตหรือไม่
Ben H

9

เมธอด getDeviceIpAddress ส่งคืนที่อยู่ IP ของอุปกรณ์และต้องการที่อยู่อินเทอร์เฟซไร้สายหากเชื่อมต่อ

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

4

นี่เป็นการนำกลับมาทำใหม่ของคำตอบนี้ซึ่งตัดข้อมูลที่ไม่เกี่ยวข้องออกไปเพิ่มความคิดเห็นที่เป็นประโยชน์ตั้งชื่อตัวแปรให้ชัดเจนยิ่งขึ้นและปรับปรุงตรรกะ

อย่าลืมที่จะรวมสิทธิ์ต่อไปนี้:

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

}

4

kotlin รุ่นที่เรียบง่าย

fun getIpv4HostAddress(): String {
    NetworkInterface.getNetworkInterfaces()?.toList()?.map { networkInterface ->
        networkInterface.inetAddresses?.toList()?.find {
            !it.isLoopbackAddress && it is Inet4Address
        }?.let { return it.hostAddress }
    }
    return ""
}


3

เพียงใช้วอลเล่ย์เพื่อรับไอพีจากเว็บไซต์นี้

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

2

เมื่อเร็ว ๆ นี้ที่อยู่ IP ยังคงถูกส่งคืนgetLocalIpAddress()แม้ว่าจะถูกตัดการเชื่อมต่อจากเครือข่าย (ไม่มีตัวบ่งชี้บริการ) หมายความว่าที่อยู่ IP ที่แสดงในการตั้งค่า> เกี่ยวกับโทรศัพท์> สถานะแตกต่างจากที่แอปพลิเคชันคิด

ฉันได้ทำการแก้ไขปัญหาโดยเพิ่มรหัสนี้ก่อน:

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

นั่นเสียงกระดิ่งให้กับทุกคนหรือไม่


2

ใน Kotlin โดยไม่มีตัวจัดรูปแบบ

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

2

ในกิจกรรมของคุณฟังก์ชั่นต่อไปนี้getIpAddress(context)จะคืนค่าที่อยู่ IP ของโทรศัพท์:

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

ฉันได้รับ 0.0.0.0
natsumiyu

โทรศัพท์ของคุณเชื่อมต่อกับเครือข่าย wifi หรือไม่ ค่าใดที่ถูกส่งคืนถ้าคุณเรียกใช้ wifiManager.getConnectionInfo (). getSSID ()
matdev

มันจะใช้งานได้กับอุปกรณ์ที่เชื่อมต่อกับ Mobile Data ไม่ใช่ WiFi หรือไม่
Sergey

ไม่วิธีนี้ใช้ได้เฉพาะเมื่ออุปกรณ์เชื่อมต่อกับ WiFi
matdev

1

นี่คือรุ่น kotlin ของ @Nilesh และ @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
}

1
หากนี่เป็นรูปแบบรหัสของคุณในโครงการจริงฉันขอแนะนำให้คุณอ่าน "รหัสสะอาด" โดย robert martin
Ahmed Adel Ismail

1

อุปกรณ์อาจมีที่อยู่ IP หลายแห่งและที่อยู่ที่ใช้งานในแอพเฉพาะอาจไม่ใช่ IP ที่เซิร์ฟเวอร์ที่ได้รับการร้องขอจะเห็น อันที่จริงผู้ใช้บางคนใช้ VPN หรือพร็อกซี่เช่นCloudflare Warp

หากจุดประสงค์ของคุณคือรับที่อยู่ IP ตามที่แสดงโดยเซิร์ฟเวอร์ที่รับคำขอจากอุปกรณ์ของคุณวิธีที่ดีที่สุดคือสอบถามบริการระบุตำแหน่งทางภูมิศาสตร์ IP เช่นIpregistry (ข้อจำกัดความรับผิดชอบ: ฉันทำงานให้ บริษัท ) กับไคลเอนต์ Java:

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

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

นอกเหนือจากการใช้งานง่ายจริง ๆ คุณจะได้รับข้อมูลเพิ่มเติมเช่นประเทศภาษาสกุลเงินเขตเวลาสำหรับ IP ของอุปกรณ์และคุณสามารถระบุได้ว่าผู้ใช้กำลังใช้พร็อกซีหรือไม่


1

นี่เป็นวิธีที่ง่ายที่สุดและง่ายที่สุดที่เคยมีในอินเทอร์เน็ต ... ก่อนอื่นเพิ่มสิทธิ์นี้ไปยังไฟล์ Manifest ของคุณ ...

  1. "อินเทอร์เน็ต"

  2. "ACCESS_NETWORK_STATE"

เพิ่มสิ่งนี้ในไฟล์สร้างของกิจกรรม ..

    getPublicIP();

ตอนนี้เพิ่มฟังก์ชั่นนี้ใน MainActivity.class ของคุณ

    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();

    }


urls.get (0) มีที่อยู่ IP สาธารณะของคุณ
เซียมูฮัมหมัด

คุณต้องประกาศในไฟล์กิจกรรมของคุณดังนี้: ArrayList <String> urls = new ArrayList <String> (); // เพื่ออ่านแต่ละบรรทัด
เซียมุฮัมมัด


0

กรุณาตรวจสอบรหัสนี้ ... ใช้รหัสนี้ เราจะรับไอพีจากอินเทอร์เน็ตบนมือถือ ...

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

0

ฉันไม่ได้ทำ Android แต่ฉันจะแก้ไขปัญหานี้ในวิธีที่แตกต่างกันโดยสิ้นเชิง

ส่งข้อความค้นหาถึง Google เช่น: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

และอ้างถึงฟิลด์ HTML ที่มีการโพสต์คำตอบ คุณสามารถสอบถามโดยตรงไปยังแหล่งที่มา

Google จะชอบอยู่ที่นั่นนานกว่าใบสมัครของคุณ

โปรดจำไว้ว่าอาจเป็นเพราะผู้ใช้ของคุณไม่มีอินเทอร์เน็ตในเวลานี้สิ่งที่คุณต้องการจะเกิดขึ้น!

โชคดี


! ที่น่าสนใจ และฉันคิดว่า Google มีการเรียก API บางประเภทที่จะคืนค่า IP ของคุณซึ่งจะมีเสถียรภาพมากกว่าการสแกน HTML
Scott Biggs

0

คุณสามารถทำได้

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

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

0

ในความซื่อสัตย์ทั้งหมดฉันคุ้นเคยกับความปลอดภัยของรหัสเพียงเล็กน้อยดังนั้นนี่อาจเป็นการแฮ็ก แต่สำหรับฉันนี่เป็นวิธีที่หลากหลายที่สุดที่จะทำ:

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

0

รวบรวมแนวคิดบางอย่างเพื่อรับ wifi ip จากWifiManagerโซลูชัน not kotlin ใน:

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

หรือคุณสามารถรับที่อยู่ ip ของอุปกรณ์วนรอบ ip4 ผ่านทาง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()

-2

ตามข้อเสนอของฉันสิ่งนี้คือข้อเสนอของฉัน

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) {}
   }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.