簡體   English   中英

Android:在SPP藍牙設備之間切換

[英]Android: Switch between SPP Bluetooth Devices

我有兩個不同的藍牙打印機。 Bixolon SPP-R200和Fujitsu FTP-628WSL110。 我可以分別連接到每個(使用三星Galaxy SII)打印,斷開連接並重新連接就好了。 但是,如果我關閉Bixolon並嘗試與Fujitsu配對(之前未配對,Bixolon仍然配對),那么在嘗試連接到創建的套接字時它會失敗。 相反的方式。

這是錯誤消息:

07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): Failed to connect to rfcomm socket.
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): java.io.IOException: Service discovery failed
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380):  at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:406)
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380):  at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:217)
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380):  at MyApp.BluetoothConnection.connect(BluetoothConnection.java:171)
07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380):  at MyApp.AbstractBluetoothPrinter.connect(AbstractBluetoothPrinter.java:34)

這是代碼,它使連接嘗試,在解釋的情況下失敗的行是btSocket.connect(); - 例外見上文:

/** Is set in connect() */
private BluetoothSocket btSocket = null;
/** Is set prior to connect() */
private BluetoothSocket btDevice;

public boolean connect(){

        try {
            btSocket = btDevice.createRfcommSocketToServiceRecord("00001101-0000-1000-8000-00805F9B34FB");
            if (btDevice.getName().startsWith("FTP")) {
                //Special treatment for the fujitsu printer
                SystemClock.sleep(1000);
            }
        } catch (Throwable e) {
            LogCat.e(TAG, "Failed to create rfcomm socket.", e);
            return false;
        }

        try {
            // Stop Bluetooth discovery if it's going on
            BluetoothHandler.cancelDiscovery();
            // This fails under the described circumstances
            btSocket.connect();
        } catch (Throwable e) {
            LogCat.e(TAG, "Failed to connect to rfcomm socket.", e);
            return false;
        }

        // Obtain streams etc...
}

我使用相同的 UUID連接到兩個設備(但是一次只打開一個設備,它們從未同時打開),SDK API中眾所周知的SPP UUID:

00001101-0000-1000-8000-00805F9B34FB

這讓我想知道:可能是,我需要為每個設備使用不同的UUID嗎? 如果是的話有什么想法?

好幾天嘗試不同的解決方案后,我現在可以在上述打印機之間切換。 由於我不完全確定我的哪些措施是成功的原因,我將列出所有這些,所以有人絆倒這篇文章將有一些關於如何解決他的藍牙問題的線索。 但有一點我很確定:你不需要不同的UUID來連接兩台不同的打印機 - 你可以使用相同的UUID(但我只打開其中一台)。

我緩存上次打印的設備 - 但不像以前我不再緩存實際的BluetoothDevice ,而是我只緩存它的mac地址,可以通過以下方式獲得:

BluetoothDevice bluetoothDevice; 

//Obtain BluetoothDevice by looking through paired devices or starting discovery

bluetoothDevice.getAddress(); 

getAddress()返回一個String:設備的硬件地址。 我緩存該mac地址,下次用戶想要打印時,我將緩存的mac地址與所有配對打印機的mac地址相匹配 - 如果mac地址匹配其中一個,我嘗試連接到該打印機。 如果失敗,我重置我的緩存的mac地址,並嘗試通過首先檢查我的配對設備,如果其中一個可以連接(如果我可以成功連接,我相應地更新我的緩存的mac地址)找到另一個設備,如果失敗我開始尋找其他潛在設備的藍牙發現。

現在,為了不讓任何套接字連接打開我的一個打印機,我的例程如下(我將省略每次調用的try-catches以簡化讀取):

創建套接字

BluetoothSocket btSocket = btDevice.createRfcommSocketToServiceRecord(MY_UUID);

MY_UUID是指用於連接SPP設備的眾所周知的UUID:

00001101-0000-1000-8000-00805F9B34FB

如果套接字創建失敗(這很少見,如果它發生,很可能是由於權限不足或藍牙被禁用/不可用),我們無法繼續進行,因為我們需要一個套接字連接。 因此,在catch塊中,您應該觸發disconnect方法(稍后會詳細介紹)。

連接到創建的套接字

bSocket.connect();

如果連接失敗,我們無法繼續進行,因為我們需要有效的套接字連接來獲取輸入和輸出流。 因此,在catch塊中,您應該觸發disconnect方法(稍后會詳細介紹)。

獲取輸入和輸出流

下一步是從套接字獲取輸入和輸出流。 我在for循環中執行此操作,該循環運行幾次(5次應該足夠) - 在每次迭代中我檢查是否有輸出流,如果沒有,我嘗試獲取它,對於輸入流也是如此。 在循環結束時,我檢查我是否有兩個流,如果是,我退出循環(和整個連接方法),如果不是,我繼續循環再試一次。 通常我在第一次循環迭代中獲得兩個流,但有時我需要兩次或三次迭代才能獲得兩個流。

如果我在循環聲明后到達后面的代碼,我顯然沒有得到我的流或其他錯誤。 此時連接被認為已經失敗,我執行了我的斷開連接代碼(它清理了打開的流和套接字,稍后會詳細介紹)。

讀/寫

現在您已連接到目標藍牙設備,您可以執行讀寫操作。 一旦完成,您應該通過關閉所有流和套接字進行清理,在下一段中將詳細介紹:斷開連接。 切記:如果在讀/寫操作期間發生異常,請務必觸發disconnect方法以清理資源。 如果您的打印機需要某種初始化命令,請務必在連接到打印機之后和執行讀/寫操作之前立即發送。

斷開

通常有兩種情況應斷開:

  • 完成讀/寫操作后
  • 如果在此過程中發生異常,則清理資源

關閉你的溪流

你要做的第一件事是清理你的流,檢查它們,你的輸入和輸出流,如果它們不是null,關閉它們並將它們設置為null。 確保將每個操作(關閉輸入流,關閉輸出流等)包裝到它自己的try-catch中,否則無法進行一次清理(因為引發了異常)將跳過所有其他清理措施。

關閉插座

既然您已確保清理輸入流,請繼續關閉套接字連接並將其設置為null。

還有一件事:我在disconnect方法的開頭和結尾都有一個Thread.sleep。 開頭的那個長約2.5秒(= 2500毫秒),目的是確保打印機沒有其他任何東西(例如掛起的讀/寫操作或打印機仍在打印等)。 第二個Thread.sleep在我的disconnect方法的末尾,大約800毫秒長。 最后睡眠的原因與我在關閉后立即嘗試立即打開新套接字時遇到的問題有關。 有關詳細信息,請參閱此答案

有問題嗎?

如果有人對我的OP或我的答案有疑問,請在評論中告訴我,我會盡力回答。

暫無
暫無

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

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