usar studio smart sirve samsung que para direct desactivar como android wifi-direct service-discovery wifip2p dns-sd

android - studio - El descubrimiento del servicio Wifi P2P funciona intermitentemente



wifi direct para pc (2)

WifiP2p (en general):

Hace algún tiempo estaba desarrollando una aplicación con un sistema de conectividad de red bastante complejo basado en WifiP2p con Service Broadcasting/Discovery . Y en base a esa experiencia, ya escribí algunas publicaciones aquí sobre SO sobre cuán difícil, desgastado y problemático es. Aquí hay dos de ellos (están bastante llenos del conocimiento interno que adquirí sobre WifiP2p con Service Discovery , y el mismo WifiP2p ):

¿Por qué es tan poco fiable descubrir compañeros para Android WifiDirect?

Wi-fi P2P. Informar a todos los compañeros disponibles de algún evento.

Le aconsejaría que leyera mis dos respuestas (aunque están un poco más centradas en el WifiP2p ). Deben darle una perspectiva sobre las cosas que debe buscar cuando trabaje con el WifiP2p Service Discovery . Puedo decir fácilmente que si desea construir un sistema de conexión WifiP2p eficiente, relativamente confiable y robusto (especialmente con Service Discovery ), tendrá que trabajar duro.

WifiP2p Service Discovery :

Para responder mejor a su pregunta exacta, le diré lo que hice (diferente a usted) para que mi Service Discovery funcione de manera bastante confiable.

1. Service radiodifusión:

En primer lugar: antes de registrar su Service (con el método addLocalService ), debe usar el método clearLocalServices del clearLocalServices . Y es importante, que solo debe llamar a addLocalService si el escucha pasó en los clearLocalServices devueltos con la onSuccess llamada onSuccess .

Aunque esto configura la transmisión bastante bien, descubrí que otros nodos no siempre podían detectar el service transmitido (especialmente cuando esos nodos no detectaban activamente los servicios en el momento de registrar su Service local, pero se "unieron" más tarde ). No pude encontrar una manera de solucionar este problema de forma 100% confiable. Y créeme, estaba intentando probablemente todo WifiP2p relacionado con WifiP2p . Y no, la secuencia clearLocalServices - addLocalService no estaba dando resultados satisfactorios. O más aún: hacer algo diferente funcionaba mucho mejor. Lo que decidí hacer fue después de haber agregado exitosamente el servicio local (devolución de llamada addLocalService de addLocalService ), comencé un Thread que periódicamente llamaba WifiP2pManager método WifiP2pManager de WifiP2pManager . Eso parecía estar obligando a retransmitir toda la información del service .

Entonces ... básicamente, la base de su código de transmisión debería tener un aspecto más o menos así (tenga en cuenta que cada pieza de código que publicaré aquí se eliminará de todas las "comprobaciones" si el sistema de conectividad de la red es correcto Estado, debe diseñarlas usted mismo para que se adapte mejor a su solución):

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

donde mServiceBroadcastingRunnable debe ser:

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. Descubriendo Service :

Para el descubrimiento de su service he utilizado un enfoque similar. Tanto con la configuración del descubrimiento como con el intento de forzar el "redescubrimiento" de los services .

La configuración se realizó con la secuencia de los siguientes tres métodos de WifiP2pManager :

addServiceRequest , addServiceRequest , discoverServices

Se llamaron en este orden exacto y se ha llamado a un método particular (el segundo o el tercero para ser exactos) solo después de que el anterior hubiera "regresado" con la onSuccess llamada onSuccess .

El redescubrimiento de services se estaba realizando con el método intuitivo (solo repitiendo la secuencia mencionada: removeServiceRequest -> addServiceRequest -> discoverServices ).

La base de mi código se veía más o menos así (para iniciar Service Discovery , primero llamaría a prepareServiceDiscovery() y luego 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 } }); }

El mServiceDiscoveringRunnable era justo:

private Runnable mServiceDiscoveringRunnable = new Runnable() { @Override public void run() { startServiceDiscovery(); } };

Todo esto hizo que mi sistema funcionara bastante bien. Todavía no era perfecto, pero con la falta de documentación sobre este tema, creo que no podría hacer mucho más para mejorarlo.

Si prueba este enfoque, asegúrese de decirme cómo funciona para usted (o si funciona para usted;)).

El descubrimiento del servicio Wifi P2P no se está comportando como se esperaba. Estoy viendo problemas intermitentes en los que no siempre se llama a los oyentes de DNSSD y, por lo tanto, no tengo ni idea de los dispositivos cercanos que ejecutan la misma aplicación. Estoy usando las siguientes dos API: una para registrar un servicio que descubrirán otros dispositivos y la otra para descubrir los servicios cercanos que se ejecutan en otros dispositivos. Cualquier idea de si estoy haciendo algo incorrecto aquí o si hay alguna secuencia específica de otras llamadas a la API de Android que se debe hacer antes de llamar a estas API para asegurar que siempre se llame a los oyentes siempre que haya un nuevo servicio registrado o incluso si un servicio Se registra antes de que llamemos a la API para descubrir los servicios locales.

API para registrar un servicio local:

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 para descubrir servicios locales:

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

Nota: el administrador y el canal se inicializan como

WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); Channel channel = manager.initialize(this, getMainLooper(), null);


Si el problema es la detección del servicio, creo que crear un grupo es la mejor manera de hacer que el dispositivo y el servicio sean detectables, pero el grupo creado en todos los dispositivos no se puede conectar directamente. Pero como red wifi. Lo hago todos los días y funciona.