如何在 Android 上发现 Zeroconf (Bonjour) 服务?我在使用 jmDNS 时遇到问题
题
我正在使用 Droid / Android 2.0.1 并遇到一个显然很多人都遇到过的问题:我无法使用我所知道的纯 Java Zeroconf 库 jmDNS 来发现服务。(Apple 的 Bonjour,虽然它可以在 Linux 和 Windows Java 上运行,但我相信由于依赖本机代码,移植到 Android 会更困难。)
我可以创建服务,但无法发现它们。我正在尝试了解正在发生的事情。
这里有一个持续的问题报告;与多播和 IPv6 相关,但似乎也抛出了 jmDNS 的用户:http://code.google.com/p/android/issues/detail?id=2323
知道为什么这个人会成功吗?请参阅错误报告中的评论 22。(我是新手,所以无法发布多个 URL。)
我测试了他们的代码,但没有任何运气。
有没有人使用 jmDNS 或其他库在 Android 上成功完成了 Zeroconf 服务发现?
我的发现问题是否可能与 IPv6 多播问题有关?
解决方案
我是新以及否则我会刚刚离开其中大部分是正确的smountcastle的答案评论。我刚刚在的Droid运行Android 2.1处理完全相同的问题。我发现,我需要设置MulticastLock到引用计数,否则它似乎被自动释放。
AndroidManifest.xml:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
// Networking code:
WifiManager wifi = getSystemService( Context.WIFI_SERVICE );
MulticastLock lock = wifi.createMulticastLock("fliing_lock");
lock.setReferenceCounted(true);
lock.acquire();
只要确保调用lock.release()
当你用它做。这可能只需要为Android 2.0+,在Droid是我唯一的测试设备目前,所以我不能肯定地说。
其他提示
我成功地为 Android 交叉编译了 Bonjour,并使其运行方式与 Apple 希望它在打印机等嵌入式设备上运行的方式大致相同。 这里 是构建脚本。
这里 是一个小型便利包装,可使其按您的预期工作。
我们使用 Bonjour 发行版中的 client_shim 层来通过常用的 dns_sd.h API 包装对嵌入式 mDNS 实现的所有访问。您不可以将惯用语与文件句柄一起使用,也不要将选择与填充层一起使用。
Apple 并不完全支持 client_shim 层 - 事实上我发现变量名称中有拼写错误,但它仍然可以工作。您需要申请 这个补丁 包含正确的头文件、修复拼写错误并通过 Android API 获取日志记录。
还有一件事:你 需要 从 Java 代码中获取并持有多播锁,否则您将找不到其他人。参见示例 这里.
除此之外,我让它在 Android API Level 8 上运行,并且我们正在维护一个预构建的库 安卓版卓悦, ,尽管我不确定这是否符合许可证。
编辑:
预构建版本是 330.10,较新的版本带有 client_shim,因为静态库无法在 Windows 上使用 MSVC2010 进行编译,因此我们保留了这个版本。
祝你好运!
的Android 4.1增加天然Bonjour支持(看起来像经由其mDNSResponder实现的)的应用。高层次的API好像是叫网络服务发现但似乎是下面的Bonjour 。此外,还似乎是一个低级别的API通过 android.net.wifi.p2p暴露。 WifiP2pManager 。
虽然它似乎没有被用于全系统的DNS查找(例如我不能简单地浏览到 HTTP://machine.local 一>经由浏览器)出现,这将是一种用于本地Android应用前进做零配置/查找的Bonjour的方式。
你有明确的收购组播锁定,这样就可以接收组播数据包?
AndroidManifest.xml: <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> // Networking code: WifiManager wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE); MulticastLock lock = wifi.createMulticastLock("mylock"); lock.acquire();
据该Android的线程问题,它看起来像2.0.1没有修复。也许你应该过渡到更高版本?
如果您还没有看到它了,我建议在GitHub上检查了这个项目(免责声明 - 我不是作家):的 https://github.com/twitwi/AndroidDnssdDemo
这是一个示例项目,几乎展示了如何让一切正常运行。它还包括解决我与具有重复类文件外的开箱jmdns.jar有一些问题,自定义jmdns.jar。