Wifi P2P服务发现的行为不符合预期。我看到间歇性的问题,DNSSD侦听器不会一直被调用,因此我不知道运行相同应用程序的附近设备。我使用以下两个API - 一个用于注册要由其他设备发现的服务,另一个用于发现在其他设备上运行的附近服务。任何想法,如果我在这里做错了或者是否有一些特定的其他Android API调用序列需要在我调用这些API之前进行,以确保在注册新服务时甚至是服务时始终调用侦听器在我们调用API以发现本地服务之前注册。
注册本地服务的API:
private void registerService() {
Map<String, String> values = new HashMap<String, String>();
values.put("name", "Steve");
values.put("port", "8080");
WifiP2pServiceInfo srvcInfo = WifiP2pDnsSdServiceInfo.newInstance(mMyDevice.deviceName, "_http._tcp", values);
manager.addLocalService(channel, srvcInfo, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
Toast.makeText(WiFiDirectActivity.this, "Local service added successfully",
Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int reasonCode) {
Toast.makeText(WiFiDirectActivity.this, "Local service addition failed : " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
发现本地服务的API:
public void discoverService() {
manager.clearServiceRequests(channel, null);
DnsSdTxtRecordListener txtListener = new DnsSdTxtRecordListener() {
@Override
/* Callback includes:
* fullDomain: full domain name: e.g "printer._ipp._tcp.local."
* record: TXT record data as a map of key/value pairs.
* device: The device running the advertised service.
*/
public void onDnsSdTxtRecordAvailable(String fullDomain, Map record, WifiP2pDevice device) {
Log.d(TAG, "DnsSdTxtRecord available -" + record.toString());
}
};
DnsSdServiceResponseListener servListener = new DnsSdServiceResponseListener() {
@Override
public void onDnsSdServiceAvailable(String instanceName, String registrationType, WifiP2pDevice resourceType) {
Log.d(TAG, "onBonjourServiceAvailable " + instanceName);
}
};
manager.setDnsSdResponseListeners(channel, servListener, txtListener);
WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
manager.addServiceRequest(channel, serviceRequest, new ActionListener() {
@Override
public void onSuccess() {
// Success!
Log.d(TAG, "addServiceRequest success");
}
@Override
public void onFailure(int code) {
// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY
Log.d(TAG, "addServiceRequest failure with code " + code);
}
});
manager.discoverServices(channel, new ActionListener() {
@Override
public void onSuccess() {
// Success!
Log.d(TAG, "discoverServices success");
}
@Override
public void onFailure(int code) {
// Command failed. Check for P2P_UNSUPPORTED, ERROR, or BUSY
if (code == WifiP2pManager.P2P_UNSUPPORTED) {
Log.d(TAG, "P2P isn't supported on this device.");
} else {
Log.d(TAG, "discoverServices failure");
}
}
});
}
注意:经理&amp;通道初始化为
WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
Channel channel = manager.initialize(this, getMainLooper(), null);
答案 0 :(得分:28)
WifiP2p
(一般情况下): 前段时间我正在开发一个基于WifiP2p
和Service Broadcasting/Discovery
的非常复杂的网络连接系统的应用程序。根据这些经验,我已经在这里写了几篇关于有多难,穿着和有问题的帖子。以下是其中两个(他们充分了解了我对WifiP2p
Service Discovery
以及WifiP2p
本身所获得的内部知识:
Why is discovering peers for Android WifiDirect so unreliable
Wi-fi P2P. Inform all peers available of some event
我建议你阅读我的两个答案(即使他们更关注WifiP2p
本身)。在使用WifiP2p Service Discovery
时,他们应该就您应该寻找的事情提供一些观点。
我可以很容易地说,如果你想建立一个高效,相对可靠和强大的WifiP2p
连接系统(特别是Service Discovery
),你将不得不解决问题。
WifiP2p Service Discovery
强> 为了更好地回答您的确切问题,我会告诉您我做了什么(与您不同),以使Service Discovery
工作非常可靠。
<强> 1。广播Service
:
首先:在注册Service
(使用addLocalService
方法)之前,您应该使用WifiP2pManager
的{{1}}方法。重要的是,如果听众传递了clearLocalServices
并返回了addLocalService
回调,那么您应该 调用clearLocalServices
。
虽然这很好地设置了广播,但我发现其他节点并不总是能够检测到广播的onSuccess
(特别是当这些节点在注册本地时尚未主动检测服务时{ {1}} - 但他们之后“加入”了。我无法找到一种方法来100%可靠地解决这个问题。相信我,我可能正在尝试所有与service
相关的事情。不,Service
- WifiP2p
序列并没有给出令人满意的结果。或者更重要的是:做一些与众不同的工作要好得多。我决定做的是,在成功添加本地服务(clearLocalServices
来回addLocalService
)后,我开始onSuccess
定期调用{{1}方法addLocalService
。这似乎迫使重播所有Thread
信息。
所以...基本上你的广播代码的基础看起来应该更像这样(请记住,如果网络连接系统是,我将在这里发布的每一段代码都被剥离掉所有“检查”在正确的状态下,您应该自己设计它们以最好地适应您的解决方案:
WifiP2pManager
discoverPeers
应该是:
service
<强> 2。发现public void startBroadcastingService(){
mWifiP2pManager.clearLocalServices(mWifiP2pChannel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
mWifiP2pManager.addLocalService(mWifiP2pChannel, mWifiP2pServiceInfo,
new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
// service broadcasting started
mServiceBroadcastingHandler
.postDelayed(mServiceBroadcastingRunnable,
SERVICE_BROADCASTING_INTERVAL);
}
@Override
public void onFailure(int error) {
// react to failure of adding the local service
}
});
}
@Override
public void onFailure(int error) {
// react to failure of clearing the local services
}
});
}
:
为了发现你mServiceBroadcastingRunnable
我使用了类似的方法。两者都设置了发现,并试图强制“重新发现”private Runnable mServiceBroadcastingRunnable = new Runnable() {
@Override
public void run() {
mWifiP2pManager.discoverPeers(mWifiP2pChannel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
}
@Override
public void onFailure(int error) {
}
});
mServiceBroadcastingHandler
.postDelayed(mServiceBroadcastingRunnable, SERVICE_BROADCASTING_INTERVAL);
}
};
。
使用以下三种Service
方法的序列进行设置:
service
,services
,WifiP2pManager
它们按照这个确切的顺序被调用,并且只有在前一个方法使用removeServiceRequest
回调“返回”之后才调用特定方法(第二个或第三个确切)。
使用直观方法重新发现addServiceRequest
(只需重复上述序列:discoverServices
- &gt; onSuccess
- &gt; services
)。< / p>
我的代码基础看起来更像是这样(要开始removeServiceRequest
我先打电话给addServiceRequest
然后再打discoverServices
):
Service Discovery
prepareServiceDiscovery()
startServiceDiscovery()
只是:
public void prepareServiceDiscovery() {
mWifiP2pManager.setDnsSdResponseListeners(mWifiP2pChannel,
new WifiP2pManager.DnsSdServiceResponseListener() {
@Override
public void onDnsSdServiceAvailable(String instanceName,
String registrationType, WifiP2pDevice srcDevice) {
// do all the things you need to do with detected service
}
}, new WifiP2pManager.DnsSdTxtRecordListener() {
@Override
public void onDnsSdTxtRecordAvailable(
String fullDomainName, Map<String, String> record,
WifiP2pDevice device) {
// do all the things you need to do with detailed information about detected service
}
});
mWifiP2pServiceRequest = WifiP2pDnsSdServiceRequest.newInstance();
}
这一切使我的系统运作良好。它还不完美,但由于缺乏关于这个主题的文档,我认为我无法做更多的改进。
如果你测试这种方法,请务必告诉我它是如何工作的(或如果它适合你;)。)。
答案 1 :(得分:0)
如果问题是检测到服务,我认为提示组是使设备和服务可检测的最佳方式,但是如果在所有设备中创建了组,则无法直接连接。 但作为wifi网络。 我每天都这样做而且有效。