Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Al cancelar el socket del servidor bluetooth antes de aceptar, todo el proceso muere. ¿Por qué?

Estoy compilando para SDK 10 (2.3.3):

android:minSdkVersion="10" android:targetSdkVersion="16" 

Estoy probando en dos teléfonos inteligentes de Sony Ericsson. Uno tiene Android 2.3.7 en él y el otro 4.0.1.

  • Java / Android: clases locales anónimas vs clases nombradas
  • Ldd equivalente en android
  • Linked-in Once Authenticated: al llamar a Url del perfil de usuario otra vez pida autenticación
  • Equivalente a la vista "Problemas" de Eclipse en Android Studio
  • Android ViewPager cambia automáticamente la página
  • ¿Necesitamos instalar la imagen del sistema Intel x86 Atom para todos los niveles de API?
  • Estoy utilizando listenUsingInsecureRfcommWithServiceRecord para abrir un nuevo socket de servidor en bluetooth y escuchar conexiones.

    Si la conexión se acepta con éxito, entonces todo funciona bien. Incluso puedo intentar cancelar el socket del servidor pero eso no parece incomodar el socket de la conexión apenas creado.

    PERO cuando quiero cancelar el zócalo del servidor antes de haber aceptado cualquier conexión tan pronto como la línea bluetoothServerSocket.close(); Se ejecuta toda la actividad se cierra y el proceso muere. Y además esto no es una excepción regular que podría manejar.

    En realidad incluso logcat se cierra! Y tengo que ejecutarlo de nuevo rápidamente con el fin de agarrar los errores que puede ver a continuación:

     Zygote D Process 25471 terminated by signal (11) 295 InputDispatcher W channel '2c2e20a8 com.pligor.test/activities.MainActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x8 295 InputDispatcher E channel '2c2e20a8 com.pligor.test/activities.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed! 295 dalvikvm D GC_FOR_ALLOC freed 1299K, 21% free 13252K/16583K, paused 93ms 295 InputDispatcher W Attempted to unregister already unregistered input channel '2c2e20a8 com.pligor.test/activities.MainActivity (server)' 295 BluetoothService D Tracked app 25471 diedType:10 295 BluetoothService D Removing service record 10009 for pid 25471 132 SurfaceFlinger D Release buffer at 0x61c08 295 WindowManager I WINDOW DIED Window{2c2e20a8 com.pligor.test/activities.MainActivity paused=false} 295 ActivityManager I Process com.pligor.test (pid 25471) has died. 295 ActivityManager W Force removing ActivityRecord{2c021800 com.pligor.test/activities.MainActivity}: app died, no saved state 295 WindowManager W Failed looking up window 295 WindowManager W java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@2bf3e798 does not exist 295 WindowManager W at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7165) 295 WindowManager W at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7156) 295 WindowManager W at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1545) 295 WindowManager W at android.os.BinderProxy.sendDeathNotice(Binder.java:417) 295 WindowManager W at dalvik.system.NativeStart.run(Native Method) 295 WindowManager I WIN DEATH: null 295 BluetoothEventLoop D Property Changed: UUIDs : 11 295 hAdapterStateMachine D BluetoothOn process message: 51 295 InputManagerService W Got RemoteException sending setActive(false) notification to pid 25471 uid 10040 

    Nota: El proceso terminado por señal (11) significa error de segmentación ( http://en.wikipedia.org/wiki/SIGSEGV ).

    EDITAR

    Creo el socket del servidor Bluetooth con el siguiente código ( Scala ):

     private val bluetoothServerSocket: BluetoothServerSocket = try { bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(MY_SERVICE_NAME_INSE‌​CURE, MY_UUID_INSECURE); } catch { case e: IOException => throw new ServerSocketException; } 

    Utilizo este código para cerrar el conector Bluetooth :

     try { isCancelled = true; bluetoothServerSocket.close(); } catch { case e: IOException => throw new NotClosedException; } 

  • Obtener error de error de protocolo al instalar apk utilizando el comando adb en android
  • Migración desde eclipse + SVN a Android Studio
  • CÓDIGO DE RESPUESTA HTTP DE SD: 200 error con Flurry
  • Android Turn-by-Turn API?
  • No hay conexión a Internet para Visual Studio Android Emulator
  • ¿Cómo apagar un dispositivo Android?
  • 3 Solutions collect form web for “Al cancelar el socket del servidor bluetooth antes de aceptar, todo el proceso muere. ¿Por qué?”

    He experimentado un problema similar y la causa raíz del problema era llamar cerca de un zócalo más de una vez. Para corregir este problema, envuelve mis zócalos bluetooth en una clase especial para evitar que el método cercano sea llamado más de una vez.

    Tenga en cuenta que el cierre de los flujos creados por un zócalo bluetooth es capaz de llamar de cerca en el zócalo. Lo siguiente resuelve el problema.

     public class CloseOnceBluetoothSocket { private final BluetoothSocket mSocket; private boolean mIsClosed; public CloseOnceBluetoothSocket(BluetoothSocket socket) { this.mSocket = socket; } public void connect() throws IOException { mSocket.connect(); } public InputStream getInputStream() throws IOException { return new FilterInputStream(mSocket.getInputStream()) { @Override public void close() throws IOException { CloseOnceBluetoothSocket.this.close(); } }; } public OutputStream getOutputStream() throws IOException { return new FilterOutputStream(mSocket.getOutputStream()) { @Override public void close() throws IOException { CloseOnceBluetoothSocket.this.close(); } }; } public void close() throws IOException { synchronized (mSocket) { if (!mIsClosed) { mSocket.close(); mIsClosed = true; } } } } 

    Si el cierre del socket causa tanto daño, ¿por qué no sólo crear un indicador booleano que se establece en true cuando el usuario está conectado y configurado como false cuando el usuario se desconecta; Entonces solo llame cerca cuando el usuario estaba previamente conectado.

    Creo que he encontrado una solución para este problema. El "Pienso" es porque esto no ha sido probado en muchos dispositivos todavía.

    Código de abajo es Scala

    Para la solución me aprovecho del método sobrecargado accept (int) que tiene un tiempo de espera

    Así que tenemos una variable para el estado del bucle infinito que está viendo a continuación

     private var toContinue = true; 

    Sólo repetimos aceptar en un bucle de tiempo

     while (toContinue) { try { //this is a blocking call and will only return on a successful connection or an exception, or on timeout val socket = bluetoothServerSocket.accept(10000); //msec connectionAccepted(socket); } catch { case e: IOException => { Logger("accepting timed out"); } } } 

    Así que ahora en lugar de llamar al bluetoothServerSocket.close() estamos poniendo la variable a false

     def cancel() { toContinue = false; } 

    El código real es un poco más complejo ya que se necesita una función de devolución de llamada para hacer algo a la salida del bucle while pero el problema principal se resuelve como se muestra arriba

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.