Error interno al utilizar Descubrimiento de servicio de red en Android

Durante la primera implementación del NSDManager utilizando los ejemplos y el tutorial en la página del desarrollador , la aplicación inició correctamente el descubrimiento y encontró los dispositivos.

Sin embargo ahora parece estar roto …

Cuando se inicia el programa, después de alguna inicialización, el código entra en el método siguiente y se ejecuta correctamente:

public void discoverServices() { Log.d(TAG, "Initializing discovery on NSD"); mNsdManager.discoverServices( SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener); } 

Se recibe el mensaje de registro. Después de un buen rato (digamos aproximadamente 5 minutos) esto se emite del programa:

 05-21 11:08:32.518: E/NsdCamera(12236): Discovery failed: Error code:0 05-21 11:08:32.518: W/dalvikvm(12236): threadid=12: thread exiting with uncaught exception (group=0x40c9c930) 05-21 11:08:32.518: E/AndroidRuntime(12236): FATAL EXCEPTION: NsdManager 05-21 11:08:32.518: E/AndroidRuntime(12236): java.lang.NullPointerException 05-21 11:08:32.518: E/AndroidRuntime(12236): at android.net.nsd.NsdManager$ServiceHandler.handleMessage(NsdManager.java:338) 05-21 11:08:32.518: E/AndroidRuntime(12236): at android.os.Handler.dispatchMessage(Handler.java:99) 05-21 11:08:32.518: E/AndroidRuntime(12236): at android.os.Looper.loop(Looper.java:137) 05-21 11:08:32.518: E/AndroidRuntime(12236): at android.os.HandlerThread.run(HandlerThread.java:60) 

También de los servicios:

 05-21 11:50:49.108: E/NativeDaemonConnector.ResponseQueue(8858): Timeout waiting for response 05-21 11:50:49.108: E/mDnsConnector(8858): timed-out waiting for response to 10 mdnssd discover 6 _http._tcp. 05-21 11:50:49.108: E/NsdService(8858): Failed to discoverServices com.android.server.NativeDaemonConnector$NativeDaemonFailureException: command '10 mdnssd discover 6 _http._tcp.' failed with 'null' 

El código de error "0" se describe en la clase NSDManager como un error interno. Las principales actualizaciones que hice fue el acceso al contexto en la clase auxiliar llamada NsdCamera. He aquí algunos fragmentos de código probablemente malvados:

Helper-clase constructor:

 public NsdCamera(CameraChooseActivity context) { mContext = context; updateUI = new UpdateUI(); mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); mServiceName = new Vector<NsdServiceInfo>(); 

Inicialización NSD de clase auxiliar:

 public void initializeNsd() { initializeDiscoveryListener(); } public void initializeDiscoveryListener() { mDiscoveryListener = new NsdManager.DiscoveryListener() { @Override public void onDiscoveryStarted(String regType) { Log.d(TAG, "Service discovery started"); } /** * A name check to see if the DNS discovery was correct. Checks if it contains * AXIS and has the desired MAC address-space * @param hostname ,the inputted hostname from the discovery cycle * @return true if it's an Axis camera. */ public boolean nameCheck(String hostname){ return (hostname.contains("AXIS") && hostname.contains("00408C")); } @Override public void onServiceFound(NsdServiceInfo service) { Log.d(TAG, "Service discovery success: " + service.getServiceName()); if (!service.getServiceType().equals(SERVICE_TYPE)) { Log.d(TAG, "Unknown Service Type: " + service.getServiceType()); } else if (nameCheck(service.getServiceName())){ mServiceName.add(service); // updateUI.execute(new BundleUI(mContext,service, null)); } } @Override public void onServiceLost(NsdServiceInfo service) { Log.e(TAG, "service lost" + service); if(mServiceName.remove(service)){ //TODO Log.e(TAG, "remove the view, service is lost"); } } @Override public void onDiscoveryStopped(String serviceType) { Log.i(TAG, "Discovery stopped: " + serviceType); //Necessary?? mServiceName.clear(); } @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); } }; } 

CameraChooseActivity -> onCreate está llamando a la clase auxiliar

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_camerachoose); //Setup the animation for the text in the Relativelayout mDescription = (TextSwitcher) findViewById(R.id.camera_add); mDescription.setFactory(this); mDescription.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in)); mDescription.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out)); mDescription.setText(getText(R.string.camera_add)); //Building alert dialog mBuilder = new AlertDialog.Builder(this,AlertDialog.THEME_HOLO_DARK); mBuilder.setMessage(R.string.dialog_about).setTitle(R.string.action_about); mBuilder.setIcon(android.R.drawable.ic_dialog_info); mLayout = (RelativeLayout) findViewById(R.id.layout_camerachoose); //Initialize the NSD mNSDHelper = new NsdCamera(this); mNSDHelper.initializeNsd(); 

Base en mi experiencia, supongo que esto es un tema de vida de escucha.

Debido a que proporciona dos oyentes al servicio NSD del sistema, uno es para startServiceDiscovery () y otro para stopServiceDiscovery (). Usted necesita cerciorarse de estos oyentes todavía vivo cuando el sistema accede a estos oyentes.

Un hecho es que onStartDiscoveryFailed () se llama 2 minutos después de que startServiceDiscovery () se llama, debe ser mucho tiempo en comparación con la vida del oyente.

Por lo tanto, si el listener es un objeto local y se libera después de llamar a startServiceDiscovery (), puede causar que el servicio NSD se bloquee.

Public void stopServiceDiscovery (escuchador NsdManager.DiscoveryListener)

Detenga el descubrimiento del servicio iniciado con discoverServices (). Un descubrimiento de servicio activo se notifica a la aplicación con onDiscoveryStarted (String) y permanece activo hasta que la aplicación invoca un descubrimiento de servicio de detención. Se notifica una detención satisfactoria con una llamada a onDiscoveryStopped (String).

Si no se interrumpe el descubrimiento del servicio, la aplicación se notifica mediante onStopDiscoveryFailed (String, int).

Parameters listener Debe ser el objeto de escucha que se pasó a discoverServices (String, int, NsdManager.DiscoveryListener). Identifica el descubrimiento que debe ser detenido y notifica de una detención exitosa.

Y debajo del fragmento, asegúrese de no llamar a ninguna api de NsdManager.

 @Override public void onStartDiscoveryFailed(String serviceType, int errorCode) { Log.i(TAG, "onStartDiscoveryFailed : Error code:" + errorCode); } @Override public void onStopDiscoveryFailed(String serviceType, int errorCode) { Log.i(TAG, "onStopDiscoveryFailed : Error code:" + errorCode); } 

Buena suerte.

Un simple reinicio del DUT resultó ser la solución. Debo decir que el error es bastante extraño. Creo que el daemon se estrelló y no se reinició.

(Si alguien puede publicar un análisis o tiene una solución mucho mejor, por favor, publicarlo)

  • Android Development: Cambio del brillo de la pantalla en el servicio
  • Grabar sonido Y reproducir sonido modulado En Android?
  • Cómo mostrar un cuadro de diálogo de un servicio
  • ResultReceiver no sobrevive a la rotación de la pantalla
  • Conexión a un servicio web desde android - AsyncTask o Service?
  • Diseño de hilos múltiples de Android Service
  • ¿Cómo saber cuántas aplicaciones se ejecutan en segundo plano en android?
  • En servicio de facturación de aplicaciones que se mueren a veces
  • Android detecta el estado táctil desde cualquier aplicación
  • El mejor enfoque para ejecutar el servicio en Android
  • ¿Puedo iniciarService desde la aplicación # onCreate ()?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.