Android:WifiInfo.getIpAddress()已弃用

rt4zxlrg  于 2023-05-15  发布在  Android
关注(0)|答案(5)|浏览(225)

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 = ?

    }
};
vxqlmq5t

vxqlmq5t1#

对于已弃用的方法,您可以阅读正式的android文档,如documnet syas:
此方法已在API级别31中弃用。使用LinkProperties上的方法,这些方法可以通过NetworkCallback#onLinkPropertiesChanged(Network,LinkProperties)或ConnectivityManager#getLinkProperties(Network)获得。
因此,通过我在这里添加方法,您可以获得所有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方法可能返回地址数组

kmpatx3s

kmpatx3s2#

在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!!
}
c3frrgcw

c3frrgcw3#

如果不想使用回调方法,现在应该通过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返回的未过滤的内容:

这就是为什么这里的其他答案之一不完全正确,因为没有人保证ipV4地址将在索引1下。

yqyhoc1h

yqyhoc1h4#

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

of1yzvn45#

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

相关问题