2012-05-12 199 views
2

我正在爲Android設計一款遊戲,其中兩臺設備連接並交易少量數據,然後斷開並使用該數據。我從藍牙聊天的例子開始。在這一點上,我主要工作,但一些(大多數)時間,其中一個設備從未收到任何數據。這是兩個設備上的同一個應用程序,因此兩者的發送和接收代碼都是相同的。 我連這樣的:Android藍牙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; 
      } 
     } 
    } 

它一次讀取數據的一個字節,追加字節的數據包串。當到達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); 
     } 
    } 

正如你所看到的,我寫的,當數據「包」發送日誌,接收到一個字節時,當整個「包」已收到。

我不確定這是否有任何相關性,但: 我使用帶有Cyanogenmod 7.1(Android 2.3.7)和運行在VirtualBox(Android 2.3.5)中的Android x86的Nook Color進行測試。我的應用程序minSdkVersion是8(Android 2.2)。對於在我的電腦上運行的Android,我正在使用Rocketfish USB藍牙適配器。

應該有兩個數據包由每個實例發送。首先,發送保存所有所需遊戲數據的數據分組。 當收到其他實例的遊戲數據時,應用程序將自己的布爾值設置爲true。 它也發送一個「完成」數據包到另一個實例。 因此,一旦兩個實例都完成了,並且知道另一個完成了,我們知道所有的數據已經被髮送和接收,並且它們都斷開/停止它們的藍牙線程並且對數據執行操作。

由於我在發送和接收數據時在兩臺設備上登錄,日誌告訴我一個發生了什麼事情的故事。

- 首先,我開始兩款遊戲並進入藍牙活動(顯然)。

- 下一步,我連接到仿真實例的Nook實例。

- 模擬實例發送它的遊戲數據包。 - Nook實例接收模擬實例的遊戲數據,併發送它自己的(有時這兩個按順序切換,僅僅因爲它們是異步發生的)。

- 由於它收到一個遊戲數據包,Nook實例現在發送它的「完成」數據包。

- 就是這樣。仿真實例永遠不會收到任何數據包。它甚至從來沒有收到一個字節,並且input.read()只是阻塞,等待從未到達的輸入(就像它應該)。

這就是我的問題。看來,兩件事情正在發生:

  1. 的數據將無法得到output.write()上的Nook實例發送,即使它不拋出任何異常,並且日誌驗證它被調用。

  2. 數據永遠不會被仿真實例上的input.read()接收到。也許它在傳輸中丟失了?

據我所知,我的代碼是堅如磐石的。這個問題似乎與藍牙相關。也許一個或兩個Android實例有一個棘手的藍牙設置?

我還想補充一點,每隔一段時間(也許只有1/15次),所有數據包都會正確發送和接收,並且遊戲繼續進行。所以不管怎麼樣,只有USUALLY會發生,但並非總是如此。

回答

1

我可以訪問另一個帶藍牙的Android設備。自從我測試了我的遊戲,並且它連接並且設備正確地交易數據。我發現了其他一些程序錯誤,這些錯誤發生在藍牙技術之後,但這並不在那裏!

以前的Nook顏色和HTC狀態是一起工作的。然後,我正式得出結論,我的電腦上有一個錯誤的藍牙適配器。上面的代碼很好地工作。

相關問題