开发Android控制App:如何从组播地址获取Govee灯具IP?
解决Govee灯具LAN IP发现问题
首先明确:组播地址239.255.255.250本来就无法通过ping响应,因为组播是一对多通信机制,ping是单播ICMP请求,设备不会回包。你需要用**SSDP(简单服务发现协议)**来发现局域网内的Govee灯具,这是多数支持LAN API的智能设备的标准发现方式。
以下是Android 5.1上的具体实现步骤:
1. 声明必要权限
在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
2. 获取多播锁定(关键)
Android默认限制多播接收,必须先获取WifiManager的MulticastLock才能接收组播响应:
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); MulticastLock multicastLock = wifiManager.createMulticastLock("GoveeDiscoveryLock"); multicastLock.acquire(); // 用完后记得释放:multicastLock.release();
3. 发送SSDP M-SEARCH请求
构造SSDP搜索数据包,发送到组播地址239.255.255.250的1900端口:
String ssdpRequest = "M-SEARCH * HTTP/1.1\r\n" + "HOST: 239.255.255.250:1900\r\n" + "MAN: \"ssdp:discover\"\r\n" + "MX: 3\r\n" + // 等待响应的最大秒数 "ST: ssdp:all\r\n\r\n"; // 搜索所有设备,也可替换为Govee特定ST值,比如urn:govee-com:device:light:1 DatagramSocket socket = new DatagramSocket(); socket.setSoTimeout(5000); // 设置超时时间 InetAddress group = InetAddress.getByName("239.255.255.250"); DatagramPacket packet = new DatagramPacket(ssdpRequest.getBytes(), ssdpRequest.length(), group, 1900); socket.send(packet);
4. 接收并解析SSDP响应
监听设备返回的响应,从中提取IP地址:
byte[] buffer = new byte[1024]; DatagramPacket responsePacket = new DatagramPacket(buffer, buffer.length); try { while (true) { socket.receive(responsePacket); String response = new String(responsePacket.getData(), 0, responsePacket.getLength()); // 解析响应中的LOCATION头,格式类似:LOCATION: http://192.168.1.100:1234/description.xml if (response.contains("LOCATION:")) { // 遍历查找LOCATION行更可靠,避免行索引变化 String[] lines = response.split("\r\n"); for (String line : lines) { if (line.startsWith("LOCATION:")) { String urlStr = line.substring(line.indexOf("http://") + 7); String ip = urlStr.split(":")[0]; // 此处得到的ip即为灯具的局域网地址 Log.d("GoveeDiscovery", "Found device IP: " + ip); break; } } break; } } } catch (SocketTimeoutException e) { Log.e("GoveeDiscovery", "Discovery timed out"); } finally { socket.close(); multicastLock.release(); }
注意事项
- 确保Android设备和Govee灯具处于同一WiFi局域网,且未开启VPN或代理
- 部分Govee灯具需在官方APP中先开启「LAN控制」权限(通常在设备设置页),否则不会响应SSDP请求
- 若
ssdp:all搜不到设备,可尝试Govee特定的ST值,具体可参考Govee官方LAN API文档
内容的提问来源于stack exchange,提问作者Adrien Bourdeaux
相关产品推荐
相关产品推荐

