在 activity 中获取 IP 会导致崩溃

Getting IP inside activity causes crash

我正在创建一个 android 应用程序,以 link 和 t运行 通过 wifi 将套接字数据包发送到服务器。为此,必须定义所连接服务器的 IP 地址。我使用下面的函数来获取 IP 地址。当我硬编码 SERVER_IP = "0";该应用程序运行正常。请帮忙!

    private final String SERVER_IP = getIpAddr();

    public String getIpAddr() {
    WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
    WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    int ip = wifiInfo.getIpAddress();

    String ipString = String.format(
            "%d.%d.%d.%d",
            (ip & 0xff),
            (ip >> 8 & 0xff),
            (ip >> 16 & 0xff),
            (ip >> 24 & 0xff));

    return ipString;
}

完成上述设置后,我运行在 OnCreate 函数中编写了以下代码。

class ClientThread implements Runnable {

    @Override
    public void run() {
        try {
            InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
            socket = new Socket(serverAddr, SERVERPORT);
        } catch (UnknownHostException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
}

一旦发生这种情况,我的 android 应用程序将停止工作。

这是出现的错误:

Java.lang.NullPointerException: 尝试在空对象引用

上调用虚拟方法'android.content.Context android.content.Context.getApplicationContext()'

以下是您必须检查的一些事项

  • 应用程序是否有访问WiFi的权限?
  • 如果您在不同的 class 中使用 getApplicationContext() ,请传递来自父 Activity 的上下文。
  • 在移动设备而不是模拟器上进行测试。

使用此函数获取 activity:

中的 IP(v4 或 v6)
// Get IP address from first non-localhost interface
// @param ipv4  true returns ipv4
//              false returns ipv6
// @return address or empty string
public static String getLocalIpAddress(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 ex) { } // for now eat exceptions
    return "";
}

需要的时候,这样称呼即可:getLocalIpAddress(true)。您将获得 IP 作为字符串供您使用。