第一次尝试在Android中进行IP发现。我使用了http://developer.android.com/training/connect-devices-wirelessly/nsd.html#discover并编写了代码。我没有注册设备,只是在网络中发现服务。当我在模拟器或设备中运行项目时,会调用onDiscoveryStarted(),但永远不会调用onServiceFound()。请在下面找到我的代码。任何输入都非常感谢。谢谢!
public class MainActivity extends AppCompatActivity {
private Button discoverButton;
Context mContext;
NsdManager mNsdManager;
NsdManager.ResolveListener mResolveListener;
NsdManager.DiscoveryListener mDiscoveryListener;
NsdManager.RegistrationListener mRegistrationListener;
public static final String SERVICE_TYPE = "_http._tcp.";
public static final String TAG = "MyApp_MAIN_CLIENT";
public String mServiceName = "MyApp";
/*
* public static final String SERVICE_TYPE = "_http._tcp.";
public static final String TAG = "NsdHelper";
public String mServiceName = "NsdChat";
* */
NsdServiceInfo mService;
private Handler mUpdateHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNsdManager = (NsdManager) this.getSystemService(Context.NSD_SERVICE);
discoverButton = (Button) findViewById(R.id.netButton);
discoverButton.setOnClickListener(new View.OnClickListener() {
public void onClick(android.view.View v) {
initializeDiscoveryListener();
initializeResolveListener();
discoverServices();
}
});
}
public void discoverServices() {
mNsdManager.discoverServices(
SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}
public void initializeDiscoveryListener() {
// Instantiate a new DiscoveryListener
mDiscoveryListener = new NsdManager.DiscoveryListener() {
// Called as soon as service discovery begins.
@Override
public void onDiscoveryStarted(String regType) {
Log.d(TAG, "Service discovery started");
}
@Override
public void onServiceFound(NsdServiceInfo service) {
// A service was found! Do something with it.
Log.d(TAG, "Service discovery success" + service);
if (!service.getServiceType().equals(SERVICE_TYPE)) {
// Service type is the string containing the protocol and
// transport layer for this service.
Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
} /*else if (service.getServiceName().equals(mServiceName)) {
// The name of the service tells the user what they'd be
// connecting to. It could be "Bob's Chat App".
Log.d(TAG, "Same machine: " + mServiceName);
}
//else if (service.getServiceName().contains("NsdChat")){*/
else{
mNsdManager.resolveService(service, mResolveListener);
}
}
@Override
public void onServiceLost(NsdServiceInfo service) {
// When the network service is no longer available.
// Internal bookkeeping code goes here.
Log.e(TAG, "service lost" + service);
}
@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);
}
};
}// end of initializeListener()
public void initializeResolveListener() {
mResolveListener = new NsdManager.ResolveListener() {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.e(TAG, "Resolve failed" + errorCode);
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
Log.e(TAG, "Resolve Succeeded. " + serviceInfo);
if (serviceInfo.getServiceName().equals(mServiceName)) {
Log.d(TAG, "Same IP.");
return;
}
mService = serviceInfo;
int port = mService.getPort();
InetAddress host = mService.getHost();
Log.d(TAG,host.toString());
}
};
}//end of initializeResolveListener
@Override
protected void onPause() {
super.onPause();
stopDiscovery();
tearDown();
}
@Override
protected void onResume() {
super.onResume();
discoverServices();
}
@Override
protected void onDestroy() {
tearDown();
super.onDestroy();
}
public void stopDiscovery() {
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}
public void tearDown() {
mNsdManager.unregisterService(mRegistrationListener);
}
}
答案 0 :(得分:2)
可能由于这篇文章的年龄,我希望你已经找到了解决方案。
如果没有,我的经验是Android模拟器(API级别25)不提供完整的网络堆栈,并且通过NSD的服务发现不起作用。
我切换到真实设备(如Android TV或平板电脑)上的调试,然后我的整个NSD / Bonjour式设置正常工作。调用了DiscoveryListener和ResolveListener的方法,并检索了IP和端口(在我的例子中)。
答案 1 :(得分:2)
来自NdsManager documentation page:
API目前支持基于DNS的服务发现和发现 目前仅限于通过多播DNS的本地网络。
从此Local networking limitations emulator docs page:
目前,模拟器不支持IGMP或组播。
希望这会对你有所帮助
答案 2 :(得分:0)
网络服务发现管理器类提供用于发现网络上服务的API。 当您的设备连接到与提供服务的设备相同的WIFI网络时,此方法将起作用。 希望这可以帮助!! 祝您编码愉快!
答案 3 :(得分:0)
使用Android NSD几个小时后,我发现此库不适用于不支持多播的路由器。尽管其他答案可能是正确的,但这也可能是您遇到问题的原因。可能的解决方案:如果可能,在路由器上启用“多播”,或使用其他网络库。