簡體   English   中英

將Android設備連接到多個藍牙串行嵌入式對等設備

[英]Connecting Android device to multiple Bluetooth serial embedded peers

我正在嘗試為此設置找到解決方案:

我有一個Android設備,我想連接到多個串行嵌入式設備......

這就是使用“正常”方式檢索藍牙套接字的方法,並不適用於所有設備,雖然它可以,但我可以連接到多個設備,並從多個設備發送和接收數據。

public final synchronized void connect()
        throws ConnectionException {
    if (socket != null)
        throw new IllegalStateException("Error socket is not null!!");
    connecting = true;
    lastException = null;
    lastPacket = null;
    lastHeartBeatReceivedAt = 0;
    log.setLength(0);
    try {
        socket = fetchBT_Socket_Normal();
        connectToSocket(socket);
        listenForIncomingSPP_Packets();
        connecting = false;
        return;
    } catch (Exception e) {
        socket = null;
        logError(e);
    }
    try {
        socket = fetchBT_Socket_Workaround();
        connectToSocket(socket);
        listenForIncomingSPP_Packets();
        connecting = false;
        return;
    } catch (Exception e) {
        socket = null;
        logError(e);
    }
    connecting = false;
    if (socket == null)
        throw new ConnectionException("Error creating RFcomm socket for" + this);
}

private BluetoothSocket fetchBT_Socket_Normal()
        throws Exception {
    /* The getType() is a hex 0xXXXX value agreed between peers --- this is the key (in my case) to multiple connections in the "Normal" way */
    String uuid = getType() + "1101-0000-1000-8000-00805F9B34FB";

    try {
        logDebug("Fetching BT RFcomm Socket standard for UUID: " + uuid + "...");
        socket = btDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
        return socket;
    } catch (Exception e) {
        logError(e);
        throw e;
    }
}

private BluetoothSocket fetchBT_Socket_Workaround()
        throws Exception {
    Method m;
    int connectionIndex = 1;
    try {
        logDebug("Fetching BT RFcomm Socket workaround index " + connectionIndex + "...");
        m = btDevice.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
        socket = (BluetoothSocket) m.invoke(btDevice, connectionIndex);
        return socket;
    } catch (Exception e1) {
        logError(e1);
        throw e1;
    }
}

private void connectToSocket(BluetoothSocket socket)
        throws ConnectionException {
    try {
        socket.connect();
    } catch (IOException e) {
        try {
            socket.close();
        } catch (IOException e1) {
            logError("Error while closing socket", e1);
        } finally {
            socket = null;
        }
        throw new ConnectionException("Error connecting to socket with" + this, e);
    }
}

這就是事情,而在“正常”方式不起作用的手機上,“解決方法”方式為單個連接提供了解決方案。 我已經搜查 ,但拉鏈上來。

在最后一個鏈接中提到了變通方法的問題,兩個連接使用相同的端口,在我的情況下,導致一個塊,其中兩個嵌入式設備實際上都可以發送數據,而這些數據尚未在Android上處理,而兩者都是嵌入式設備可以接收從Android發送的數據。

以前有人處理過嗎?

有更多的參考這里

更新:

下面這個 (我在前面貼)我想給M端口一個機會,也許看其他端口索引,以及其他設備如何管理他們,我發現在的BluetoothSocket對象的領域是不同的,而這是相同的兩種情況下的FQN類:

來自HTC Vivid 2.3.4的Detils使用“解決方法”Technic:

Socket類的類型是:[ android.bluetooth.BluetoothSocket ]

mSocket BluetoothSocket  (id=830008629928)  
    EADDRINUSE          98  
    EBADFD              77  
    MAX_RFCOMM_CHANNEL  30  
    TAG                 "BluetoothSocket" (id=830002722432) 
    TYPE_L2CAP          3   
    TYPE_RFCOMM         1   
    TYPE_SCO            2   
    mAddress            "64:9C:8E:DC:56:9A" (id=830008516328)   
    mAuth               true    
    mClosed             false   
    mClosing            AtomicBoolean  (id=830007851600)    
    mDevice             BluetoothDevice  (id=830007854256)  
    mEncrypt            true    
    mInputStream        BluetoothInputStream  (id=830008688856) 
    mLock               ReentrantReadWriteLock  (id=830008629992)   
    mOutputStream       BluetoothOutputStream  (id=830008430536)    
    **mPort             1** 
    mSdp                null    
    mSocketData         3923880 
    mType               1   

來自LG-P925 2.2.2的Detils使用“普通”技術:

Socket類的類型是:[ android.bluetooth.BluetoothSocket ]

mSocket BluetoothSocket  (id=830105532880)  
    EADDRINUSE          98  
    EBADFD              77  
    MAX_RFCOMM_CHANNEL  30  
    TAG                 "BluetoothSocket" (id=830002668088) 
    TYPE_L2CAP          3   
    TYPE_RFCOMM         1   
    TYPE_SCO            2   
    mAccepted           false   
    mAddress            "64:9C:8E:B9:3F:77" (id=830105544600)   
    mAuth               true    
    mClosed             false   
    mConnected          ConditionVariable  (id=830105533144)    
    mDevice             BluetoothDevice  (id=830105349488)  
    mEncrypt            true    
    mInputStream        BluetoothInputStream  (id=830105532952) 
    mLock               ReentrantReadWriteLock  (id=830105532984)   
    mOutputStream       BluetoothOutputStream  (id=830105532968)    
    mPortName           "" (id=830002606256)    
    mSocketData         0   
    mSppPort            BluetoothSppPort  (id=830105533160) 
    mType               1   
    mUuid               ParcelUuid  (id=830105714176)   

任何人都有一些見解......

哇,每次這個讓我失望一個大型的WTF?

這是一個競爭條件問題,它明顯適用於一個版本的android,而不是另一個版本。 在Android對等體上,我正在解析從套接字接收的數據包:

public class SocketListener
        implements Runnable {

    private boolean stop;

    private OnIncomingPacketListener packetListener;

    @Override
    public void run() {
        InputStream inputStream;
        try {
            stop = false;
            inputStream = socket.getInputStream();
            while (!stop) {
                Packet packet = Packet.getPacket(inputStream);
                lastPacket = packet;
                if (packet.getDescriptor() == Packet.HeartBeat)
                    lastHeartBeatReceivedAt = System.currentTimeMillis();
                else if (packet.getDescriptor() == Packet.LogEntry)
                    log.append(((LogEntryPacket) packet).getLogEntry());
                synchronized (this) {
                    if (packetListener != null)
                        packetListener.onIncomingData(EmbeddedDevice.this, packet);
                }
            }
        } catch (IOException e) {
            logError("----- BLUETOOTH IO ERROR -----\n @: " + EmbeddedDevice.this, e);

            return;
        } catch (RuntimeException e) {
            logError("----- BLUETOOTH LISTENER ERROR -----\n @: " + EmbeddedDevice.this, e);
            throw e;
        } finally {
            socketListeningThread = null;
        }
    }
}

Packet.getPacket(inputStream)的位置是:

public static synchronized Packet getPacketInstance(InputStream inputStream)
        throws IOException {
    int data = inputStream.read();
    Packet type = null;
    for (Packet packetType : values())
        if (packetType.packetType == data) {
            type = packetType;
            break;
        } // race condition here...
    if (type == null)
        throw new IllegalArgumentException("Unknown packet type: " + data);
    try {
        Packet packet = type.incomingPacketType.newInstance();
        packet.setDescriptor(type);
        packet.readPacketData(inputStream);
        return packet;
    } catch (IOException e) {
        throw e;
    } catch (Exception e) {
        throw new IllegalStateException("Error instantiating type: " + type.incomingPacketType.getName(), e);
    }

}

每次數據包完成時,下一個線程都應該進行解析。

我的猜測是端口上存在某種鎖定,與我的實現一起導致第二個線程無限期地阻塞,一旦我將每個線程的解析移除到不同的實例,問題就解散了。

這種見解的靈感來自mPort鏈接中的Daniel Knoppel

謝謝Daniel!

暫無
暫無

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

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