如何获取连接至移动热点与WiFi的客户端设备详情?
可行解决方案
1. 适配Android 10+的权限配置
- 必须申请
ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限,且需用户主动授权(网络扫描依赖位置权限) - Android 12及以上版本,额外声明
NEARBY_WIFI_DEVICES权限,该权限无需位置授权弹窗,Manifest配置如下:<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" /> - 若目标版本为Android 13+,
ACCESS_FINE_LOCATION仅用于位置相关功能,获取WiFi设备信息优先使用NEARBY_WIFI_DEVICES
2. 替代/proc/net/arp的网络设备扫描方案
/proc/net/arp在Android 10+被系统限制访问,推荐使用官方API结合子网扫描:
- 先通过
WifiManager获取当前网络的子网段:val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager val dhcpInfo = wifiManager.dhcpInfo val subnetBase = dhcpInfo.ipAddress and dhcpInfo.netmask - 遍历子网内的IP地址,通过
InetAddress.isReachable()检测在线设备:for (i in 1..254) { val ipInt = (subnetBase shl 8) + i val ipAddress = String.format( "%d.%d.%d.%d", (ipInt shr 24) and 0xff, (ipInt shr 16) and 0xff, (ipInt shr 8) and 0xff, ipInt and 0xff ) val inetAddress = InetAddress.getByName(ipAddress) if (inetAddress.isReachable(1000)) { val deviceName = inetAddress.hostName // 后续处理设备信息 } }
3. MAC地址获取的替代方法
Android 10+禁止直接获取其他设备的MAC地址,可通过以下方式尝试:
- mDNS设备发现:使用
NsdManager扫描网络内的mDNS服务,部分设备会广播名称、IP及MAC相关信息:val nsdManager = context.getSystemService(Context.NSD_SERVICE) as NsdManager val discoveryListener = object : NsdManager.DiscoveryListener { override fun onDiscoveryStarted(regType: String) {} override fun onServiceFound(serviceInfo: NsdServiceInfo) { val deviceName = serviceInfo.serviceName val ip = serviceInfo.host?.hostAddress // 部分设备的MAC可通过解析serviceInfo属性获取 } override fun onServiceLost(serviceInfo: NsdServiceInfo) {} override fun onDiscoveryStopped(regType: String) {} override fun onStartDiscoveryFailed(regType: String, errorCode: Int) {} override fun onStopDiscoveryFailed(regType: String, errorCode: Int) {} } // 扫描HTTP服务,可替换为其他服务类型如_ssh._tcp. nsdManager.discoverServices("_http._tcp.", NsdManager.PROTOCOL_DNS_SD, discoveryListener) - 热点连接设备专属API:若你的应用是热点创建者,Android 12+可通过
WifiManager.getConnectedStations()获取连接设备的MAC、IP及名称:val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager val connectedStations = wifiManager.connectedStations connectedStations.forEach { station -> val mac = station.macAddress val ip = station.ipAddress?.let { String.format( "%d.%d.%d.%d", (it shr 24) and 0xff, (it shr 16) and 0xff, (it shr 8) and 0xff, it and 0xff ) } val deviceName = station.deviceName }
4. 权限申请的注意事项
- 动态申请权限时,需向用户明确说明权限用途(如“需要获取网络设备信息以展示连接到热点的设备”),提升授权率
- Android 12+优先请求
NEARBY_WIFI_DEVICES权限,避免触发位置权限弹窗,优化用户体验
内容的提问来源于stack exchange,提问作者Android Developer
相关产品推荐
相关产品推荐

