Làm cách nào để lấy địa chỉ IP của thiết bị từ mã?


384

Có thể lấy địa chỉ IP của thiết bị bằng một số mã không?


5
Đừng quên rằng đây là tập hợp có kích thước N và bạn không thể cho rằng N == (0 || 1). Nói cách khác, đừng cho rằng một thiết bị chỉ có một cách nói chuyện với mạng và đừng cho rằng thiết bị đó có bất kỳ cách nào để nói chuyện với mạng cả.
James Moore



Bạn nên lấy nó từ một dịch vụ bên ngoài ipof.in/txt là một trong những dịch vụ như vậy
vivekv

Có thể lấy nó theo chương trình trong Android?
Tanmay Sahoo

Câu trả lời:


434

Đây là người trợ giúp của tôi sử dụng để đọc địa chỉ IP và MAC. Triển khai là java thuần túy, nhưng tôi có một khối nhận xét trong getMACAddress()đó có thể đọc giá trị từ tệp Linux (Android) đặc biệt. Tôi chỉ chạy mã này trên một số thiết bị và Trình giả lập nhưng hãy cho tôi biết ở đây nếu bạn thấy kết quả lạ.

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

}

Tuyên bố miễn trừ trách nhiệm: Ý tưởng và mã ví dụ cho lớp Utils này đến từ một số bài đăng SO và Google. Tôi đã làm sạch và hợp nhất tất cả các ví dụ.


17
Điều này yêu cầu API cấp 9 trở lên vì getHardwareAddress ().
Calvin

2
Vấn đề - cảnh báo lint trên toUpperCase(). Bắt Exceptionluôn luôn tinh ranh (và các phương thức của người trợ giúp nên ném bằng mọi cách và để người gọi xử lý Ngoại lệ - mặc dù không sửa đổi điều này). Định dạng: nên không quá 80 dòng. Thực hiện có điều kiện cho getHardwareAddress()- patch: github.com/Utumno/AndroidHelpers/commit/ mẹo . Bạn nói gì
Mr_and_Mrs_D

5
Nếu bạn đang sử dụng mạng cục bộ (ví dụ: Wifi hoặc trình giả lập), bạn sẽ nhận được một địa chỉ IP riêng. Bạn có thể nhận địa chỉ IP proxy thông qua yêu cầu đến một trang web cụ thể cung cấp cho bạn địa chỉ proxy, ví dụ whatismyip.akamai.com
Julien Kronegg

1
Điều này hoạt động hoàn hảo đối với tôi với thiết bị thực sự sử dụng Wifi. Cảm ơn rất nhiều,
anh bạn

5
Tôi đang nhận được kết quả xấu từ điều này trên Nexus 6 khi cố gắng lấy địa chỉ IP. Tôi có NetworkInterface với tên "name: dummy0 (dummy0)" cung cấp địa chỉ có định dạng "/ XX :: XXXX: XXXX: XXXX: XXXX% dummy0", nhưng cũng có giao diện mạng thực sự tương ứng với wlan0, nhưng cũng có giao diện mạng thực sự tương ứng với wlan0, nhưng kể từ khi "hình nộm" xảy ra đầu tiên, tôi luôn nhận được địa chỉ giả đó
Julian Suarez

201

Điều này làm việc cho tôi:

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

10
cái này làm việc cho tôi tuy nhiên, nó cần có quyền "ACCESS_WIFI_STATE" và như "Umair" đã viết, việc sử dụng danh sách là không cần thiết.
nhà phát triển Android

13
formatIpAddress bị phản đối vì một số lý do. Nên dùng cái gì thay thế?
nhà phát triển Android

8
Từ các tài liệu: Sử dụng getHostAddress(), hỗ trợ cả địa chỉ IPv4 và IPv6. Phương pháp này không hỗ trợ địa chỉ IPv6.
Ryan R

7
Làm thế nào để sử dụng gethostAddress () trong việc lấy địa chỉ IP của máy chủ và máy khách @RyanR?
gumuruh

42
Điều này sẽ vẫn hoạt động ngay cả khi người dùng sử dụng dữ liệu thay vì wifi?
PinoyCoder

65

Tôi đã sử dụng mã sau: Lý do tôi sử dụng hashCode là vì tôi nhận được một số giá trị rác được gắn vào địa chỉ IP khi tôi sử dụng getHostAddress. Nhưng tôi hashCodeđã làm việc rất tốt vì tôi có thể sử dụng Formatter để lấy địa chỉ IP với định dạng chính xác.

Đây là ví dụ đầu ra:

1. sử dụng getHostAddress:***** IP=fe80::65ca:a13d:ea5a:233d%rmnet_sdio0

2. sử dụng hashCodeFormatter: ***** IP=238.194.77.212

Như bạn có thể thấy phương pháp thứ 2 cho tôi chính xác những gì tôi cần.

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()sẽ làm tương tự như các công cụ định dạng bạn đã thêm.
Phil

10
Sử dụng hashCode hoàn toàn sai và trả về vô nghĩa. Sử dụng InetAddress.gethostAddress () để thay thế.
Con trỏ Null

thay đổi phần này: if (! inetAddress.isLoopbackAddress ()) {String ip = Formatter.formatIpAddress (inetAddress.hashCode ()); Log.i (TAG, "***** IP =" + ip); trả lại ip; } với điều này: if (! inetAddress.isLoopbackAddress () && InetAddressUtils.isIPv4Address (inetAddress.gethostAddress ())) {return inetAddress .gethostAddress (). } điều này sẽ cung cấp cho bạn định dạng ip chính xác
Chuy47

Mã chỉ trả về IP đầu tiên, một điện thoại có thể có địa chỉ celluar, WIFI và BT cùng lúc
reker

@ Chuy47 nó nói InetAddressUtils không thể được tìm thấy
FabioR 16/07/19

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

Tôi đã thêm inetAddressinstanceof Inet4Addressđể kiểm tra xem đó có phải là địa chỉ ipv4 không.


đã cứu ngày của tôi! cảm ơn. Đây là mã duy nhất hoạt động trên samsung s7 edge
Dhananjay Sarsonia

Đây là câu trả lời thực sự, thay vì ở trên chỉ có giao diện WiFi.
nyconing

Đây thực sự phải là câu trả lời chính xác, nó hoạt động cho cả WiFi và mạng di động và sử dụng "gethostAddress" thay vì định dạng tùy chỉnh.
Balázs Gerlei

Tuy nhiên, nó nhận được IP cục bộ của tôi, tôi cần IP công cộng của mình (vì tôi tin rằng OP cũng cần)
FabioR 16/07/19

53

Mặc dù có một câu trả lời đúng, tôi chia sẻ câu trả lời của mình ở đây và hy vọng rằng cách này sẽ thuận tiện hơn.

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
Cảm ơn! Formatter không được dùng nữa và tôi thực sự không cảm thấy muốn viết logic bit đơn giản.
William Morrison

4
Hoạt động rất tốt, nhưng cần có sự cho phép của WIFI_STATE:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Brent Faust

1
Tôi sử dụng formaater nhưng nó không hoạt động. Nó thật tuyệt! Rất cảm kích. Bạn có thể giải thích những gì được thực hiện trong dòng cuối cùng. Tôi biết% d.% D.% D.% D tuy nhiên những người khác? Cảm ơn
Günay Gültekin

1
Không, điều này không trả lời trực tiếp cho OP. Bởi vì không phải tất cả các thiết bị Android sử dụng WiFi để kết nối với internet. Nó có thể có mạng LAN NATed trên Ethernet, hoặc BT và không kết nối mạng NAT, v.v.
nyconing

31

Mã dưới đây có thể giúp bạn .. Đừng quên thêm quyền ..

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

Thêm quyền dưới đây trong tệp kê khai.

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

hạnh phúc mã hóa !!


6
Này, điều này trả về một giá trị không chính xác như: "fe80 :: f225: b7ff: fe8c: d357% wlan0"
Jorgesys

@Jorgesys kiểm tra câu trả lời của evertvandenbruel, nơi anh ta đã thêm inetAddress instanceof Inet4Address
temirbek

3
thay đổi nếu điều kiện như thế này để có được ip chính xác: if (! inetAddress.isLoopbackAddress () && inetAddress instanceof Inet4Address)
Rajesh.k

Mã chỉ trả về IP đầu tiên, một điện thoại có thể có địa chỉ celluar, WIFI và BT cùng lúc
reker

Nếu bạn có một điểm truy cập trên, bạn có thể nhận được nhiều hơn một ip
Harsha

16

Bạn không cần phải thêm quyền như trường hợp với các giải pháp được cung cấp cho đến nay. Tải xuống trang web này dưới dạng chuỗi:

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

hoặc là

http://www.telize.com/geoip

Tải xuống một trang web dưới dạng một chuỗi có thể được thực hiện với mã java:

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

Phân tích đối tượng JSON như thế này:

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

Thuộc tính json "truy vấn" hoặc "ip" chứa địa chỉ IP.


2
cái này cần kết nối Internet. Vấn đề lớn
David

4
Tại sao đó là một vấn đề lớn? Tất nhiên bạn cần có kết nối internet vì một địa chỉ IP có liên quan về mặt kỹ thuật với kết nối như vậy. Nếu bạn rời khỏi nhà và đến một nhà hàng, bạn sẽ sử dụng một kết nối internet khác và do đó là một địa chỉ IP khác. Bạn không cần một cái gì đó để thêm nhiều hơn như ACCESS_NETWORK_STATE hoặc ACCESS_WIFI_STATE. Kết nối internet là sự cho phép duy nhất bạn cần cho giải pháp do tôi cung cấp.
Daan

2
Tên miền nào? Nếu ip-api.com không hoạt động, bạn có thể sử dụng telize.com làm dự phòng. Nếu không, bạn có thể sử dụng api.ipify.org . Nó cũng có sẵn ở đây (không phải json): ip.jsontest.com/?callback=showIP . Nhiều ứng dụng sử dụng các tên miền được đảm bảo vẫn trực tuyến; đó là bình thường. Tuy nhiên, nếu bạn sử dụng dự phòng thì rất khó có khả năng xảy ra sự cố.
Daan

3
Quan điểm ban đầu của David vẫn đứng vững. Điều gì xảy ra nếu bạn đang sử dụng mạng nội bộ không có quyền truy cập internet.
hiandbaii

2
Tôi chưa bao giờ nghĩ về điều đó bởi vì tôi không biết bất kỳ mục đích thực tế nào của một ứng dụng chắc chắn cần một mạng nhưng nên hoạt động mà không có internet (có thể có nhưng tôi không thấy nó cho các thiết bị di động).
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
có thể điều này sẽ trả về ip mạng riêng từ giao diện wifi, như 192.168.0.x? hoặc nó sẽ luôn trả về địa chỉ IP bên ngoài, sẽ được sử dụng trên internet?
Ben H

9

Phương thức getDeviceIpAddress trả về địa chỉ IP của thiết bị và ưu tiên địa chỉ giao diện wifi nếu được kết nối.

  @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

Đây là một bài làm lại của câu trả lời này nhằm loại bỏ thông tin không liên quan, thêm ý kiến ​​hữu ích, đặt tên biến rõ ràng hơn và cải thiện logic.

Đừng quên bao gồm các quyền sau:

<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

phiên bản tối giản kotlin

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

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

3

Chỉ cần sử dụng Volley để lấy ip từ trang web này

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

Gần đây, một địa chỉ IP vẫn được trả về bởi getLocalIpAddress() mặc dù đã bị ngắt kết nối mạng (không có chỉ báo dịch vụ). Điều đó có nghĩa là địa chỉ IP được hiển thị trong Cài đặt> Giới thiệu về điện thoại> Trạng thái khác với những gì ứng dụng nghĩ.

Tôi đã triển khai một cách giải quyết bằng cách thêm mã này trước đây:

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

Điều đó có rung chuông cho bất cứ ai?


2

trong Kotlin, không có 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 ""
}

2

Trong hoạt động của bạn, chức năng sau đây getIpAddress(context)trả về địa chỉ IP của điện thoại:

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

Tôi đang nhận được 0.0.0.0
natsumiyu

Điện thoại của bạn có kết nối với mạng wifi không? Giá trị nào được trả về nếu bạn gọi wifiManager.getConnectionInfo (). GetSSID ()?
matdev

Nó có hoạt động cho thiết bị được kết nối với Dữ liệu di động, không phải WiFi không?
Serge

Không, phương pháp này chỉ hoạt động nếu thiết bị được kết nối với WiFi
matdev

1

Đây là phiên bản kotlin của @Nilesh và @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
Nếu đây là kiểu mã của bạn trong các dự án thực tế, tôi khuyên bạn nên đọc "mã sạch" của robert martin
Ahmed Adel Ismail

1

Một thiết bị có thể có một số địa chỉ IP và địa chỉ được sử dụng trong một ứng dụng cụ thể có thể không phải là IP mà các máy chủ nhận được yêu cầu sẽ thấy. Thật vậy, một số người dùng sử dụng VPN hoặc proxy như Cloudflare Warp .

Nếu mục đích của bạn là lấy địa chỉ IP như được hiển thị bởi các máy chủ nhận yêu cầu từ thiết bị của bạn, thì tốt nhất là truy vấn dịch vụ định vị địa lý IP như Ipregistry (từ chối trách nhiệm: Tôi làm việc cho công ty) với máy khách Java của nó:

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

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

Ngoài việc thực sự đơn giản để sử dụng, bạn còn nhận được thông tin bổ sung như quốc gia, ngôn ngữ, tiền tệ, múi giờ cho IP của thiết bị và bạn có thể xác định liệu người dùng có sử dụng proxy hay không.


1

Đây là cách dễ nhất và đơn giản nhất từng tồn tại trên internet ... Trước hết, hãy thêm quyền này vào tệp kê khai của bạn ...

  1. "INTERNET"

  2. "ACCESS_NETWORK_STATE"

thêm phần này vào tệp onCreate của Activity ..

    getPublicIP();

Bây giờ Thêm chức năng này vào MainActivity. Class của bạn.

    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) chứa địa chỉ IP công cộng của bạn.
Zia Muhammad

Bạn phải khai báo trong tệp hoạt động của mình như thế này: ArrayList <String> urls = new ArrayList <String> (); // để đọc từng dòng
Zia Muhammad

0

Nếu bạn có vỏ; ifconfig eth0 cũng hoạt động cho thiết bị x86


0

Vui lòng kiểm tra mã này ... Sử dụng mã này. chúng tôi sẽ nhận được ip từ internet di động ...

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

Tôi không làm Android, nhưng tôi sẽ giải quyết vấn đề này theo một cách hoàn toàn khác.

Gửi truy vấn tới Google, đại loại như: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

Và tham khảo trường HTML nơi phản hồi được đăng. Bạn cũng có thể truy vấn trực tiếp đến nguồn.

Google sẽ thích ở đó lâu hơn Ứng dụng của bạn.

Chỉ cần nhớ, có thể là người dùng của bạn không có internet vào thời điểm này, điều gì bạn muốn xảy ra!

Chúc may mắn


Hấp dẫn! Và tôi cá rằng Google có một số loại lệnh gọi API sẽ trả về IP của bạn, sẽ ổn định hơn so với quét HTML.
Scott Bigss

0

Bạn có thể làm được việc này

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

Thành thật mà nói, tôi chỉ hơi quen với an toàn mã, vì vậy đây có thể là hack-ish. Nhưng đối với tôi đây là cách linh hoạt nhất để làm điều đó:

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

Tổng hợp một số ý tưởng để có được ip wifi từ WifiManagergiải pháp kotlin đẹp hơn:

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

Ngoài ra, bạn có thể nhận địa chỉ ip của thiết bị loopback ip4 thông qua 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

Dựa trên những gì tôi đã thử nghiệm, đây là đề xuất của tôi

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) {}
   }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.