2012-05-12 3 views
2

Я делаю игру для Android, в которой два устройства соединяются, а затем торгуют небольшим количеством данных, а затем отключают и используют эти данные. Я начал с примера Bluetooth Chat. На данный момент у меня это в основном работает, но в некоторые (большинство) времен одно из устройств никогда не получает никаких данных. Это одно и то же приложение на обоих устройствах, поэтому код отправки и получения для обоих вариантов одинаковый. я подключаю так:Android Bluetooth Inputstream.read никогда не получает данные

public BluetoothClientThread(BluetoothDevice get_device,boolean secure){ 
     BluetoothSocket temp=null; 
     device=get_device; 
     socket_type=secure?"Secure":"Insecure"; 

     try{ 
      if(secure){ 
       temp=device.createRfcommSocketToServiceRecord(UUID_SECURE); 
      } 
      else{ 
       temp=device.createRfcommSocketToServiceRecord(UUID_INSECURE); 
      } 
     } 
     catch(IOException e){ 
      StorageManager.error_log_add(context,TAG,"create() on "+socket_type+" client socket failed.",e); 
     } 

     socket=temp; 
    } 

    public void run(){ 
     bluetooth_adapter.cancelDiscovery(); 

     try{ 
      socket.connect(); 
     } 
     catch(IOException e){ 
      StorageManager.error_log_add(context,TAG,"Connection failed.",e); 

      try{ 
       socket.close(); 
      } 
      catch(IOException ioe){ 
       StorageManager.error_log_add(context,TAG,"close() on "+socket_type+" client socket failed during connection failure.",ioe); 
      } 

      connection_failed(); 

      return; 
     } 

     synchronized(BluetoothService.this){ 
      bluetooth_client_thread=null; 
     } 

     connected(socket,device,socket_type,false); 
    } 

После подключения, я хватаю, сокет getInputStream() и getOutputStream(). Затем я использую следующий код для чтения ввода на гнездо:

public void run(){ 
     String packet=""; 

     while(true){ 
      try{ 
       int get_byte=input.read(); 
       char get_char=(char)get_byte; 

       if(get_char!='\u0003'){ 
        StorageManager.error_log_add(context,"BluetoothService","Adding packet raw data: \""+get_char+"\"",null); 
        packet+=get_char; 
       } 
       else{ 
        StorageManager.error_log_add(context,"BluetoothService","Packet received:\n"+packet,null); 
        handler.obtainMessage(Activity_Battle_Menu.HANDLER_READ,packet).sendToTarget(); 
        packet=""; 
       } 

       if(done && they_done){ 
        handler.obtainMessage(Activity_Battle_Menu.HANDLER_READY).sendToTarget(); 
       } 
      } 
      catch(IOException e){ 
       StorageManager.error_log_add(context,TAG,"Connection lost.",e); 

       connection_lost(); 

       break; 
      } 
     } 
    } 

Он считывает данные одного байта, в то время, добавляя байты пакетов String. Когда достигнут символ ETX (который я нахожу в конце всего, когда я его отправляю), был получен полный пакет и передается в действие через обработчик, где он действует. Вот мое письмо Код:

public void write(byte[] buffer){ 
     try{ 
      StorageManager.error_log_add(context,"BluetoothService","Writing data:\n"+new String(buffer),null); 

      output.write(buffer); 
     } 
     catch(IOException e){ 
      StorageManager.error_log_add(context,TAG,"write() on "+socket_type+" connected socket failed.",e); 
     } 
    } 

Как вы можете видеть, я пишу в журнал, когда данные «пакет» отправляются, когда байты принимаются, и когда целый «пакет» был получен.

Я не уверен, что это относится к делу, но: Я тестирую это с помощью цвета Nook с Cyanogenmod 7.1 (Android 2.3.7) и Android x86, работающим в VirtualBox (Android 2.3.5). Мое приложение minSdkVersion - 8 (Android 2.2). Для Android, запущенного на моем компьютере, я использую USB-адаптер Rocketfish USB Bluetooth.

Предполагается, что должны быть два пакета данных, отправленных каждым экземпляром. Сначала отправляется пакет данных, содержащий все необходимые игровые данные. Когда полученные игровые данные другого экземпляра получены, приложение устанавливает свое собственное логическое значение в true. Он также отправляет пакет «done» в другой экземпляр. Таким образом, как только оба экземпляра выполнены, и знают, что все сделано, мы знаем, что все данные были отправлены и получены, и они оба отключают/останавливают свои потоки Bluetooth и действуют на данные.

Поскольку я регистрирую данные на обоих устройствах, когда данные отправляются и принимаются, журналы сообщают мне историю происходящего.

-Первый, я запускаю обе игры и перехожу к активности Bluetooth (очевидно).

-Следующий, я подключаюсь к экземпляру Nook из эмулируемого экземпляра.

-Эмулированный экземпляр отправляет пакет данных своей игры.

-Интерфейс Nook получает данные игрового процесса эмулируемого экземпляра и отправляет его (иногда эти два переключаются по порядку, только потому, что они происходят асинхронно).

-Поскольку он получил пакет данных игры, экземпляр Nook теперь отправляет свой «готовый» пакет.

-Что такое. Эмулируемый экземпляр никогда не получает ни одного пакета. Он никогда не получает ни одного байта, а input.read() просто блокирует, ожидая ввода, который никогда не приходит (как и должно).

Так что это моя проблема.Похоже, что одна из двух вещей происходит:

  1. данные никогда не отправляется на output.write() на экземпляре Nook, даже если он не выбрасывает никаких исключений, и журнал проверяет, что она вызывается ,

  2. Данные, которые никогда не получаются input.read() в эмулированном экземпляре. Может быть, он потерялся в передаче?

Насколько я могу судить, мой код твердый. Проблема, похоже, связана с Bluetooth. Может быть, один или оба Android-приложения имеют жесткую настройку Bluetooth?

Я также хочу добавить, что каждый раз, когда-либо (возможно, в 1/15 раза), все пакеты отправляются и принимаются должным образом, и игра продолжается так, как должна. Так что все, что не так, происходит только в УБЕЖДЕНИИ, но не всегда.

ответ

1

Я получил доступ к другому устройству Android с Bluetooth. С тех пор я тестировал свою игру, и она подключается, и устройства правильно обрабатывают данные. Я обнаружил несколько других ошибок с моей программой, которые происходят после Bluetooth, но это ни здесь, ни там!

Цвет обложки от предыдущего и статуса HTC - это то, что сработало вместе. Тогда я официально завершаю, что у меня есть неисправный адаптер Bluetooth на моем компьютере. Вышеприведенный код работает достаточно хорошо.

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