Android:WifiInfo.getIpAddress()已废弃

4

API 31已废弃getIpAddress()方法。需要帮助从回调实现中获取地址。

val networkCallback = object : ConnectivityManager.NetworkCallback() {

    override fun onAvailable(network: Network) {}


    @RequiresApi(Build.VERSION_CODES.Q)
    override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
        super.onCapabilitiesChanged(network, networkCapabilities)
        val wifiInfo = networkCapabilities.transportInfo as? WifiInfo
    }

    override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
        super.onLinkPropertiesChanged(network, linkProperties)
        // val ipV4Address = ?

    }
};

5个回答

7

对于被弃用的方法,您可以阅读官方Android文档,正如文档所述:

此方法已从API级别31开始弃用。请使用可通过NetworkCallback#onLinkPropertiesChanged(Network,LinkProperties)或ConnectivityManager#getLinkProperties(Network)获得的LinkProperties上的方法。

因此,通过我在这里添加的方法,您可以获得所有IP地址:

   private fun getIpAddress() {
    val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE)
     if (connectivityManager is ConnectivityManager) {
        var link:LinkProperties =  connectivityManager.getLinkProperties(connectivityManager.activeNetwork) as LinkProperties
         Log.e("NETWOOOOOOOOOOOORK", link.linkAddresses.toString())
    }

}

注意:link.linkAddresses方法可能返回地址数组


它工作了!!谢谢 - Breimer

5

在Wifi网络中获取IP地址(例如192.168.1.123)的方法:

fun Context.getConnectivityManager() = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

fun getIpAddress(context: Context) = with(context.getConnectivityManager()) {
    getLinkProperties(activeNetwork)!!.linkAddresses[1].address.hostAddress!!
}

谢谢您的回答。我正在使用这个解决方案,我想访问linkAddresses[1],linkAddresses的大小应该是2或更多。是否会有link地址大小小于2的情况(需要处理此场景)?我找不到关于linkAddresses大小和传递值的顺序的任何文档。 - Rachita Nanda
@Rachita Nanda 我也不确定,我能找到的唯一信息是这个:https://developer.android.com/reference/android/net/LinkProperties#getLinkAddresses()。 - Sam Chen

3

如果您不想使用回调方法,现在可以通过ConnectivityManager.getLinkProperties()函数获取IP地址。根据链接中的文档,此函数自API 21(Android 5)起可用,因此,如果您的minSDK>= 21,则可以使用建议的方法替换当前获取IP地址的方法:

val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

val linkAddresses = connectivityManager?.getLinkProperties(connectivityManager.activeNetwork)?.linkAddresses

val ipV4Address = linkAddresses?.firstOrNull { linkAddress ->
                linkAddress.address.hostAddress?.contains('.') ?: false }?.address?.hostAddress

你需要过滤返回结果,因为可能会有多个ipV6地址和一个ipV4地址。以下是未经过滤从linkAddresses返回的内容: enter image description here 这就是为什么这里的其他答案并不完全正确,因为没有人保证ipV4地址将在索引1下。

0
Java 代码:
public static Optional<String> getIPv4Address(Context context) {
    var connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager instanceof ConnectivityManager cm) {
        LinkProperties link = cm.getLinkProperties(cm.getActiveNetwork());

        Log.e("IPAddress List", link.getLinkAddresses().toString()); 
        
        // return only one IPv4Address
        return link.getLinkAddresses().stream()
                .filter(linkAddress -> linkAddress.getAddress().getAddress().length == 4)
                .findFirst()
                .map(LinkAddress::toString);
    }
    return Optional.empty();
}

欢迎来到stackoverflow。请修改您的答案,并解释一下为什么您的代码可以解决这个问题。https://stackoverflow.com/help/how-to-answer - DJSDev

0
private fun getDeviceIpAddress(): String? {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
        val ipAddressInt = wifiManager.connectionInfo.ipAddress
        val ipAddress: String? = Formatter.formatIpAddress(ipAddressInt)
        if (ipAddress.isNullOrBlank() || ipAddress.isEmpty()) {
            return String.format(
                "%d.%d.%d.%d", ipAddressInt and 0xff, ipAddressInt shr 8 and 0xff,
                ipAddressInt shr 16 and 0xff, ipAddressInt shr 24 and 0xff
            )
        }
    } else {
        val linkProperties =
            connManager.getLinkProperties(connManager.activeNetwork)
        linkProperties?.let { linkProp ->
            for (linkAddress in linkProp.linkAddresses) {
                val inetAddress = linkAddress.address
                if (inetAddress is Inet4Address
                    && !inetAddress.isLoopbackAddress()
                    && inetAddress.isSiteLocalAddress()
                ) {
                    return inetAddress.getHostAddress()
                }
            }
        }
    }
    return ""
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接