公司有這樣一個應用場景:有一臺球機設備,是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 nullval networkCapabilities: NetworkCapabilities = cm.getNetworkCapabilities(activeNetwork) ?: return nullif (!networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) return nullval linkProperties: LinkProperties = cm.getLinkProperties(cm.activeNetwork) ?: return nullreturn 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呢。