[英]Pairing two Android devices to a third device using Bluetooth
I am doing an Android application where I need 2 devices or more to be able to connect to one device via Bluetooth. 我正在做一个Android应用程序,我需要2台或更多设备才能通过蓝牙连接到一台设备。 The code to connect two devices together in a peer-to-peer form works, but when I try to connect another I get an IOException saying "Connection refused" because the Socket is closed and as such, is unable to complete pairing.
以对等形式将两个设备连接在一起的代码有效,但是当我尝试连接另一个时,我得到一个IOException,说“连接被拒绝”,因为Socket已关闭,因此无法完成配对。 The error is shown below.
错误如下所示。
Socket closed. Unable to complete pairing.
java.io.IOException: Connection refused
at android.bluetooth.BluetoothSocket.connectNative(Native Method)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:216)
at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:270)
at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Could not connect to this device
I've then read that it needs to have a different UUID for each connection, is that right? 我已经读过它需要为每个连接提供不同的UUID,是吗? Anyway, I've written my code as shown below, taking a different UUID from an array for each new connection.
无论如何,我已经编写了如下所示的代码,为每个新连接从数组中获取不同的UUID。
// Unique UUID for this application
private static int indexUUID = 0;
private static final UUID[] MY_UUID_SECURE = {UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d168"),
UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d169"),
UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d170"),
UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d171"),
UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d172")};
private static final String NAME_SECURE = "GridFrameworkSecure";
/**
* Method to connect securely to Bluetooth device using it's MAC address
* @param macAddress valid Bluetooth MAC address
*/
public boolean connectSecurelyToDevice(BluetoothAdapter btAdapter, String macAddress){
BluetoothDevice device = btAdapter.getRemoteDevice(macAddress);
ConnectAsyncTask connectTask = new ConnectAsyncTask();
BluetoothSocket deviceSocket = null;
try {
deviceSocket = connectTask.execute(device).get();
} catch (InterruptedException e) {
e.printStackTrace();
return false;
} catch (ExecutionException e) {
e.printStackTrace();
return false;
}
if(deviceSocket!=null){
if(serverBluetoothNode==null){
try {
serverBluetoothNode = new BluetoothNode(deviceSocket);
Log.i("bluetooth manager", "You are now a slave node.");
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
} else {
Log.e("bluetooth manager", "You already have a master.");
return false;
}
} else return false;
}
/**
* Method to allow this Bluetooth device to accept connection from another Bluetooth device
*/
public void allowSecureConnectionFromRemoteDevice(BluetoothAdapter btAdapter){
AcceptConnectionAsyncTask acceptTask = new AcceptConnectionAsyncTask();
acceptTask.execute(btAdapter);
}
private class ConnectAsyncTask extends AsyncTask<BluetoothDevice, Void, BluetoothSocket> {
@Override
protected BluetoothSocket doInBackground(BluetoothDevice... params) {
BluetoothDevice device = params[0];
BluetoothSocket socket = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
socket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE[indexUUID]);
} catch (IOException e) {
Log.e("Bluetooth Pairing", "create() failed", e);
}
Log.i("Bluetooth Pairing", "BEGIN ConnectThread SocketType: Secure");
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket.connect();
Log.i("bluetooth manager", "You have connected a slave node to this one.");
return socket;
} catch (IOException e) {
Log.e("Bluetooth Pairing", "Socket closed. Unable to complete pairing.", e);
// Close the socket
try {
socket.close();
indexUUID++;
} catch (IOException e2) {
Log.e("Bluetooth Pairing", "unable to close() socket during connection failure", e2);
}
}
return null;
}
}
private class AcceptConnectionAsyncTask extends AsyncTask<BluetoothAdapter, Void, Void> {
@Override
protected Void doInBackground(BluetoothAdapter... params) {
BluetoothServerSocket serverSocket = null;
String socketType = "Secure";
// Create a new listening server socket
try {
serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]);
} catch (IOException e) {
Log.e("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType + "listen() failed", e);
indexUUID++;
}
Log.d("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType +
"BEGIN mAcceptThread" + this);
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (true) { //mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = serverSocket.accept();
Log.i("Slave", "server socket found");
// If a connection was accepted
if (socket != null) {
BluetoothNode node = null;
try {
node = new BluetoothNode(socket);
Log.i("connected to", node.getDeviceInformation());
slaveBluetoothNodes.add(node);
indexUUID++;
serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]);
} catch (IOException e) {
e.printStackTrace();
indexUUID++;
serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]);
}
}
} catch (IOException e) {
Log.e("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType + "accept() failed", e);
try {
indexUUID++;
serverSocket = params[0].listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[indexUUID]);
} catch (IOException e1) {
Log.e("Accept Bluetooth Pairing Thread", "Socket Type: " + socketType + "listen() failed", e1);
}
}
}
}
}
But even so, I get a different error on the third mobile which I'm trying to connect to one that has already a working Bluetooth connection to a second device, as shown below. 但即便如此,我在第三个移动设备上遇到了一个不同的错误,我正在尝试连接到已经与第二个设备建立蓝牙连接的移动设备,如下所示。
Socket closed. Unable to complete pairing.
java.io.IOException: Service discovery failed
at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:406)
at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:217)
at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:270)
at com.ablueworld.androidgridcomputingframework.BluetoothManager$ConnectAsyncTask.doInBackground(BluetoothManager.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)
Could not connect to this device
Can anybody help figure this out? 任何人都能帮到解决这个问题吗? Thank you.
谢谢。
try calling cancelDiscovery()
on your BluetoothAdapter
before creating the socket connection. 尝试在创建套接字连接之前在
BluetoothAdapter
上调用cancelDiscovery()
。 This might solve your problem on the java.io.IOException: Service discovery failed
that you are getting. 这可能会解决您在
java.io.IOException: Service discovery failed
上的问题java.io.IOException: Service discovery failed
您获得的java.io.IOException: Service discovery failed
。
I've figured out the solution to my problem. 我已经找到了解决问题的方法。
In the method to listen then make the connection, I've written it this way: 在侦听的方法然后建立连接,我这样写:
UUID[] MY_UUID_SECURE = {UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d168"),
UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d169"),
UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d170"),
UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d171"),
UUID.fromString("98b97e6b-62ff-4a36-a81b-82256fd1d172")};
BluetoothServerSocket serverSocket = null;
BluetoothSocket socket = null;
try {
// Listen for all UUIDs in array
for (int i = 0; i < MY_UUID_SECURE.length; i++) {
serverSocket = btAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE[i]);
socket = serverSocket.accept();
if (socket != null) {
BluetoothNode node = null;
node = new BluetoothNode(socket);
Log.i("connected to", node.getDeviceInformation());
slaveBluetoothNodes.add(node);
// add node to database
databaseManager.insertToGridTree(node.getDeviceAddress(), "slave", "active", node.getDeviceName());
}
}
} catch (IOException e) {
Log.e("Accept Bluetooth Pairing Thread", "accept() failed", e);
}
And the method for the slave devices to connect to the master: 以及从设备连接到主设备的方法:
BluetoothDevice device = params[0];
BluetoothSocket socket = null;
Log.i("Bluetooth Pairing", "BEGIN ConnectThread SocketType: Secure");
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
for(int i=0; i<MY_UUID_SECURE.length; i++){
try {
socket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE[i]);
// This is a blocking call and will only return on a
// successful connection or an exception
socket.connect();
Log.i("bluetooth manager", "You have connected a slave node to this one.");
return socket;
} catch (IOException e) {
Log.e("Bluetooth Pairing", "create() failed", e);
Log.i("Bluetooth Pairing", "trying another UUID");
try {
socket.close();
} catch (IOException e2) {
Log.e("Bluetooth Pairing", "unable to close() socket during connection failure", e2);
}
}
}
This project helped me figure this out: https://github.com/polyclef/BluetoothChatMulti 这个项目帮我解决了这个问题: https : //github.com/polyclef/BluetoothChatMulti
Hope this helps anyone having the same issue. 希望这有助于任何人遇到同样的问题。 :)
:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.