ore*_*k86 15 android mdns jmdns android-annotations android-nsd
我正在尝试实现一个类来发现网络上的服务.我曾尝试使用Android的NSD,它确实发现服务很好,但它只支持16级及以上的API级别,而且我似乎无法检索服务信息中的txtRecord字段(由于某种原因它返回null).原来这是一个已知问题......
所以现在我正在尝试使用jmDNS,它似乎根本找不到服务.这是我的班级(我正在使用AndroidAnnotations框架)MDnsHelper:
@EBean
public class MDnsHelper implements ServiceListener {
public static final String SERVICE_TYPE = "_http._tcp.local";
Activity activity;
private JmDNS jmdns;
private MulticastLock multicastLock;
WifiManager wm;
InetAddress bindingAddress;
boolean isDiscovering;
public void init(Activity activity) {
this.activity = activity;
isDiscovering = false;
wm = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);
multicastLock = wm.createMulticastLock(activity.getPackageName());
multicastLock.setReferenceCounted(false);
}
@Background
public void startDiscovery() {
if (isDiscovering)
return;
System.out.println("starting...");
multicastLock.acquire();
try {
System.out.println("creating jmdns");
jmdns = JmDNS.create();
System.out.println("jmdns created");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (jmdns != null) {
jmdns.addServiceListener(SERVICE_TYPE, MDnsHelper.this);
isDiscovering = true;
System.out.println("discovering services of type: " + SERVICE_TYPE);
}
}
}
@Background
public void stopDiscovery() {
if (!isDiscovering || jmdns == null)
return;
System.out.println("stopping...");
multicastLock.release();
jmdns.removeServiceListener(SERVICE_TYPE, MDnsHelper.this);
System.out.println("listener for " + SERVICE_TYPE + " removed");
try {
jmdns.close();
isDiscovering = false;
System.out.println("jmdns closed");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void serviceAdded(ServiceEvent service) {
System.out.println("found: " + service.getInfo().toString());
}
@Override
public void serviceRemoved(ServiceEvent service) {
System.out.println("lost: " + service.getInfo().toString());
}
@Override
public void serviceResolved(ServiceEvent service) {
System.out.println("resolved: " + service.getInfo().toString());
}
}
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,我打电话:
init(getActivity());
Run Code Online (Sandbox Code Playgroud)
然后startDiscovery();
开始扫描并stopDiscovery();
停止扫描.
当然,我在应用程序中为应用程序提供了所需的权限......我在这里缺少什么?如果您需要我提供额外的代码/信息 - 请问.谢谢!!
Mel*_*are 32
我是Android的ZeroConf Browser的作者,我使用开源库JmDNS来解决所有问题.它工作得很好,但有一些技巧可以让它正常工作.
在Android manifest.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" />
Run Code Online (Sandbox Code Playgroud)在开始活动之前,您必须通过获取多播锁来允许多播数据包.
@Override
protected void onStart() {
Log.i(TAG, "Starting ServiceActivity...");
super.onStart();
try {
Log.i(TAG, "Starting Mutlicast Lock...");
WifiManager wifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
// get the device ip address
final InetAddress deviceIpAddress = getDeviceIpAddress(wifi);
multicastLock = wifi.createMulticastLock(getClass().getName());
multicastLock.setReferenceCounted(true);
multicastLock.acquire();
Log.i(TAG, "Starting ZeroConf probe....");
jmdns = JmDNS.create(deviceIpAddress, HOSTNAME);
jmdns.addServiceTypeListener(this);
} catch (IOException ex) {
Log.e(TAG, ex.getMessage(), ex);
}
Log.i(TAG, "Started ZeroConf probe....");
}
private InetAddress getDeviceIpAddress(WifiManager wifi) {
InetAddress result = null;
try {
// default to Android localhost
result = InetAddress.getByName("10.0.0.2");
// figure out our wifi address, otherwise bail
WifiInfo wifiinfo = wifi.getConnectionInfo();
int intaddr = wifiinfo.getIpAddress();
byte[] byteaddr = new byte[] { (byte) (intaddr & 0xff), (byte) (intaddr >> 8 & 0xff),
(byte) (intaddr >> 16 & 0xff), (byte) (intaddr >> 24 & 0xff) };
result = InetAddress.getByAddress(byteaddr);
} catch (UnknownHostException ex) {
Log.w(TAG, String.format("getDeviceIpAddress Error: %s", ex.getMessage()));
}
return result;
}
Run Code Online (Sandbox Code Playgroud)并且不要忘记停止扫描以解锁多播锁并关闭JmDNS.
@Override
protected void onStop() {
Log.i(TAG, "Stopping ServiceActivity...");
super.onStop();
stopScan();
}
private static void stopScan() {
try {
if (jmdns != null) {
Log.i(TAG, "Stopping ZeroConf probe....");
jmdns.unregisterAllServices();
jmdns.close();
jmdns = null;
}
if (multicastLock != null) {
Log.i(TAG, "Releasing Mutlicast Lock...");
multicastLock.release();
multicastLock = null;
}
} catch (Exception ex) {
Log.e(TAG, ex.getMessage(), ex);
}
}
Run Code Online (Sandbox Code Playgroud)最重要的是不要使用默认构造函数.您必须使用IP地址构造函数.我注意到你的代码中只是在做JmDNS.create().我认为由于某种原因,它在Android上运行的唯一方法是使用下面的构造函数.
jmdns = JmDNS.create(deviceIpAddress, HOSTNAME);
Run Code Online (Sandbox Code Playgroud) 归档时间: |
|
查看次数: |
6554 次 |
最近记录: |