我该如何在安卓设备上发现零配置(Bonjour)服务? 我使用jmDNS时遇到了问题。

40

我正在使用一台Droid/Android 2.0.1设备,并遇到了一个似乎许多人都会遇到的问题:我无法使用我所知道的唯一纯Java zeroconf库jmDNS发现服务。 (虽然苹果的Bonjour在Linux和Windows Java上可行,但我认为由于依赖本地代码,将其移植到Android将更加困难。)

我可以创建服务,但无法发现它们。我正试图理解发生了什么事情。

这里有一个持续的问题报告;与多播和IPv6有关,但似乎也影响到了jmDNS的用户: http://code.google.com/p/android/issues/detail?id=2323

你知道为什么那个人可能会成功吗?请参见错误报告中的评论22。 (我是SO的新手,因此无法发布多个URL。)

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

有人成功地在Android上使用jmDNS或其他库实现了zeroconf服务发现吗?

我的发现问题是否与IPv6多播问题有关?


那个错误报告中没有第22条评论,它只有14条。 - CommonsWare
看起来问题跟踪器链接应该是:http://code.google.com/p/android/issues/detail?id=2917 - Roman Nurik
抱歉,更正如下:http://code.google.com/p/android/issues/detail?id=2917#c22。 - Peter Kirn
抱歉我不能提出更具体的问题。问题在于,当什么都没有发生时,很难解决问题。 ;) 我很惊讶没有更多的人尝试过这个,但也许这是因为Java零配置库的状况不佳...这是一个先有鸡还是先有蛋的问题。 - Peter Kirn
零配置协议故意非常简单。我建议直接按照RFC编写一个最基本的客户端,看看是否正确接收数据包。这与多播的怪异性无关,但肯定可能与发送/接收广播UDP数据包的问题有关。 - Rakis
非常详细的关于Android和Bonjour的文章:http://andriydruk.com/post/mdnsresponder/ - delkant
5个回答

13

我也是新手,否则我本可以在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,所以我不能确定。


离能够进行一般性评论如此之近...我正在使用JmDNS,在运行2.1-update1的Motorola Droid上使用MulticastLock方法已经成功了。最近刚刚获得了一台运行相同版本Android的HTC Incredible,但是使用完全相同的代码无法进行服务发现。我一直在为这个问题苦恼,祝你好运... - Churlbong
你能添加一些代码展示你是如何调用所有内容的吗?我已经尝试添加了CHANGE_WIFI_MULTICAST_STATE权限,但仍然没有得到任何结果。 - mudit
谢谢,Churlbong - 出于好奇,您是使用jmDNS还是直接编写客户端实现?(或者使用其他库)?我会尝试一下,因为我的锁定代码不完全相同,而且我不确定我是否意识到它还有一个独立于网络权限的单独权限。;) - Peter Kirn

8
我成功地将Bonjour交叉编译为Android,并使其运行方式与苹果打算在嵌入式设备上(如打印机)运行的方式非常相似。 这里 是构建脚本。 这里 是一个小型方便包装器,使其按您预期工作。
我们正在使用来自Bonjour分发的client_shim层,通过通常的dns_sd.h API包装对嵌入式mDNS实现的所有访问。您不需要使用文件句柄和选择与shim层的惯用语。
客户端shim层并不是由苹果公司完全支持 - 实际上,我发现变量名中有拼写错误,但它仍然可以正常工作。您需要应用此补丁以包含正确的头文件,修复拼写错误并通过Android API记录。

还有一件事:您需要在Java代码中获取和持有MultiCast Lock,否则您将找不到其他人。请参见此处的示例here

除此之外,我已经在Android API Level 8上运行它,并且我们正在维护Bonjour for Android的预构建库,尽管我不确定这是否符合许可证要求。

编辑:

预构建版本的版本号为330.10,使用client_shim作为静态库的更新版本无法在Windows上使用MSVC2010进行编译,因此我们保留了这个版本。

祝你好运!


有些链接已经无效了,但我设法找到了预构建的示例。这些类(Publisher、Subscriber、Node、Discovery)可用于与使用其Bonjour实现的苹果设备进行通信,还是苹果设备也必须同时运行umundo? - Adrian Jandl
我们仍然有预构建文件,但它们已经移动到一个tarball中,在配置时下载。除了darwin平台外,每个平台都有一个libmdnsembedded内置。uMundo是ZeroMQ + mDNS用于发布/订阅 - 如果您只想查找服务,请使用libmdnsembedded和dns_sd.h,而不需要像client_shim实现中所做的选择。 - sradomski
我想通过我的Android设备仅查找服务。有没有关于如何在Android设备上使用libmDNSEmbedded.a文件与dns_sd.h一起使用的示例?是否有用于简单服务发现的Java包装器? - Adrian Jandl
你可以使用umundo并忽略除了发现子系统以外的一切。这里有一个umundo在安卓上的示例项目。Discovery对象可用于按服务类型/域浏览/广告服务。完成后不要忘记取消浏览/取消广告。如果您选择继续并遇到问题,请在umundo问题跟踪器上继续。 - sradomski

7

Android 4.1新增了本地Bonjour支持(似乎是通过mDNSResponder实现的)供应用程序使用。高级API似乎被称为Network Service Discovery,但在下面似乎是Bonjour。此外,还似乎通过android.net.wifi.p2p.WifiP2pManager公开了较低级别的API。

虽然它似乎不用于系统范围的DNS查找(例如,我无法通过Chrome简单地浏览到http://machine.local),但这似乎是未来原生Android应用程序进行零配置/Bonjour查找的方法。


5
很遗憾,原生API不允许访问TXT记录,这严重限制了功能。- https://code.google.com/p/android/issues/detail?id=136099 - Nick Dowell

3
你是否已经显式地获取了多播锁,以便可以接收多播数据包?
AndroidManifest.xml: <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
// 网络代码: WifiManager wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE); MulticastLock lock = wifi.createMulticastLock("mylock"); lock.acquire();
根据那个 Android 问题线程,看起来 2.0.1 没有修复。也许你应该转换到更高版本?

3
如果您还没有看过它,我建议您在github上查看这个项目(免责声明 - 我不是作者):https://github.com/twitwi/AndroidDnssdDemo 这是一个示例项目,几乎展示了如何使一切都能正常运行。它还包括一个自定义的jmdns.jar文件,解决了我使用默认的jmdns.jar时遇到的重复类文件问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接