基于Android Kotlin扫描网络设备IP(电视遥控器开发需求)
Android Kotlin 实现局域网设备IP扫描(适配电视遥控器场景)
核心逻辑
要扫描局域网内的设备,本质是遍历当前网段的所有IP,通过端口检测或ICMP ping判断设备是否在线,再针对性筛选电视设备。
具体实现步骤
1. 获取当前设备的网段
先拿到本地设备的IP,再提取网段(比如192.168.1.100的网段是192.168.1):
fun getLocalIpAddress(): String? { NetworkInterface.getNetworkInterfaces()?.toList()?.forEach { intf -> intf.inetAddresses?.toList()?.forEach { addr -> if (!addr.isLoopbackAddress && addr is Inet4Address) { return addr.hostAddress } } } return null } fun getNetworkSegment(localIp: String): String { return localIp.substring(0, localIp.lastIndexOf(".")) }
2. 多线程并发扫描IP
单线程扫描太慢,用线程池并发处理,避免阻塞主线程:
fun scanNetwork(segment: String, onDeviceFound: (String) -> Unit) { // 控制并发数,20个线程足够兼顾速度和系统负载 val executor = Executors.newFixedThreadPool(20) for (i in 1..254) { val targetIp = "$segment.$i" executor.execute { Socket().use { socket -> try { // 1秒超时,可根据网络环境调整 socket.connect(InetSocketAddress(targetIp, 80), 1000) onDeviceFound(targetIp) } catch (e: IOException) { // 连接失败,说明设备不在线或未开放该端口,直接忽略 } } } } executor.shutdown() }
提示:电视常用开放端口有80、8080、554(RTSP),可以多试几个端口提高识别率。
3. 配置必要权限
在AndroidManifest.xml里加权限,注意Android 10+需要动态申请定位权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- Android 10及以上必须申请,否则无法获取正确的本地IP --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
4. 筛选电视设备(可选)
如果要精准定位电视,可扫描到IP后尝试访问设备的描述页面(多数智能电视支持):
fun isTvDevice(ip: String): Boolean { return try { val url = URL("http://$ip/description.xml") val connection = url.openConnection() as HttpURLConnection connection.connectTimeout = 1000 val isSuccess = connection.responseCode == HttpURLConnection.HTTP_OK val isXml = connection.contentType?.contains("xml") == true // 还可以进一步解析XML里的设备类型字段,比如是否包含"TV"关键词 isSuccess && isXml } catch (e: Exception) { false } }
调用示例
val localIp = getLocalIpAddress() localIp?.let { val networkSegment = getNetworkSegment(it) scanNetwork(networkSegment) { foundIp -> if (isTvDevice(foundIp)) { // 找到目标电视,回到主线程更新UI或保存IP作为BaseUrl runOnUiThread { // 比如把IP显示在列表里 } } } }
内容的提问来源于stack exchange,提问作者WilliamVietnam
相关产品推荐
相关产品推荐

