Kotlin主机端热点应用:如何获取已连接客户端的WiFi名称?
实现建议:获取热点客户端的WiFi名称
首先明确:Android系统没有直接API能获取连接到热点的客户端自身的WiFi名称(即客户端的SSID),因为热点的ARP表/DHCP日志仅记录客户端的IP、MAC地址,不会同步客户端的WiFi配置信息。以下是几种可行的间接实现方案:
方案1:ARP表解析+反向DNS查询获取设备主机名
大部分设备的主机名会包含设备标识甚至WiFi相关信息,可通过读取系统ARP表获取客户端IP,再反向解析主机名:
代码实现(Kotlin)
data class ClientDevice( val ip: String, val mac: String, val hostName: String ) fun getConnectedHotspotClients(): List<ClientDevice> { val clients = mutableListOf<ClientDevice>() runCatching { BufferedReader(FileReader(File("/proc/net/arp"))).use { reader -> reader.readLine() // 跳过表头行 var line: String? while (reader.readLine().also { line = it } != null) { val segments = line!!.split("\\s+".toRegex()) if (segments.size >= 4) { val ip = segments[0] val mac = segments[3] // 尝试反向解析主机名 val hostName = runCatching { InetAddress.getByName(ip).canonicalHostName }.getOrDefault("Unknown") clients.add(ClientDevice(ip, mac, hostName)) } } } }.onFailure { it.printStackTrace() } return clients }
注意事项
- 需要在Manifest中添加权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - 反向DNS解析依赖设备支持,部分设备可能返回IP而非主机名
方案2:mDNS服务发现获取设备信息
利用Android的NsdManager扫描局域网内的mDNS服务,多数智能设备会通过mDNS广播自身信息,其中可能包含设备名称或WiFi相关标识:
代码实现(Kotlin)
class HotspotClientDiscovery(private val context: Context) { private val nsdManager = context.getSystemService(Context.NSD_SERVICE) as NsdManager private var discoveryListener: NsdManager.DiscoveryListener? = null private val multicastLock: WifiManager.MulticastLock init { val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager multicastLock = wifiManager.createMulticastLock("HotspotClientDiscoveryLock") } fun startDiscovery(onDeviceFound: (NsdServiceInfo) -> Unit) { multicastLock.acquire() discoveryListener = object : NsdManager.DiscoveryListener { override fun onDiscoveryStarted(serviceType: String) {} override fun onServiceFound(serviceInfo: NsdServiceInfo) { onDeviceFound(serviceInfo) } override fun onServiceLost(serviceInfo: NsdServiceInfo) {} override fun onDiscoveryStopped(serviceType: String) {} override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) {} override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) {} } // 扫描全量服务类型,可根据需求指定特定类型如"_http._tcp." nsdManager.discoverServices("_services._dns-sd._udp.", NsdManager.PROTOCOL_DNS_SD, discoveryListener) } fun stopDiscovery() { discoveryListener?.let { nsdManager.stopServiceDiscovery(it) } multicastLock.release() } } // 使用示例 // val discovery = HotspotClientDiscovery(context) // discovery.startDiscovery { serviceInfo -> // val deviceName = serviceInfo.serviceName // val clientIp = serviceInfo.host?.hostAddress // // 处理设备信息 // }
注意事项
- 需要添加权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> - 多播锁必须在扫描时持有,使用后释放,否则可能无法接收mDNS包
方案3:客户端主动上报WiFi信息(需客户端配合)
如果能控制连接热点的客户端应用,可让客户端在连接热点后通过UDP广播或Socket主动发送自身的WiFi名称,主机端接收后展示:
主机端监听代码
fun startUdpListener(onWifiInfoReceived: (ssid: String, mac: String) -> Unit) { Thread { runCatching { DatagramSocket(12345).use { socket -> val buffer = ByteArray(1024) while (true) { val packet = DatagramPacket(buffer, buffer.size) socket.receive(packet) val message = String(packet.data, 0, packet.length) // 解析客户端发送的信息,格式示例:"SSID:MyHomeWiFi,MAC:aa:bb:cc:dd:ee:ff" val ssid = message.split(",").find { it.startsWith("SSID:") }?.substring(5) ?: "Unknown" val mac = message.split(",").find { it.startsWith("MAC:") }?.substring(4) ?: "Unknown" onWifiInfoReceived(ssid, mac) } } }.onFailure { it.printStackTrace() } }.start() }
客户端发送代码
fun reportWifiInfoToHotspotHost() { val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager val currentSsid = wifiManager.connectionInfo.ssid.replace("\"", "") val macAddress = wifiManager.connectionInfo.macAddress ?: "Unknown" val message = "SSID:$currentSsid,MAC:$macAddress" val hotspotGatewayIp = "192.168.43.1" // Android热点默认网关IP,若修改过需对应调整 runCatching { DatagramSocket().use { socket -> val packet = DatagramPacket( message.toByteArray(), message.length, InetAddress.getByName(hotspotGatewayIp), 12345 ) socket.send(packet) } }.onFailure { it.printStackTrace() } }
注意事项
- 客户端需要
ACCESS_WIFI_STATE权限获取自身WiFi信息 - 需确保主机和客户端使用相同的端口和消息格式
内容的提问来源于stack exchange,提问作者David Ansu Dave
相关产品推荐
相关产品推荐

