我一直试图发现多个同伴 - 在后台服务中多次而不是活动。广泛基于此: http://developer.android.com/training/connect-devices-wirelessly/nsd-wifi-direct.html
因为,如果该对等体消失并返回范围,则一旦收到对等体的广告服务就不会再出现。我需要重新发现相同的同伴的原因是我根据应用程序的使用情况更改了TXT记录值。需要重新公布,接收设备使用新值更新本地文件。
尽管如此,我还是设法以一种不可靠的方式使用它。 通过,删除localservice和serviceRequest并使用处理程序重新启动注册和发现。
但是,我所注意到的是,即使广告设备已经停止广告,并且TXT听众也没有附加,有时也会将一些较早的广告合并并继续显示。这会导致WifiP2pManager在添加本地服务以及服务发现请求时忽略警告。因此,听众有时不会获得广告,而有时甚至在Wifi被禁用时仍会收到广告。
01-06 17:14:34.324 26591-26591/com.cutting.chai.wifi D/WifiP2pManager﹕ Ignored { when=-25ms what=139313 target=android.net.wifi.p2p.WifiP2pManager$Channel$P2pHandler }
[ 01-06 17:14:34.324 26591:26591 D/Status] Added Local Service
01-06 17:14:34.324 26591-26591/com.cutting.chai.wifi D/WifiP2pManager﹕ Ignored { when=-25ms what=139313 target=android.net.wifi.p2p.WifiP2pManager$Channel$P2pHandler }
01-06 17:14:34.324 26591-26591/com.cutting.chai.wifi D/WifiP2pManager﹕ Ignored { when=-26ms what=139313 target=android.net.wifi.p2p.WifiP2pManager$Channel$P2pHandler }
[ 01-06 17:14:34.324 26591:26591 D/Status] Added service discovery request
以下是我的代码:
public class WifiDirectDiscoverService extends Service{
public static final String TAG = "wifidirectservicedemo";
// TXT RECORD properties
public static final String TXTRECORD_PROP_AVAILABLE = "available";
public static final String SERVICE_INSTANCE = "_ccwifidirect";
public static final String SERVICE_REG_TYPE = "_presence._tcp";
private WifiP2pManager manager;
private final IntentFilter intentFilter = new IntentFilter();
private WifiP2pManager.Channel channel;
private BroadcastReceiver mReceiver;
private WifiP2pDnsSdServiceRequest serviceRequest;
WifiP2pDnsSdServiceInfo service;
/* Preferences to get user data to set the advertisement record */
private ccSharedPreferences sharedPreferences;
private String[] interestCodes;
private String[] hobbyCodes;
Handler mHandler = new Handler();
@Override
public IBinder onBind(Intent arg0) {
return null;
}
public void onCreate() {
super.onCreate();
Log.d("Server", ">>>onCreate()");
}
final Runnable ToastRunnable = new Runnable(){
public void run(){
Toast.makeText(getApplicationContext(), "discover service",
Toast.LENGTH_LONG).show();
manager.removeLocalService(channel, service, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess () {
appendStatus("Remove Local Service");
}
@Override
public void onFailure ( int error){
appendStatus("Failed to remove a service "+error);
}
});
manager.removeServiceRequest(channel, serviceRequest, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
appendStatus("Clear Service Requests");
}
@Override
public void onFailure(int error) {
appendStatus("Failed to clear Service Requests "+error);
}
});
startRegistration();
setupListener();
initiateDiscovery();
mHandler.postDelayed(ToastRunnable, 15000);
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, startId, startId);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter
.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter
.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = manager.initialize(getApplicationContext(), getMainLooper(), null);
mReceiver = new WiFiDirectBroadcastReceiver(manager, channel, WifiDirectDiscoverService.this);
registerReceiver(mReceiver, intentFilter);
startRegistration();
setupListener();
initiateDiscovery();
mHandler.postDelayed(ToastRunnable, 10000);
return START_STICKY;
}
/**
* Registers a local service and then initiates a service discovery
*/
private void startRegistration() {
sharedPreferences = new ccSharedPreferences();
Map<String, String> record = new HashMap<>();
record.put(TXTRECORD_PROP_AVAILABLE, "visible");
int size = record.toString().length();
Toast.makeText(getApplicationContext(), size + " bytes record ", Toast.LENGTH_LONG).show();
service = WifiP2pDnsSdServiceInfo.newInstance(
SERVICE_INSTANCE, SERVICE_REG_TYPE, record);
manager.addLocalService(channel, service, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
appendStatus("Added Local Service");
}
@Override
public void onFailure(int error) {
appendStatus("Failed to add a service "+error);
}
});
}
private void setupListener() {
/*
* Register listeners for DNS-SD services. These are callbacks invoked
* by the system when a service is actually discovered.
*/
WifiP2pManager.DnsSdTxtRecordListener txtListener = new WifiP2pManager.DnsSdTxtRecordListener() {
/**
* A new TXT record is available. Pick up the advertised
* buddy name.
*/
@Override
public void onDnsSdTxtRecordAvailable(
String fullDomainName, Map<String, String> record,
WifiP2pDevice device) {
if (record.get(TXTRECORD_PROP_AVAILABLE) != null) {
Log.d(TAG,
device.deviceName + " is "
+ record.get(TXTRECORD_PROP_AVAILABLE));
Toast.makeText(getApplicationContext(), device.deviceName + " is " + record.get(TXTRECORD_PROP_AVAILABLE), Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), "Advertised Service is " + record.toString(), Toast.LENGTH_LONG).show();
Log.d("Record", record.toString());
}
}
};
WifiP2pManager.DnsSdServiceResponseListener servListener = new WifiP2pManager.DnsSdServiceResponseListener() {
@Override
public void onDnsSdServiceAvailable(String instanceName,
String registrationType, WifiP2pDevice srcDevice) {
// A service has been discovered. Is this our app?
if (instanceName.equalsIgnoreCase(SERVICE_INSTANCE)) {
// update the UI and add the item the discovered
// device.
WiFiP2pService service = new WiFiP2pService();
service.device = srcDevice;
service.instanceName = instanceName;
service.serviceRegistrationType = registrationType;
Log.d(TAG, "onBonjourServiceAvailable "
+ instanceName);
Toast.makeText(getApplicationContext(), service.device + " is around ", Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), instanceName + " is the instance name ", Toast.LENGTH_LONG).show();
}
}
};
manager.setDnsSdResponseListeners(channel, servListener, txtListener);
}
public void initiateDiscovery(){
// After attaching listeners, create a service request and initiate
// discovery.
serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
manager.addServiceRequest(channel, serviceRequest,
new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
appendStatus("Added service discovery request");
}
@Override
public void onFailure(int arg0) {
appendStatus("Failed adding service discovery request "+arg0);
}
});
manager.discoverServices(channel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
appendStatus("Service discovery initiated");
}
@Override
public void onFailure(int arg0) {
appendStatus("Service discovery failed "+arg0);
}
});
}
public void appendStatus(String status) {
Log.d("Status" + "\n", status);
}
@Override
public void onDestroy() {
Toast.makeText(this, "service onDestroy", Toast.LENGTH_LONG).show();
mHandler.removeCallbacksAndMessages(null);
}
}
我也读过这个:Sending data in Android WiFi Direct service discovery instead of connecting
虽然,我理解使用多播DNS发现的不可靠性主要用于服务发现而非消息传递方案。就我而言,记录值不会经常变化。但是,我需要确保广告和发现以及多个同伴发生而没有所描述的不稳定行为。
非常感谢您对此的任何帮助!
谢谢!
ARNAB