I working with a project where I need to connect my tablet (android 4.2.2) to Bluetooth-to-UART converter (RN42 by microchip). I am using BluetoothChat example to manage bluetooth connection, but its difficult to connect. Sometimes program fails at method mmSocket.connect(); - it throws IOException. Sometimes i need three or more tries to connect to my remote device. After connection is made, it is very stable. I tried to change UUID, tried to change rn42 module (i also tried to use HC-05 module). I tried secure and insecure rfcomm connection, still no luck. here is my code: In the MainActivity:
@Override
public void onButtonPressed(View view, Device device){
switch (view.getId()){
case R.id.buttonRedaguotiIrengini:
// Edit button is pressed
Intent i = new Intent(this, DeviceActivity.class);
i.putExtra("device", device);
i.putExtra("requestCode", REQUEST_EDIT_DEVICE);
startActivityForResult(i, REQUEST_EDIT_DEVICE);
break;
case R.id.buttonPrisijungti:
if (mBtService.getState()==BluetoothService.STATE_CONNECTED){
mBtService.stop();
} else {
BluetoothDevice btDevice = mBluetoothAdapter.getRemoteDevice(device.getMac());
mBtService.connect(btDevice, false);
}
break;
}
}
in the BluetoothService Class:
// Name for the SDP record when creating server socket
private static final String NAME_SECURE = "BluetoothChatSecure";
private static final String NAME_INSECURE = "BluetoothChatInsecure";
// Unique UUID for this application
private static final UUID MY_UUID_SECURE =UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static final UUID MY_UUID_INSECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private AcceptThread mSecureAcceptThread;
private AcceptThread mInsecureAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
public synchronized void connect(BluetoothDevice device, boolean secure) {
if (D) Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device, secure);
mConnectThread.start();
setState(STATE_CONNECTING);
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private String mSocketType;
public ConnectThread(BluetoothDevice device, boolean secure) {
mmDevice = device;
BluetoothSocket tmp = null;
mSocketType = secure ? "Secure" : "Insecure";
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
if (secure) {
tmp = device.createRfcommSocketToServiceRecord(
MY_UUID_SECURE);
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(
MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
}
mmSocket = tmp;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
setName("ConnectThread" + mSocketType);
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
if (D) {Log.d(TAG, "will try to connect to socket");};
mmSocket.connect();
} catch (IOException e) {
// Close the socket
if (D) {Log.d(TAG, "failed to connect to socket");};
e.printStackTrace();
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() " + mSocketType +
" socket during connection failure", e2);
}
connectionFailed();
return;
}
if (D){Log.d(TAG, "Success");};
// Reset the ConnectThread because we're done
synchronized (BluetoothService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice, mSocketType);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);
}
}
}
private void connectionFailed() {
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(MainActivity.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(MainActivity.TOAST, "Unable to connect device");
msg.setData(bundle);
mHandler.sendMessage(msg);
if (D){Log.d(TAG, "Failed, unable to connect device");};
setState(STATE_NONE);
}
Here are the LogCat output
03-12 16:01:38.992: D/mBT(9947): connect to: 00:06:66:67:44:3E
03-12 16:01:38.992: I/BluetoothSocket_MTK(9947): [JSR82] Bluetooth Socket Constructor
03-12 16:01:38.992: I/BluetoothSocket_MTK(9947): [JSR82] type=1 fd=-1 auth=false encrypt=false port=-1
03-12 16:01:38.993: D/BTSocketService(452): [JSR82][Service] initSocket
03-12 16:01:38.993: I/BluetoothSocketService.cpp(452): [JSR82][JNI] initSocketNative +++.
03-12 16:01:38.993: I/BluetoothSocketService.cpp(452): [JSR82][JNI] initSocketNative: start to initialize socket.
03-12 16:01:38.993: I/BluetoothSocketService.cpp(452): [JSR82][JNI] type=1, auth=0, encrypt=0, port=-1
03-12 16:01:38.993: I/BluetoothSocketService.cpp(452): [JSR82][JNI] initSocketNative: Initialize socket done.
03-12 16:01:38.993: E/BluetoothSocketService.cpp(452): [JSR82] alloc context : index=2
03-12 16:01:38.993: E/BluetoothSocketService.cpp(452): [JSR82] Clear context : index=2, ctx.index=0, ctx.fd=0
03-12 16:01:38.993: I/BluetoothSocketService.cpp(452): [JSR82][JNI] jsr82ConnectCond (2) initialization success
03-12 16:01:38.993: I/BluetoothSocketService.cpp(452): [JSR82][JNI] jsr82ReadCond (2) initialization success <READ>
03-12 16:01:38.993: I/BluetoothSocketService.cpp(452): [JSR82][JNI] jsr82WriteCond (2) initialization success <WRITE>
03-12 16:01:38.993: I/BluetoothSocketService.cpp(452): [JSR82][JNI] jsr82RegisterCond (2) initialization success <REGISTER>
03-12 16:01:38.993: I/BluetoothSocketService.cpp(452): [JSR82][JNI] initSocketNative ---. fdHandle=32770
03-12 16:01:38.995: D/mBT(9947): setState() 1 -> 2
03-12 16:01:38.998: I/mBT(9947): BEGIN mConnectThread SocketType:Insecure
03-12 16:01:39.001: D/BluetoothService(452): [API] cancelDiscovery()
03-12 16:01:39.001: I/BluetoothService.cpp(452): [GAP][API] stopDiscoveryNative
03-12 16:01:39.001: I/BluetoothService.cpp(452): [GAP] btmtk_gap_discovery_cancel
03-12 16:01:39.001: I/BluetoothService.cpp(452): [GAP] btmtk_gap_discovery_cancel already cancelled
03-12 16:01:39.001: I/BluetoothService.cpp(452): [GAP] btmtk_gap_send_discovery_stop_event
03-12 16:01:39.001: I/BluetoothService.cpp(452): [JNI] bt_sendind(ptr=0x5C6AEA50, len=28)
03-12 16:01:39.001: I/BluetoothService.cpp(452): [JNI] send ind=3528
03-12 16:01:39.001: I/BluetoothEventLoop.cpp(452): [MSG] Polling returned
03-12 16:01:39.001: I/BluetoothEventLoop.cpp(452): [MSG] Start retrieve data
03-12 16:01:39.002: I/BluetoothEventLoop.cpp(452): [MSG] fd 1 data ready
03-12 16:01:39.002: I/BluetoothEventLoop.cpp(452): [MSG] nat->pollData[i].fd data ready : revents = 0x1
03-12 16:01:39.002: I/BluetoothEventLoop.cpp(452): [MSG] msg 3528 received : size=28
03-12 16:01:39.002: I/BluetoothEventLoop.cpp(452): [GAP] receive event=3528
03-12 16:01:39.002: I/BluetoothEventLoop.cpp(452): [GAP] btmtk_util_update_adapter_property_discovering: is_discovering = 0
03-12 16:01:39.002: D/BluetoothEventLoop(452): Property Changed: Discovering : false
03-12 16:01:39.006: I/BluetoothService.cpp(452): [JNI] send ind success : 28
03-12 16:01:39.007: I/BluetoothEventLoop.cpp(452): [MSG] Start polling
03-12 16:01:39.008: V/BluetoothEventManager(1562): Received android.bluetooth.adapter.action.DISCOVERY_FINISHED
03-12 16:01:39.011: D/mBT(9947): will try to connect to socket
03-12 16:01:39.011: I/BluetoothSocket_MTK(9947): [JSR82] connect: do SDP
03-12 16:01:39.012: D/BluetoothService(452): [API] fetchRemoteUuids(00:06:66:67:44:3E)
03-12 16:01:39.012: V/BluetoothAdapterProperties(452): getObjectPath():MTKBT/dev_
03-12 16:01:39.012: I/BluetoothService.cpp(452): [GAP][API] discoverServicesNative : addr=MTKBT/dev_00_06_66_67_44_3E, pattern=00001101-0000-1000-8000-00805f9b34fb
03-12 16:01:39.013: I/BluetoothService.cpp(452): [GAP] btmtk_gap_service_search_raw_request addr=67443E:66:6, size=19
03-12 16:01:39.013: D/[BT](142): mtk_bt_write: buffer bebcbcc8, len 5
03-12 16:01:39.013: I/BluetoothService.cpp(452): [GAP] btmtk_gap_send_sdp_discover_event
03-12 16:01:39.013: I/BluetoothService.cpp(452): [JNI] bt_sendind(ptr=0x54B921A0, len=60)
03-12 16:01:39.013: I/BluetoothService.cpp(452): [JNI] send ind=3535
03-12 16:01:39.013: I/BluetoothService.cpp(452): [JNI] send ind success : 60
03-12 16:01:39.013: I/BluetoothEventLoop.cpp(452): [MSG] Polling returned
03-12 16:01:39.013: I/BluetoothEventLoop.cpp(452): [MSG] Start retrieve data
03-12 16:01:39.013: I/BluetoothEventLoop.cpp(452): [MSG] fd 1 data ready
03-12 16:01:39.014: I/BluetoothEventLoop.cpp(452): [MSG] nat->pollData[i].fd data ready : revents = 0x1
03-12 16:01:39.014: I/BluetoothEventLoop.cpp(452): [MSG] msg 3535 received : size=60
03-12 16:01:39.014: I/BluetoothEventLoop.cpp(452): [GAP] receive event=3535
03-12 16:01:39.014: I/BluetoothEventLoop.cpp(452): [GAP] receive event ANDROID_EV_SDP_DEVICE_CREATE 0x67443E:0x66:0x6
03-12 16:01:39.014: I/BluetoothEventLoop.cpp(452): [GAP] pattern (16) 0: 0:11: 1
03-12 16:01:39.014: I/BluetoothEventLoop.cpp(452): [MSG] Start polling
03-12 16:01:39.015: V/BluetoothDiscoveryReceiver(1562): Received: android.bluetooth.adapter.action.DISCOVERY_FINISHED
03-12 16:01:39.018: D/[BT](142): mtk_bt_read: buffer 401c901c, len 1
03-12 16:01:39.018: D/[BT](142): mtk_bt_read: buffer 401c9024, len 2
03-12 16:01:39.018: D/[BT](142): mtk_bt_read: buffer 401980e6, len 4
03-12 16:01:39.018: D/[BT](142): mtk_bt_read: buffer 401c901c, len 1
03-12 16:01:39.019: D/[BT](142): mtk_bt_write: buffer bebcbcc8, len 5
03-12 16:01:39.026: D/[BT](142): mtk_bt_read: buffer 401c901c, len 1
03-12 16:01:39.026: D/[BT](142): mtk_bt_read: buffer 401c9024, len 2
03-12 16:01:39.026: D/[BT](142): mtk_bt_read: buffer 401981e7, len 4
03-12 16:01:39.026: D/[BT](142): mtk_bt_read: buffer 401c901c, len 1
03-12 16:01:39.026: D/[BT](142): mtk_bt_write: buffer bebcbcc8, len 17
03-12 16:01:39.032: D/[BT](142): mtk_bt_read: buffer 401c901c, len 1
03-12 16:01:39.032: D/[BT](142): mtk_bt_read: buffer 401c9024, len 2
03-12 16:01:39.032: D/[BT](142): mtk_bt_read: buffer 401982e8, len 4
03-12 16:01:39.033: D/[BT](142): mtk_bt_read: buffer 401c901c, len 1
03-12 16:01:40.017: D/[BT](142): mtk_bt_read: buffer 401c901c, len 1
03-12 16:01:40.017: D/[BT](142): mtk_bt_read: buffer 401c9024, len 2
03-12 16:01:40.017: D/[BT](142): mtk_bt_read: buffer 401983e9, len 4
03-12 16:01:40.017: D/[BT](142): mtk_bt_read: buffer 401c901c, len 1
03-12 16:01:44.775: D/Bluetooth HS/HF(692): [BT][HFG] [API] mStateReceiver.onReceive(android.intent.action.BATTERY_CHANGED)
03-12 16:01:44.776: D/Bluetooth HS/HF(692): [BT][HFG] [API] mHandler.handleMessage(9)
03-12 16:01:44.776: D/Bluetooth HS/HF(692): [BT][HFG] [API] updateBatteryState
03-12 16:01:45.014: D/BluetoothService(452): [API] getUuidFromCache(00:06:66:67:44:3E)
03-12 16:01:45.015: D/BluetoothService(452): [API] getUuidFromCache=00001101-0000-1000-8000-00805f9b34fb)
03-12 16:01:45.016: D/BluetoothService(452): [API] getUuidFromCache=00001101-0000-1000-8000-00805f9b34fb)
03-12 16:01:45.016: D/BluetoothService(452): [API] sendUuidIntent(00:06:66:67:44:3E)
03-12 16:01:45.020: D/Bluetooth HSHFP(692): [BT][HFG][Intent] action=android.bluetooth.device.action.UUID, state=0
03-12 16:01:45.022: D/BluetoothService(452): [API] makeServiceChannelCallbacks(00:06:66:67:44:3E)
03-12 16:01:45.022: D/BluetoothService(452): Cleaning up failed UUID channel lookup: 00:06:66:67:44:3E 00001101-0000-1000-8000-00805f9b34fb
03-12 16:01:45.022: I/BluetoothSocket_MTK(9947): [JSR82] SdpHelper::onRfcommChannelFound: channel=-1
03-12 16:01:45.023: D/mBT(9947): failed to connect to socket
03-12 16:01:45.023: W/System.err(9947): java.io.IOException: Service discovery failed
03-12 16:01:45.024: W/System.err(9947): at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:813)
03-12 16:01:45.024: W/System.err(9947): at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:382)
03-12 16:01:45.024: W/System.err(9947): at p.demoui.BluetoothService$ConnectThread.run(BluetoothService.java:389)
03-12 16:01:45.024: I/BluetoothSocket_MTK(9947): [JSR82] close
03-12 16:01:45.024: I/BluetoothSocket_MTK(9947): [JSR82] readLock got.
03-12 16:01:45.025: D/BTSocketService(452): [JSR82][Service] abort
03-12 16:01:45.025: I/BluetoothSocketService.cpp(452): [JSR82][JNI] abortNative +++. fd=32770.
03-12 16:01:45.025: I/BluetoothSocketService.cpp(452): [JSR82][JNI] abortNative ---.
03-12 16:01:45.025: I/BluetoothSocket_MTK(9947): [JSR82] Start to aquire writeLock.
03-12 16:01:45.026: I/BluetoothSocket_MTK(9947): [JSR82] writeLock got.
03-12 16:01:45.026: D/BTSocketService(452): [JSR82][Service] destroy
03-12 16:01:45.026: I/BluetoothSocketService.cpp(452): [JSR82][JNI] destroyNative: fd=32770.
03-12 16:01:45.026: E/BluetoothSocketService.cpp(452): [JSR82] Clear context : index=2, ctx.index=-1, ctx.fd=32770
03-12 16:01:45.030: D/mBT(9947): Failed, unable to connect device
03-12 16:01:45.030: D/mBT(9947): setState() 2 -> 0
Where is mistake? how can I improve this code? Why is the IOException is thrown in this case?
Thanks for your help.