Android应用如何获取公网IPv4地址?两种尝试方法均返回空值
解决Android获取公网IPv4地址的问题
先明确两种方法的核心问题
第一种方法的本质缺陷
你写的getIPAddress()是遍历设备本地网络接口,只能拿到局域网IPv4地址(比如192.168.x.x、10.x.x.x这类),完全无法获取公网IP,直接放弃这个方法即可。
第二种方法失效的常见原因
getPublicIPv4Address()本身逻辑没问题,但返回空值大概率是以下两个原因:
- 缺少
INTERNET权限,导致应用无法发起网络请求 - 在Android主线程中调用该方法,触发
NetworkOnMainThreadException,进入异常分支返回null
修复方案
1. 添加必要权限
在AndroidManifest.xml中添加网络权限:
<uses-permission android:name="android.permission.INTERNET" />
2. 将网络请求移至子线程
Android从3.0开始禁止主线程执行网络操作,必须把请求放到子线程。推荐用Kotlin协程实现,代码更简洁且符合现代Android开发规范:
第一步:添加协程依赖(如果项目未引入)
在模块级build.gradle(或build.gradle.kts)的dependencies块中添加:
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
第二步:修复后的公网IP获取方法
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.net.HttpURLConnection import java.net.URL import java.io.BufferedReader suspend fun getPublicIPv4Address(): String? { return withContext(Dispatchers.IO) { var publicIP: String? = null var connection: HttpURLConnection? = null try { val url = URL("https://api.ipify.org") connection = url.openConnection() as HttpURLConnection connection.apply { requestMethod = "GET" connectTimeout = 5000 readTimeout = 5000 setRequestProperty("Accept", "text/plain") } if (connection.responseCode == HttpURLConnection.HTTP_OK) { BufferedReader(connection.inputStream).use { reader -> // 直接读取一行即可,api.ipify返回纯文本IP publicIP = reader.readLine() } } else { // 打印响应码方便排查问题 println("请求失败,响应码:${connection.responseCode}") } } catch (e: Exception) { e.printStackTrace() } finally { // 确保网络连接关闭 connection?.disconnect() } publicIP } }
第三步:在合适的作用域中调用方法
比如在Activity中调用:
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.Dispatchers class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 在协程中调用获取IP的方法 GlobalScope.launch(Dispatchers.Main) { val publicIp = getPublicIPv4Address() // 处理结果,比如显示到UI或用于API调用 publicIp?.let { println("公网IPv4地址:$it") } ?: run { println("获取公网IP失败") } } } }
额外排查建议
- 如果仍无法获取IP,检查设备网络连接状态,确保能正常访问外网
- 若
api.ipify.org访问不稳定,可替换为其他纯文本返回的公网IPAPI,比如https://icanhazip.com/或https://api.ip.sb/ip
内容的提问来源于stack exchange,提问作者Ripped_Asssasin
相关产品推荐
相关产品推荐

