gpt4 book ai didi

Android - jmdns 没有发现设备

转载 作者:IT老高 更新时间:2023-10-28 23:40:12 28 4
gpt4 key购买 nike

我正在尝试实现一个类来发现网络上的服务。我试过使用 Android's NSD它确实发现服务很好,但它只支持 API 级别 16 及更高级别,而且我似乎无法检索服务信息中的 txtRecord 字段(由于某种原因它返回 null)。结果是it's a known problem...

所以现在我正在尝试使用 jmDNS ,这似乎根本找不到服务。这是我的类(class)(我正在使用 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());
}
}

在我的应用程序中我调用:

init(getActivity());

然后startDiscovery();开始扫描,stopDiscovery();停止扫描。

当然,我在 list 中为应用授予了所需的权限...我在这里想念什么?如果您需要我提供其他代码/信息 - 请询问。谢谢!!

最佳答案

我是 ZeroConf Browser for Android 的作者,我使用开源库 JmDNS 进行所有解析。它工作得很好,但有一些技巧可以让它正常工作。

  1. 在您的 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" />
  2. 在开始 Activity 之前,您必须通过获取多播锁定来允许多播数据包。

    @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;
    }
  3. 不要忘记停止扫描以解锁多播锁定并关闭 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);
    }
    }
  4. 最重要的是不要使用默认构造函数。您必须使用 IP 地址构造函数。我注意到在您的代码中您只是在执行 JmDNS.create()。我认为出于某种原因,它在 Android 上运行的唯一方法是使用下面的构造函数。

    jmdns = JmDNS.create(deviceIpAddress, HOSTNAME);

关于Android - jmdns 没有发现设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23805893/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com