公司有这样一个应用场景:有一台球机设备,是Android系统的,它不像手机,它没有触摸屏幕,所以我们对球机的操作很不方便,于是我们搞这样一个设置:点击球机电源键5次分享出一个热点,然后我们用手机连接上这个热点,这样手机和球机就有了连接,我们想通过手机来修改球机的设置,这需要在球机上运行一个Web服务器,以便提供一些API接口来让手机访问,访问不同的API修改不同的设置。现在的问题是,手机连接热点之后,我们要访问球机时需要知道球的ip地址是多少,而且球机分享的热点的本机ip地址每次都不一样,如何通过代码在手机上获取到球机的ip地址,以便进行http通信。解决方案如下:
-
添加权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-
代码
fun getWifiRouteIpAddress(): String? { val cm = (getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager) val activeNetwork: Network = cm.activeNetwork ?: return null val networkCapabilities: NetworkCapabilities = cm.getNetworkCapabilities(activeNetwork) ?: return null if (!networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) return null val linkProperties: LinkProperties = cm.getLinkProperties(cm.activeNetwork) ?: return null return linkProperties.routes.first { it.isDefaultRoute }?.gateway?.hostAddress }
如上代码可以获取到连接的wifi的路由ip地址,它和wifi的网关是一样的,通过该ip地址,手机就能访问到球机。我们公司的wifi是192.168.1.xxx网段的,如果连接上公司的wifi,拿到的网关地址为:192.168.1.1
另外:linkProperties.dhcpServerAddress
也可以获取到球机的dhcp服务器地址,它也是和网关一样的,但是这个函数是Android 11才出的api,在低版本不可用。linkProperties.dnsServers
拿到的是dns服务器的地址,和网关也是一样的,这个函数在Android 5.0的时候就出了。不知道是否所有的Android设备分享的热点都会把 dhcp服务器地址 和 dns服务器地址都设置成和网关一样,大家如果要用这两个函数的话可以多找几台设备分享热点,然后连接这些热点看获取的 dhcp 和 dns 地址是否都和网关一样。在Windows系统上,通过查看网络状态可以看到这些信息,如下:
这里我们可能通过路由、dhcp、dns来获取网关地址,奇怪的是Android官网为什么不提供一个直接获取网关的api呢。