Android Bluetooth sockets will fail to connect during discovery.

This commit is contained in:
akwizgran
2012-11-13 15:30:17 +00:00
parent 3355851e35
commit 18cd0c5f34
2 changed files with 23 additions and 15 deletions

View File

@@ -11,6 +11,7 @@ import static java.util.logging.Level.WARNING;
import java.io.IOException; import java.io.IOException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -247,20 +248,23 @@ class DroidtoothPlugin implements DuplexPlugin {
LOG.warning("Invalid address " + address); LOG.warning("Invalid address " + address);
return null; return null;
} }
BluetoothDevice d = adapter.getRemoteDevice(address);
// Validate the UUID // Validate the UUID
UUID u; UUID u;
try { try {
u = UUID.fromString(uuid); u = UUID.fromString(uuid);
} catch(IllegalArgumentException e) { } catch(IllegalArgumentException e) {
if(LOG.isLoggable(WARNING)) if(LOG.isLoggable(WARNING)) LOG.warning("Invalid UUID " + uuid);
LOG.warning("Invalid UUID " + uuid);
return null; return null;
} }
// Try to connect // Try to connect
BluetoothDevice d = adapter.getRemoteDevice(address);
try { try {
if(LOG.isLoggable(INFO))
LOG.info("Creating socket for " + address);
BluetoothSocket s = InsecureBluetooth.createSocket(d, u); BluetoothSocket s = InsecureBluetooth.createSocket(d, u);
if(LOG.isLoggable(INFO)) LOG.info("Connecting");
s.connect(); s.connect();
if(LOG.isLoggable(INFO)) LOG.info("Connected");
return new DroidtoothTransportConnection(s); return new DroidtoothTransportConnection(s);
} catch(IOException e) { } catch(IOException e) {
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
@@ -324,6 +328,7 @@ class DroidtoothPlugin implements DuplexPlugin {
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString()); if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
return null; return null;
} }
if(LOG.isLoggable(INFO)) LOG.info("Listening");
// Return the first connection received by the socket, if any // Return the first connection received by the socket, if any
try { try {
return new DroidtoothTransportConnection(ss.accept((int) timeout)); return new DroidtoothTransportConnection(ss.accept((int) timeout));
@@ -369,6 +374,7 @@ class DroidtoothPlugin implements DuplexPlugin {
private class DiscoveryReceiver extends BroadcastReceiver { private class DiscoveryReceiver extends BroadcastReceiver {
private final CountDownLatch finished = new CountDownLatch(1); private final CountDownLatch finished = new CountDownLatch(1);
private final Collection<String> addresses = new ArrayList<String>();
private final String uuid; private final String uuid;
private volatile DuplexTransportConnection connection = null; private volatile DuplexTransportConnection connection = null;
@@ -378,13 +384,22 @@ class DroidtoothPlugin implements DuplexPlugin {
} }
@Override @Override
public void onReceive(final Context ctx, Intent intent) { public void onReceive(Context ctx, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
if(action.equals(DISCOVERY_FINISHED)) { if(action.equals(DISCOVERY_FINISHED)) {
finish(ctx); if(LOG.isLoggable(INFO)) LOG.info("Discovery finished");
ctx.unregisterReceiver(this);
connectToDiscoveredDevices();
} else if(action.equals(FOUND)) { } else if(action.equals(FOUND)) {
BluetoothDevice d = intent.getParcelableExtra(EXTRA_DEVICE); BluetoothDevice d = intent.getParcelableExtra(EXTRA_DEVICE);
final String address = d.getAddress(); String address = d.getAddress();
if(LOG.isLoggable(INFO)) LOG.info("Discovered " + address);
addresses.add(address);
}
}
private void connectToDiscoveredDevices() {
for(final String address : addresses) {
pluginExecutor.execute(new Runnable() { pluginExecutor.execute(new Runnable() {
public void run() { public void run() {
synchronized(DroidtoothPlugin.this) { synchronized(DroidtoothPlugin.this) {
@@ -393,18 +408,13 @@ class DroidtoothPlugin implements DuplexPlugin {
DuplexTransportConnection conn = connect(address, uuid); DuplexTransportConnection conn = connect(address, uuid);
if(conn != null) { if(conn != null) {
connection = conn; connection = conn;
finish(ctx); finished.countDown();
} }
} }
}); });
} }
} }
private void finish(Context ctx) {
ctx.unregisterReceiver(this);
finished.countDown();
}
private DuplexTransportConnection waitForConnection(long timeout) private DuplexTransportConnection waitForConnection(long timeout)
throws InterruptedException { throws InterruptedException {
finished.await(timeout, MILLISECONDS); finished.await(timeout, MILLISECONDS);

View File

@@ -116,9 +116,7 @@ class InsecureBluetooth {
int errno = (Integer) result; int errno = (Integer) result;
if(errno != 0) { if(errno != 0) {
socket.close(); socket.close();
Method throwErrnoNative = mSocket.getClass().getMethod( throw new IOException("Can't bind: errno " + errno);
"throwErrnoNative", int.class);
throwErrnoNative.invoke(mSocket, errno);
} }
return socket; return socket;
} catch(NoSuchMethodException e) { } catch(NoSuchMethodException e) {