2015-09-15 2 views
0

Может кто-то, пожалуйста, помогите мне выяснить, почему я могу получить только нулевой файловый дескриптор в разъем Bluetooth, открытый через BluetoothServerSocket.accept()?Почему мой файловый дескриптор в гнездо bluetooth не равен нулю?

Моя цель - потоковое видео между двумя устройствами через Bluetooth, путем записи видео в дескриптор файла с одной стороны и чтения его из файлового дескриптора с другой стороны. Мое Bluetooth-соединение хорошее, я могу отправлять необработанные данные взад и вперед, но я могу получить только дескриптор файла на стороне клиента. На стороне сервера, используя тот же код, я могу получить только нулевой файловый дескриптор. В отладчике я вижу файловый дескриптор на стороне сервера в mySocket.mSocketIS.this $ 0.fd, но я не могу понять, как получить к нему доступ. Может ли кто-нибудь помочь? Это Android 4.4.2, вот мой код:

Сначала неработающей код (на стороне сервера):

// Listen for an incoming Bluetooth connection 
class AcceptThread extends Thread 
{ 
    // Thread that accepts incoming bluetooth connections 
    public AcceptThread() 
    { 
     try 
     { 
      // Open a listening server socket. This is non-blocking 
      btServerSocket = BA.listenUsingRfcommWithServiceRecord("ServerApp", videoUUID); 
     } catch(IOException e){ btServerSocket = null; } 
    } // AcceptThread() 

    public void run() 
    { 
     BluetoothSocket btSocket = null; 

     // Listen until exception or we have a socket 
     while(true) 
     { 
      try 
      { 
       // Blocking call to accept an incoming connection. To get out of this, call cancel() which closes the socket, causing .accept() to throw an exception 
       btSocket = btServerSocket.accept(); 
       // If we get here, we're connected! 

       Field pfdField = btSocket.getClass().getDeclaredField("mPfd"); 
       pfdField.setAccessible(true); 
       ParcelFileDescriptor pfd = (ParcelFileDescriptor) pfdField.get(btSocket); 

       // >>> ERROR - pfd is null <<<< I can see a fd at mySocket.mSocketIS.this$0.fd;, but how do I access it? 


       FileDescriptor myFd = pfd.getFileDescriptor(); 


       // ... blah blah... 

Теперь рабочий код (на стороне клиента):

// Connect to a remote device as the client (we are the client) 
class ConnectThread extends Thread 
{ 
    // ctor 
    // remoteUUID - The UUID of the remote device that we want to connect to 
    public ConnectThread(BluetoothDevice btDevice, UUID remoteUUID) 
    { 
     // Get a BT socket to connect with the given BluetoothDevice 
     try 
     { 
      // MY_UUID is the app's UUID string, also used by the server code 
      btClientSocket = btDevice.createRfcommSocketToServiceRecord(remoteUUID); 
     }catch(Exception e){ postUIMessage("ConnectThread exception: " + e.toString()); } 
    } // ConnectThread ctor 

    public void run() 
    { 
     // Cancel discovery because it will slow down the connection 
     BA.cancelDiscovery(); 
     try 
     { 
      // Connect the device through the socket. This will block until it succeeds or throws an exception. To get out, call cancel() below, which will cause .connect() to throw an exception. 
      btClientSocket.connect(); 

      Field pfdField = btClientSocket.getClass().getDeclaredField("mPfd"); 
      pfdField.setAccessible(true); 
      ParcelFileDescriptor pfd = (ParcelFileDescriptor) pfdField.get(btClientSocket); 
      FileDescriptor myFd = pfd.getFileDescriptor(); // Pass this to Recorder.setOutputFile(); 

      // Yay myFd is good! 

ответ

0

Я нашел исправить на моей стороне относительно этой проблемы, мы используем bluetooth как сервер. Я нашел файловый дескриптор из поля LocalSocket в BluetoothSocket. Моя цель состояла в том, чтобы получить файл и закрыть его.

int mfd = 0; 
     Field socketField = null; 
     LocalSocket mSocket = null; 

     try 
     { 
      socketField = btSocket.getClass().getDeclaredField("mSocket"); 
      socketField.setAccessible(true); 

      mSocket = (LocalSocket)socketField.get(btSocket); 
     } 
     catch(Exception e) 
     { 
      Log ("Exception getting mSocket in cleanCloseFix(): " + e.toString()); 
     } 

     if(mSocket != null) 
     { 
      FileDescriptor fileDescriptor = 
        mSocket.getFileDescriptor(); 

      String in = fileDescriptor.toString(); 

      //regular expression to get filedescriptor index id 
      Pattern p = Pattern.compile("\\[(.*?)\\]"); 
      Matcher m = p.matcher(in); 

      while(m.find()) { 
       Log ("File Descriptor " + m.group(1)); 
       mfd = Integer.parseInt(m.group(1)); 
       break; 
      } 

      //Shutdown the socket properly 
      mSocket.shutdownInput(); 
      mSocket.shutdownOutput(); 
      mSocket.close(); 

      mSocket = null; 

      try { socketField.set(btSocket, mSocket); } 
      catch(Exception e) 
      { 
       Log ("Exception setting mSocket = null in cleanCloseFix(): " + e.toString()); 
      } 

      //Close the file descriptor when we have it from the Local Socket 
      try { 
       ParcelFileDescriptor parcelFileDescriptor = ParcelFileDescriptor.adoptFd(mfd); 
       if (parcelFileDescriptor != null) { 
        parcelFileDescriptor.close(); 
        Log ("File descriptor close succeed : FD = " + mfd); 
       } 
      } catch (Exception ex) { 
       Log ("File descriptor close exception " + ex.getMessage()); 
      } 
     } 
+0

Благодарим за информацию! Я попробую это, когда вернусь к проекту. – Matt

Смежные вопросы