Android Jetpack Compose Get Client Public Ip Address

Put the function in ViewModel or Singleton.

  • The only way to get public ip seems to be via external website returning the client's connectiong ip address.
import kotlinx.coroutines.channels.awaitCloseimport kotlinx.coroutines.flow.callbackFlowimport kotlinx.coroutines.flow.catchimport kotlinx.coroutines.flow.flowimport okhttp3.*import okhttp3.Request.Builderimport java.io.IOExceptionclass Util {    companion object {    /*    fun getIpv4HostAddress(): String? {        try {            NetworkInterface.getNetworkInterfaces()?.toList()?.map { networkInterface ->                networkInterface.inetAddresses?.toList()?.find {                    !it.isLoopbackAddress && it is Inet4Address                }?.let { return it.hostAddress }            }            return null        } catch (e: Exception) {            return null        }    }     */    /*    fun getPublicIp(): String? {        val urls = listOf("https://ifcfg.me/", "https://icanhazip.com/")        for (url in urls) {            try {                val ipAddress = getHttpRaw(url)                if (ipAddress != null) return ipAddress            }            catch (e: Exception) {                Timber.e("getPublicIp: $url")                throw e            }        }        return null    }     */    fun getHttpRawFlow(url: String) = callbackFlow {        val client = OkHttpClient()        val request: Request = Builder()            .url(url)            .build()        client.newCall(request).enqueue(object : Callback {            override fun onFailure(call: Call, e: IOException) {                close(e)            }            override fun onResponse(call: Call, response: Response) {                response.use {                    if (!response.isSuccessful) close(IOException("Unexpected code $response"))                    // close(Exception("TEST"))                    trySend(response.body!!.string())                }            }        })        awaitClose { }    }    val getPublicIpFlow = flow {        val urls = listOf("https://ifcfg.me/", "https://icanhazip.com/")        for (url in urls) {            getHttpRawFlow(url)                .catch { Timber.e(it, "getHttpRawFlow=$url") }                .collect {                    emit(it)                }        }    }  }}

NOTE: OkHttp is required.

Usage

val ipAddress by Util.getPublicIpFlow.collectAsState(initial = null)

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.