簡體   English   中英

無法在Android 4.2上連續建立Bluetooth RFCOMM連接

[英]Bluetooth RFCOMM connection couldn't be established consecutively on Android 4.2

我有一個可以通過藍牙通過RFCOMM與自定義設備通信的應用程序。 通信代碼基於BluetoothTalk示例項目。 它之前在Galaxy S3,Galaxy S2,Galaxy Note和Nexus 7上運行都沒有問題。

最近,Nexus 7已升級到Android 4.2,此后,問題發生如下:

  1. 首次使用該應用程序建立連接時,這意味着該設備剛剛打開並且應用程序剛剛啟動,沒問題,您可以正常獲取數據。

  2. 然后,如果停止通信並嘗試重新啟動,則通信將失敗,並顯示錯誤“ java.io.IOException:bt套接字已關閉,讀取返回:-1”。 從那時起,無論您嘗試重新連接多少次,它始終總是失敗。

  3. 使它再次運行的唯一方法是,如果重新啟動自定義設備和該應用程序,然后嘗試連接,則通信將正常。 但是,一旦停止並重新啟動通訊,通訊就會繼續失敗。

我借用了Android 4.2的Nexus 4,問題仍然存在。

確實很煩人,因為我們設備的主要價值在於依賴Bluetooth RFCOMM應用程序。 我仔細檢查了Android 4.2中有關BT的文檔,但沒有發現任何重大變化。 我對自己的代碼很有信心,因為它適用於任何未運行4.2的Android設備

任何提示或建議,將不勝感激。 該設備需要在12月初進行演示,我們確實希望盡快解決此問題。

編輯:現在4.2.1已發布,問題仍然沒有解決。 我們能否至少獲得一些有關它是否正在工作並且即將修復的確認?

這對您無濟於事,但請注意,Google引入了帶有4.2的全新藍牙堆棧。

這應該是一件好事-根據我作為用戶和開發人員的經驗,帶有Bluez(舊版本的組合)的Android永遠無法可靠運行,因此,我很高興聽到他們進行了全面重寫。

我想我只能說聽起來像是您在新堆棧中遇到了錯誤或怪癖。 不幸的是聽到新堆棧也有問題。

關於您的演示,請注意,Google會發布其所有Nexus設備的固件映像(https://developers.google.com/android/nexus/images),並將它們刷新到您的設備相當容易。

因此,我建議您提交一個錯誤報告,然后將設備刷新到4.1.2。

我的測試也發生了這種情況。 在BluetoothChat示例代碼中,您應該查看connectionLost方法。 我不記得是否有任何變量可以保留丟失的連接數量,但您可以自己添加。 在connectionLost方法中,測試丟失的連接數量是否小於預定義的數量(在我的情況下為3)。 如果是這樣,請使用mHandler(祝酒)向UI發送消息,然后再次調用connect(device)。 如果不是這樣(您失去了3次以上的連接),請調用stop()方法。

還要確保像這樣在ConnectThread中打開套接字:

    public ConnectThread(BluetoothDevice device, boolean isSecure) {
        mmDevice = device;
        BluetoothSocket tmp = null;
        mSocketType = isSecure ? "Secure" : "Insecure";
        // Get a BluetoothSocket for a connection with the given BluetoothDevice
        if (isSecure) {
            // reflection is better to use
            Method m = null;
            try {
                Log.d(TAG, "create reflection");
                m = device.getClass().getMethod("createRfcommSocket",new Class[] { int.class });
                } catch (NoSuchMethodException e1) {
                e1.printStackTrace();
            }
            try {
                tmp = (BluetoothSocket) m.invoke(device, 1);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            mmSocketFallBack = tmp;
        } else {
            Log.d(TAG, "create insecure");
            try {
                tmp = device
                        .createInsecureRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        mmSocket = mmSocketFallBack;
    }

您的connectionLost應該看起來像:

public void connectionLost() {
    init = false;
    Log.d(TAG, "connectionLost -> " + mConnectionLostCount);
    mConnectionLostCount++;
  if (mConnectionLostCount < 3) {
    // Send a reconnect message back to the Activity
        Message msg = mHandler.obtainMessage(cBluetooth.MESSAGE_TOAST);
        Bundle bundle = new Bundle();
        bundle.putString(WebAppInterface.TOAST, "Connection lost. Reconnecting...");
        msg.setData(bundle);
        mHandler.sendMessage(msg);
        connect(mSavedDevice,true);     
    } else {
    mConnectionLostCount = 0;
    Message msg = mHandler.obtainMessage(cBluetooth.MESSAGE_TOAST);
    Bundle bundle = new Bundle();
    bundle.putString(WebAppInterface.TOAST,"Device connection was lost!");
    msg.setData(bundle);
    mHandler.sendMessage(msg);
    cBluetooth.this.stop();
    }
}

希望您可以根據自己的情況進行調整。 您也可以檢查此鏈接,它們對我有很大幫助:

  1. 遙控器示例
  2. 連接染色解決方案
  3. 藍牙服務示例從中得到啟發

我遇到了類似的問題,並花了一些時間調試此問題。 我正在運行Android 4.3,發現設置BluetoothChat示例代碼所需的唯一基本修改是:

MY_UUID_SECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

我正在嘗試連接到HC-05藍牙模塊,並且我相信它使用此UUID指示的SPP配置文件。 您可以使用以下代碼查詢設備的UUID:

UUID uuid = device.getUuids()[0].getUuid();

根據要連接的設備類型,驗證UUID並查看它是否與有意義的配置文件匹配。

MY_UUID_SECURE = uuid;

根據要連接的內容,UUID可能指示不同類型的設備配置文件。 有了正確的UUID,我仍然能夠運行AcceptThread代碼並作為BluetoothServerSocket進行偵聽而沒有任何問題。 我希望這對您有所幫助,但是,我對Android和藍牙技術的開發還比較陌生,因此,如果我的假設不對,請糾正我。

遇到類似的問題。 通過使用以17為構建目標的4.2 SDK進行構建,修復了其中的一些問題。

我終於找到了解決方案。

事實證明,這不是新的藍牙驅動程序中的錯誤。 這是藍牙示例應用程序(尤其是Android SDK提供的BluetoothChat項目)中未考慮的特殊情況。

在BluetoothChat示例項目中的Bluetooth服務代碼中,當連接失敗或丟失時,它將始終重新啟動服務以重新啟動監聽模式。 將電話用作服務器沒問題,但是,在某些情況下,將電話用作客戶端時,一旦進入偵聽模式,就無法連接到其他服務器。 因為在“連接”功能中,它不會取消(In)SecureAcceptThread。 因此,從本質上講,您在嘗試連接其他服務器連接時嘗試連接到其他服務器作為客戶端。 這是矛盾的。

解決此問題的方法是,如果您確定您的電話不會用作監聽傳入連接的服務器,則只需刪除代碼即可在連接失敗或停止后重新啟動監聽模式。

Nexus 4遇到相同的問題。

就我而言,我認為問題在於SDP服務發現協議。 設備和服務器必須對同一服務使用相同的UUID。

我在我的應用程序中使用SPP(串行端口協議)。 因此,我將UUID從BluetoothChat示例代碼中的“ fa87c0d0-afac-11de-8a39-0800200c9a66”更改為SPP“ 00001101-0000-1000-8000-00805F9B34FB”。 現在很好。

我禁用了BluetoothChatService.start()中acceptThread的偵聽代碼。 現在更加簡潔。 希望它會有所幫助。

我在4.2.2。上有相同的經驗。

但是我發現,只有在我的應用程序崩潰或在沒有正確清理資源(套接字和/或流)的情況下被殺死之后,藍牙堆棧才開始出現異常。 在此之前,當我正確關閉我的應用程序時,它可以正常工作。

例如,當我關閉套接字然后殺死該應用程序時,我可以啟動它並再次正常連接。 如果我在沒有關閉套接字的情況下殺死了我的應用程序,那該死的了,我必須重新啟動設備以使其再次運行。

因此,似乎新的Android藍牙堆棧在隱式清理機制中存在一些錯誤。 當應用程序崩潰時,Android應該清除未打開的藍牙資源。

我的藍牙管理代碼在Application子類中。 沒有辦法-或者我看不到-如何鈎住應用程序銷毀並進行清潔。

任何建議表示贊賞

編輯:

我做了一個很雜亂的解決方法。

我創建了包含單個遠程服務的單獨應用程序。 我將所有通信代碼(套接字和流的打開,讀取,寫入,關閉)移到了此遠程服務中。 然后,如果主應用程序崩潰或被殺死,則該服務仍在運行。 當我再次啟動應用程序時,連接仍然建立。 從藍牙輸入流讀取的字節通過標准服務消息傳遞到主應用程序中。 就我而言,這是可以的,因為我只傳輸少量數據。

當包含該服務的應用程序被殺死時,同樣會發生混亂。

我正面臨着同樣的問題。 這對我有用:

try {
    Thread.sleep(1000); 
}
catch(Exception e3)
{
    Toast.makeText(getApplicationContext(), "wa ni sud sa thread sleep!", Toast.LENGTH_SHORT).show();
}
btSocket.close();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM