2010-04-22 99 views
1

我正在做藍牙開發,用於連接電腦。我基本上使用BTChatExample並將UUID更改爲標準PC SPP配置文件。2.0+上的藍牙

  1. 試圖在阻塞讀取過程中關閉藍牙應用程序時,通過關閉BluetoothSocket將使藍牙堆棧處於不可用狀態。這隻能通過禁用和啓用藍牙並重新啓動應用程序來解決。檢查logcat,你可以看到一些內部方法失敗,留下一個開放的端口。這方面的任何信息?

  2. 首先,在N1和HTC Legend/Desire上如何實現藍牙的差異如何,這兩者運行2.1,你知道這件事嗎?

  3. 連接並非100%可靠,有時我會收到一條警告,說~PortSystemContext init: FAILED。這使藍牙無法使用,並且需要重新啓動。

  4. 我是否正確地認爲SPP是唯一支持使用API​​的配置文件?這就是BluetoothAdapter上的文檔所說的。

我很樂意與開發人員討論藍牙問題,並解決這些問題,以便Android可以擁有良好的適當藍牙支持。

回答

2

在阻塞讀取期間關閉一個線程中的套接字應該肯定會導致讀取返回(通過拋出IOException)並且不應該使堆棧處於「不良狀態」。這是Droid和Nexus上的行爲。

我直接與原始海報對話,他在HTC Legend和HTC Desire上觀察到了這個問題。看起來他們沒有正確實施API。我正在向他們提出這個問題。

您是正確的SPP/RFCOMM是旨在與API的使用唯一的配置文件。 SPP/RFCOMM爲您提供了一個流式套接字,足以滿足很多用例的需求。

現在我推薦Nexus One/Motorola Droid上的BT開發,它們被認爲是Bluetooth API的「參考」實現。

1

我可以建議您不要阻止read()調用,除非您首先使用inputstream.available()檢查是否有數據已準備好被讀取,它將返回一個整數,指示在輸入緩衝區中等待的字節數。

long timeouttime = gettimeinseconds() + 2; 
    String response = ""; 

    while (gettimeinseconds() < timeouttime) { 
     if (inputstream.available() > 0) 
      response = response + inputstream.read(); 
     } else { 
      Thread.sleep(100); // sleep to slow down the while() loop. 
     } 
    } 
return response; 

這只是僞代碼,其過於簡化。最重要的是,除非我們確信他們會立即返回,否則我們不會執行任何阻止呼叫(read())。

此外,我強烈建議使用BufferedInputStream而不是標準InputStream

0

任何人都可以解決這個問題?

我試試下面的代碼:

// Keep listening to the InputStream while connected 
while (!isInterrupted) 
{ 
    try 
    { 
     //Clear buffer 
     buffer = new byte[1024]; 

     // Read from the InputStream 
     if (mmInStream != null && mmInStream.available() > 0) 
     { 
      if (isInterrupted) 
       break; 

      bytes = mmInStream.read(buffer); 

      // Send the obtained bytes to the UI Activity 
      mHandler.obtainMessage(Act_Main.MESSAGE_READ, bytes, -1, buffer).sendToTarget(); 
     } 
     else 
     { 
      try 
      { 
       synchronized (this) 
       { 
        this.wait(100); 
       } 

       if (isInterrupted) 
        break; 
      } 
      catch(InterruptedException ex) 
      { 
       Log.e(TAG, "WAIT_EXCEPTION:"+ ex.getMessage()); 
      } 
     } 
    } 
    catch(Exception ex) 
    { 
     Log.e(TAG, "disconnected", ex); 
     connectionLost(); 
     break; 
    } 
} 

我在cancel()方法改變了isInterrupted布爾。這裏是我的stop()方法:

/** 
* Stop all threads 
*/ 
public synchronized void stop() 
{ 
    isStop = true ; 

    if (D) 
     Log.d(TAG, "stop"); 

    if(mConnectThread != null) 
    { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
    } 

    if(mConnectedThread != null) 
    { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 
    } 

    setState(STATE_NONE); 
}