2012-10-09 33 views
27

Tôi đang cố gắng chạy một ứng dụng bằng Android Native Service Discovery nhưng đôi khi khi tôi chạy ứng dụng, nó không phát hiện tất cả các dịch vụ từ mạng của tôi. Tôi đang chạy mã từ https://github.com/joeluchoa/nsd bằng cách sử dụng bốn mối quan hệ thiên hà và hầu hết thời gian mỗi người trong số họ khám phá số lượng dịch vụ khác nhau cùng một lúc.Android NSD không phát hiện tất cả các dịch vụ

Về cơ bản tôi chạy một dịch vụ với một ServerSocket:

ServerSocket server = new ServerSocket(0); 
Log.i(TAG, "IP " + server.getInetAddress() 
     + ", running on port " + server.getLocalPort()); 

Intent intent = new Intent(MySocket.this, 
     MyPresence.class); 
intent.putExtra("PORT", server.getLocalPort()); 
startService(intent); 

Sau đó, tôi phát hành nó bằng cách sử dụng phương pháp registerService từ NsdManager:

NsdServiceInfo serviceInfo = new NsdServiceInfo(); 

serviceInfo.setServiceName(Build.SERIAL + "-" + new Date().getTime()); 
serviceInfo.setServiceType(SERVICE_TYPE); 
serviceInfo.setPort(port); 

mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, 
     mRegistrationListener); 

Để khám phá các dịch vụ tôi sử dụng discoverServices phương pháp từ NsdManager:

mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, 
     mDiscoveryListener); 

Với mDiscoveryListener như sau:

mDiscoveryListener = new NsdManager.DiscoveryListener() { 

    @Override 
    public void onDiscoveryStarted(String regType) { 
     Log.d(TAG, "Service discovery started"); 
    } 

    @Override 
    public void onServiceFound(NsdServiceInfo service) { 
     Log.d(TAG, "Service discovery success"); 
     Log.d(TAG, String.format("%s %s %s %d", 
       service.getServiceName(), service.getServiceType(), 
       service.getHost(), service.getPort())); 
     if (!service.getServiceType().contains(SERVICE_TYPE)) { 
      Log.d(TAG, 
        "Unknown Service Type: " + service.getServiceType()); 
     } else if (service.getServiceName().equals(mServiceName)) { 
      Log.d(TAG, "Same machine: " + mServiceName); 
     } else { 
      mNsdManager.resolveService(service, mResolveListener); 
     } 
    } 

    @Override 
    public void onServiceLost(NsdServiceInfo service) { 
     Log.e(TAG, "service lost" + service); 
    } 

    @Override 
    public void onDiscoveryStopped(String serviceType) { 
     Log.i(TAG, serviceType + " Discovery stopped: " + serviceType); 
    } 

    @Override 
    public void onStartDiscoveryFailed(String serviceType, int errorCode) { 
     Log.e(TAG, serviceType + " Discovery failed: Error code:" 
       + errorCode); 
     mNsdManager.stopServiceDiscovery(this); 
    } 

    @Override 
    public void onStopDiscoveryFailed(String serviceType, int errorCode) { 
     Log.e(TAG, serviceType + " Discovery failed: Error code:" 
       + errorCode); 
     mNsdManager.stopServiceDiscovery(this); 
    } 
}; 

Tôi đang làm gì sai? Có ai biết một giải pháp hoặc một workaround cho điều này?

+0

tôi camer acros bài của bạn trong khi cố gắng để sửa chữa một NPE mà dường như bật lên khi tôi có hai thiết bị trong mạng với cùng thông tin NSD ... Vì vậy, tôi không' t có một câu trả lời cho bạn, nhưng tôi nhận thấy rằng bạn đang cố gắng để có được thông tin mà bạn đã không giải quyết trong báo cáo đăng nhập của bạn. –

+2

nó là một thực tế phổ biến cho tất cả các nhà phát triển để làm theo đó bằng cách thử bắt hoặc in ra tất cả các biến để tìm ra các lỗi –

+0

bạn chỉ khám phá các dịch vụ của SERVICE_TYPE, trong ví dụ này là http máy chủ web. –

Trả lời

1

Tôi gặp sự cố tương tự, cài đặt lại đã được trợ giúp. Hãy thử sử dụng :)

1

Tôi sợ rằng vẫn còn lỗi trong quá trình triển khai khiến nó bị thiếu dịch vụ. Tôi đã thực hiện một vài ngày thử nghiệm với nhiều thiết bị Android và MacBook, và nó chỉ không hoạt động mọi lúc. Tôi đã ghi lại các phát hiện của mình về một báo cáo lỗi trong trình theo dõi lỗi của Android: https://code.google.com/p/android/issues/detail?id=178080

1

Tôi có xu hướng nghĩ rằng việc triển khai NSD toàn bộ trong Android phải là một chút không ổn định. Tôi cũng có một Activity đơn giản chỉ để chứng minh vòng đời (không có ổ cắm nào được mở), và đôi khi nó hoạt động, và đôi khi nó không hoạt động. Tôi chỉ đơn giản là không nhận được nó. Dưới đây là các Hoạt động nếu ai có một số cái nhìn sâu sắc:

https://github.com/mholzel/Dump/blob/master/NetworkServiceDiscoveryViaWifi.java

Mặt khác, Wifi Direct dựa NSD có vẻ là rất đáng tin cậy đối với tôi:

https://github.com/mholzel/Dump/blob/master/NetworkServiceDiscoveryViaWifiDirect.java

Lưu ý rằng không ai trong số những Các hoạt động có bất kỳ tài nguyên nào, vì vậy, chỉ cần thêm Hoạt động vào Tệp kê khai của bạn với quyền thích hợp.

0

Có thể hơi muộn để trả lời, nhưng tôi đã tìm thấy một giải pháp tốt cho NSD cho android cung cấp trên trang web dành cho nhà phát triển của họ. Tôi đã thực hiện một vài sửa đổi và nó hoạt động hoàn toàn tốt đẹp.

public class NsdClient { 
private Context mContext; 

private NsdManager mNsdManager; 
NsdManager.DiscoveryListener mDiscoveryListener; 

//To find all the available networks SERVICE_TYPE = "_services._dns-sd._udp" 
public static final String SERVICE_TYPE = "_hap._tcp."; 
public static final String TAG = "NsdClient"; 

private static ArrayList<NsdServiceInfo> ServicesAvailable = new ArrayList<>(); 

public NsdClient(Context context) { 
    mContext = context; 
    mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); 
} 

public void initializeNsd() { 
    initializeDiscoveryListener(); 
} 

public void initializeDiscoveryListener() { 
    mDiscoveryListener = new NsdManager.DiscoveryListener() { 

     @Override 
     public void onDiscoveryStarted(String regType) { 
      Log.d(TAG, "Service discovery started " + regType); 
     } 

     @Override 
     public void onServiceFound(NsdServiceInfo service) { 
      Log.d(TAG, "Service discovery success " + service); 
      AVAILABLE_NETWORKS.add(service); 

      if (!service.getServiceType().equals(SERVICE_TYPE)) { 
       Log.d(TAG, "Unknown Service Type: " + service.getServiceType()); 
      } else if (service.getServiceName().equals(mServiceName)) { 
       Log.d(TAG, "Same Machine: " + mServiceName); 
      } else if (service.getServiceName().contains(mServiceName)) { 
       Log.d(TAG, "Resolving Services: " + service); 
       mNsdManager.resolveService(service, new initializeResolveListener()); 
      } 
     } 

     @Override 
     public void onServiceLost(NsdServiceInfo service) { 
      Log.e(TAG, "service lost" + service); 
      if (ServicesAvailable.equals(service)) { 
       ServicesAvailable = null; 
      } 
     } 

     @Override 
     public void onDiscoveryStopped(String serviceType) { 
      Log.i(TAG, "Discovery stopped: " + serviceType); 
     } 

     @Override 
     public void onStartDiscoveryFailed(String serviceType, int errorCode) { 
      Log.e(TAG, "Discovery failed: Error code:" + errorCode); 
      mNsdManager.stopServiceDiscovery(this); 
     } 

     @Override 
     public void onStopDiscoveryFailed(String serviceType, int errorCode) { 
      Log.e(TAG, "Discovery failed: Error code:" + errorCode); 
      mNsdManager.stopServiceDiscovery(this); 
     } 
    }; 
} 

public class initializeResolveListener implements NsdManager.ResolveListener { 

    @Override 
    public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { 
     Log.e(TAG, "Resolve failed " + errorCode); 
     switch (errorCode) { 
      case NsdManager.FAILURE_ALREADY_ACTIVE: 
       Log.e(TAG, "FAILURE ALREADY ACTIVE"); 
       mNsdManager.resolveService(serviceInfo, new initializeResolveListener()); 
       break; 
      case NsdManager.FAILURE_INTERNAL_ERROR: 
       Log.e(TAG, "FAILURE_INTERNAL_ERROR"); 
       break; 
      case NsdManager.FAILURE_MAX_LIMIT: 
       Log.e(TAG, "FAILURE_MAX_LIMIT"); 
       break; 
     } 
    } 

    @Override 
    public void onServiceResolved(NsdServiceInfo serviceInfo) { 
     Log.e(TAG, "Resolve Succeeded. " + serviceInfo); 


     if (serviceInfo.getServiceName().equals(mServiceName)) { 
      Log.d(TAG, "Same IP."); 
      return; 
     } 

    } 
} 

public void stopDiscovery() { 
    mNsdManager.stopServiceDiscovery(mDiscoveryListener); 
} 

public List<NsdServiceInfo> getChosenServiceInfo() { 
    return ServicesAvailable; 
} 

public void discoverServices() { 
    mNsdManager.discoverServices(
      SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener); 
} 
} 

Hy vọng nó giúp này

Các vấn đề liên quan