[英]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.