无法在Android上使用网络服务发现(NSD)检测服务
我是一个新手,尝试在我正在构建的应用程序中使用NSD,以查找在同一wifi网络上运行相同服务的对等方并连接到该应用程序 [参考代码]我有一台设备运行着HostActivity.java,还有一台设备运行着GuestActivity.java。单击主机中的浮动按钮在端口9000上注册服务(目前已预设),然后在来宾中单击该按钮,开始为该端口运行服务发现。两者都连接到同一个wifi网络 在我的日志猫中,我观察到从HostActivity.java注册工作正常-我从NsdHelper.java获得必要的日志消息。但是,运行GuestActivity.java只会记录“服务发现已启动”,而不会最终解析为网络上存在的服务 我做错了什么?请帮忙 有关守则- HostActivity.java无法在Android上使用网络服务发现(NSD)检测服务,android,nsd,Android,Nsd,我是一个新手,尝试在我正在构建的应用程序中使用NSD,以查找在同一wifi网络上运行相同服务的对等方并连接到该应用程序 [参考代码]我有一台设备运行着HostActivity.java,还有一台设备运行着GuestActivity.java。单击主机中的浮动按钮在端口9000上注册服务(目前已预设),然后在来宾中单击该按钮,开始为该端口运行服务发现。两者都连接到同一个wifi网络 在我的日志猫中,我观察到从HostActivity.java注册工作正常-我从NsdHelper.java获得必要的
NsdHelper mNsdHelper;
public static final String TAG = "ABC";
private final int ABC_PORT = 9000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shared_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mNsdHelper = new NsdHelper(this);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Started Registration", Snackbar.LENGTH_LONG)
.setAction("CLOSE", null).show();
mNsdHelper.initializeNsd();
mNsdHelper.registerService(ABC_PORT);
Snackbar.make(view, "Completed Registration", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
if (mNsdHelper != null) {
mNsdHelper.initializeNsd();
mNsdHelper.registerService(ABC_PORT);
}
}
@Override
protected void onDestroy() {
mNsdHelper.tearDown();
super.onDestroy();
}
NsdHelper mNsdHelper;
public static final String TAG = "ABC";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shared_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mNsdHelper = new NsdHelper(this);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Searching for available services", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
mNsdHelper.initializeNsd();
mNsdHelper.discoverServices();
}
});
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
if(mNsdHelper != null) {
mNsdHelper.initializeNsd();
mNsdHelper.discoverServices();
}
}
@Override
protected void onDestroy() {
mNsdHelper.tearDown();
super.onDestroy();
}
GuestActivity.java
NsdHelper mNsdHelper;
public static final String TAG = "ABC";
private final int ABC_PORT = 9000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shared_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mNsdHelper = new NsdHelper(this);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Started Registration", Snackbar.LENGTH_LONG)
.setAction("CLOSE", null).show();
mNsdHelper.initializeNsd();
mNsdHelper.registerService(ABC_PORT);
Snackbar.make(view, "Completed Registration", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
if (mNsdHelper != null) {
mNsdHelper.initializeNsd();
mNsdHelper.registerService(ABC_PORT);
}
}
@Override
protected void onDestroy() {
mNsdHelper.tearDown();
super.onDestroy();
}
NsdHelper mNsdHelper;
public static final String TAG = "ABC";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shared_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mNsdHelper = new NsdHelper(this);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Searching for available services", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
mNsdHelper.initializeNsd();
mNsdHelper.discoverServices();
}
});
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
if(mNsdHelper != null) {
mNsdHelper.initializeNsd();
mNsdHelper.discoverServices();
}
}
@Override
protected void onDestroy() {
mNsdHelper.tearDown();
super.onDestroy();
}
NsdHelper.java-包含所有NSD实现细节
public class NsdHelper {
Context mContext;
NsdManager mNsdManager;
NsdManager.ResolveListener mResolveListener;
NsdManager.DiscoveryListener mDiscoveryListener;
NsdManager.RegistrationListener mRegistrationListener;
private static final String SERVICE_TYPE = "_http._tcp.";
private static final String TAG = "NsdHelper";
private String mServiceName = "ABC";
// First step : register a NsdServiceInfo object to advertise your service
NsdServiceInfo mService;
public NsdHelper(Context context) {
mContext = context;
mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
}
public void initializeNsd() {
initializeRegistrationListener();
initializeDiscoveryListener();
initializeResolveListener();
}
// Check success of service registration
public void initializeRegistrationListener() {
mRegistrationListener = new NsdManager.RegistrationListener() {
@Override
public void onServiceRegistered(NsdServiceInfo nsdServiceInfo) {
mServiceName = nsdServiceInfo.getServiceName();
Log.d(TAG, "Registered name : " + mServiceName);
}
@Override
public void onRegistrationFailed(NsdServiceInfo nsdServiceInfo, int arg1) {
Log.d(TAG, "Registration Failed");
}
@Override
public void onServiceUnregistered(NsdServiceInfo nsdServiceInfo) {
Log.d(TAG, "Unregistered");
}
@Override
public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
}
};
}
public void registerService(int port) {
NsdServiceInfo serviceInfo = new NsdServiceInfo();
serviceInfo.setPort(port);
serviceInfo.setServiceName(mServiceName);
serviceInfo.setServiceType(SERVICE_TYPE);
mNsdManager.registerService(
serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
}
// To discover services of the type you're looking for on the network
public void initializeDiscoveryListener() {
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 : " + service);
Log.d(TAG, "Host = "+ service.getServiceName());
Log.d(TAG, "port = " + String.valueOf(service.getPort()));
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)){
mNsdManager.resolveService(service, mResolveListener);
}
}
@Override
public void onServiceLost(NsdServiceInfo service) {
Log.e(TAG, "service lost" + service);
if (mService == service) {
mService = null;
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);
}
};
}
public void discoverServices() {
mNsdManager.discoverServices(
SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}
// Connection handshake
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();
}
};
}
public void stopDiscovery() {
if (mNsdManager != null) {
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}
}
public NsdServiceInfo getChosenServiceInfo() {
return mService;
}
public void tearDown() {
if (mNsdManager != null) {
if (mRegistrationListener != null) {
mNsdManager.unregisterService(mRegistrationListener);
}
if (mDiscoveryListener != null) {
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}
}
}
}您似乎遵循了Android开发者网站上的代码示例,但有两个错误阻碍了我们:
public void onServiceFound(NsdServiceInfo service)
方法中,检查服务名称的代码不正确。据我所知,同一网络中的其他设备也可以使用相同的服务命名,因此请删除if(service.getServiceName().equals(msservicename))
代码块public void on服务已解决(NsdServiceInfo serviceInfo)
代码块中。请删除if(serviceInfo.getServiceName().equals(msservicename))
代码块我从来没有玩过NSD,所以我没有任何关于此代码的建议。在这种情况下,我试图找到一些现有的工作代码,然后慢慢修改代码,直到它完成我需要它做的事情。要么我最终找出我在哪里破坏了东西,要么我得到了工作代码。:-)谷歌可能有一个NSD示例,我似乎记得最近的一次Android会议(droidcon.it 2016?)上有一个关于NSD的演示,其中可能包括一个工作示例。大部分(全部?)核心NSD代码基本上都是逐字提取的-因此,如果谷歌的基础本身不起作用,我就无法对其进行更改。我也看过类似的代码,声称在这里可以工作(虽然是两年前的),但这也不成立。我会找droidcon的演示文稿,希望我能找到一些东西。谢谢你的提示。如果调用public void onservicefund(NsdServiceInfo服务),你至少会看到你的日志语句。我在两款通用安卓平板电脑上运行类似的程序。一旦找不到服务,我必须关闭两个设备,然后再次打开它们。使用快速引导重新启动不起作用。这是一个解决方法,我愿意找到更好的方法。我同意您的意见,但这里的问题是“OnServiceFund(NsdServiceInfo服务)”方法没有被调用,即使有多个设备连接到网络。我使用的服务类型是“\uHTTP.\uTCP”