如何在Android上发现zeroconf(Bonjour)服务?我在使用jmDNS时遇到了麻烦

时间:2010-03-18 23:53:17

标签: android bonjour zeroconf

我正在使用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。 (我是SO的新手,所以不能发布多个网址。)

我已经测试了他们的代码,但没有运气。

有没有人在Android上使用jmDNS或其他库成功完成zeroconf服务发现?

我的发现问题是否可能与IPv6组播问题有关?

5 个答案:

答案 0 :(得分:12)

我也是新人,否则我会对smountcastle的答案发表评论,这个评论大多是正确的。我刚刚在运行Android 2.1的Droid上处理完全相同的问题。我发现我需要将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是我目前唯一的测试设备,所以我不能肯定地说。

答案 1 :(得分:8)

我设法将Android版的Bonjour交叉编译,并使其运行方式与Apple打算在打印机等嵌入式设备上运行的方式相同。 Here是构建脚本。

Here是一个小巧便利的包装器,可以让它按照您的预期运行。

我们正在使用Bonjour发行版中的client_shim层,通过通常的dns_sd.h API来包装对嵌入式mDNS实现的所有访问。你不要使用带有文件句柄的惯用语和带有填充层的选择。

Apple并不完全支持client_shim层 - 实际上我在变量名中发现了拼写错误,但它仍然有效。您需要应用this patch来包含正确的头文件,修复拼写错误并通过Android API进行记录。

还有一件事:您需要从Java代码中获取并保存MultiCast Lock,否则您将找不到任何其他人。请参阅示例here

除此之外,我让它在Android API Level 8上运行,我们正在维护一个预先构建的Bonjour for Android库,但我不确定这是否可以按照许可证进行。

<强>编辑:

prebuilts中的版本是330.10,较新的版本是client_shim,因为静态库无法在Windows上使用MSVC2010进行编译,所以我们保留了这个版本。

祝你好运!

答案 2 :(得分:7)

Android 4.1为应用程序添加了本机Bonjour支持(看起来像是通过mDNSResponder实现的)。高级API似乎被称为Network Service Discovery,但下面似乎是Bonjour。似乎还有一个通过android.net.wifi.p2p.WifiP2pManager公开的低级API。

虽然它似乎没有用于系统范围的DNS查找(例如,我不能通过Chrome浏览到http://machine.local),但这似乎是zeroconf / Bonjour查找的方法未来的原生Android应用程序。

答案 3 :(得分:3)

您是否已明确获取多播锁,以便可以接收多播数据包?

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没有修复。也许您应该转换到以后的版本?

答案 4 :(得分:3)

如果你还没有看过,我建议你在github上查看这个项目(免责声明 - 我不是作者):https://github.com/twitwi/AndroidDnssdDemo

这是一个示例项目,几乎展示了如何使一切运行起来。它还包括一个自定义的jmdns.jar,它解决了我在使用具有重复类文件的开箱即用的jmdns.jar时遇到的一些问题。