gpt4 book ai didi

android - Wifi P2P 服务发现间歇性工作

转载 作者:IT老高 更新时间:2023-10-28 21:52:41 25 4
gpt4 key购买 nike

Wifi P2P 服务发现未按预期运行。我看到不总是调用 DNSSD 监听器的间歇性问题,因此我不知道附近设备运行相同的应用程序。我正在使用以下两个 API - 一个用于注册要被其他设备发现的服务,另一个用于发现在其他设备上运行的附近服务。知道我在这里做错了什么,或者在我调用这些 API 之前需要进行一些特定的其他 android 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");
}
}
});
}

注意:manager & channel 初始化为
WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
Channel channel = manager.initialize(this, getMainLooper(), null);

最佳答案

WifiP2p (一般):

前段时间,我正在开发一个基于 WifiP2p 的具有相当复杂的网络连接系统的应用程序。与 Service Broadcasting/Discovery .基于那次经验,我已经在这里写了几篇关于 SO 的文章,说明这是多么困难、磨损和有问题。这是其中的两个(它们完全是我获得的关于 WifiP2pService DiscoveryWifiP2p 本身的内部知识):

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 方法)您应该使用 WifiP2pManagerclearLocalServices方法。重要的是,您应该 仅限 调用addLocalService如果监听器传入 clearLocalServices返回 onSuccess打回来。

尽管这很好地设置了广播,但我发现其他节点并不总是能够检测到广播 service (尤其是当这些节点在注册您的本地 Service 时尚未主动检测服务时 - 但它们后来“加入”了)。我找不到 100% 可靠地解决此问题的方法。相信我,我可能正在尝试一切WifiP2p -有关的。不,clearLocalServices - addLocalService序列并没有真正给出令人满意的结果。或者更重要的是:做一些不同的事情会更好。我决定做的是在我 之后成功添加本地服务(onSuccess 来自 addLocalService 的回调),我开始了 Thread会定期调用 WifiP2pManager的方法discoverPeers .这似乎迫使重播所有 service信息。

所以......基本上你的广播代码的基础应该看起来更像这样(请记住,如果网络连接系统正确,我将在这里发布的每一段代码都被剥离了所有“检查”状态,您应该自己设计它们以最适合您的解决方案):

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);
}
};

2.发现Service :

为了发现您的 service我使用了类似的方法。无论是设置发现还是试图强制“重新发现” services .

设置是按照以下三个 WifiP2pManager 的顺序执行的的方法:
removeServiceRequest , addServiceRequest , discoverServices
它们是按这个确切的顺序调用的,并且只有在前一个方法通过 onSuccess“返回”后才调用特定方法(准确地说是第二个或第三个)。打回来。
services的重新发现正在使用直观的方法执行(只需重复上述顺序: 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();
}
private void startServiceDiscovery() {
mWifiP2pManager.removeServiceRequest(mWifiP2pChannel, mWifiP2pServiceRequest,
new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
mWifiP2pManager.addServiceRequest(mWifiP2pChannel, mWifiP2pServiceRequest,
new WifiP2pManager.ActionListener() {

@Override
public void onSuccess() {
mWifiP2pManager.discoverServices(mWifiP2pChannel,
new WifiP2pManager.ActionListener() {

@Override
public void onSuccess() {
//service discovery started

mServiceDiscoveringHandler.postDelayed(
mServiceDiscoveringRunnable,
SERVICE_DISCOVERING_INTERVAL);
}

@Override
public void onFailure(int error) {
// react to failure of starting service discovery
}
});
}

@Override
public void onFailure(int error) {
// react to failure of adding service request
}
});
}

@Override
public void onFailure(int reason) {
// react to failure of removing service request
}
});
}
mServiceDiscoveringRunnable只是:
private Runnable mServiceDiscoveringRunnable = new Runnable() {
@Override
public void run() {
startServiceDiscovery();
}
};

所有这些使我的系统运行良好。它还不完美,但由于缺乏关于这个主题的文档,我认为我无法做更多的改进。

如果您测试这种方法,请务必告诉我它如何为您工作(或者它是否适合您;))。

关于android - Wifi P2P 服务发现间歇性工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26300889/

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