package com.hairysoft.bt; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.Context; import android.os.Handler; import com.hairysoft.util.Log; import android.widget.Toast; import com.hairysoft.cockcrow.R; import com.hairysoft.message.ClockMessage; import com.hairysoft.util.Constants; import org.json.JSONException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Queue; import java.util.UUID; /** * Thread class to handle the bluetooth communication. * This thread is only instantiated after successfully discovering the device. */ public class ConnectThread extends Thread { private final static String TAG = "ConnectThread"; private final static UUID MY_UUID_SECURE = UUID.fromString("62d1e4b0-848f-11e4-b4a9-0800200c9a66"); // Providing a static reference for the connection, as it is supposed to exist only one connection at a given time private static ConnectThread instance; private final Context c; private final Handler mHandler; private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; private boolean connected; private InputStream mmInStream; private OutputStream mmOutStream; /** * Returns the current connection instance * * @return ConnectThread Static reference for the current connection instance */ public static ConnectThread getInstance() { return ConnectThread.instance; } public static boolean isConnected() { return ConnectThread.instance != null && ConnectThread.instance.connected; } public ConnectThread(Context c, Handler handler, BluetoothDevice device) { this.c = c; mHandler = handler; mmDevice = device; BluetoothSocket tmpSocket = null; connected = false; try { // Starts a secure bluetooth connection with the device tmpSocket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE); } catch(IOException ex) { Log.e(TAG, "Failed to open socket to device", ex); } mmSocket = tmpSocket; ConnectThread.instance = this; } @Override public void run() { try { Log.d(TAG, "Connecting to Waky"); mmSocket.connect(); connected = true; // Notifies the UI thread of the connection state change mHandler.obtainMessage(Constants.BT_CONNECT_SUCCESS).sendToTarget(); connectedRoutine(); } catch(IOException ex) { Log.e(TAG, "Problem during connection", ex); try { mmSocket.close(); } catch(IOException ex2) { Log.e(TAG, "Problem closing socket during connect failure", ex2); } try { // To avoid eating up all the device's CPU when trying to perform multiple reconnects Thread.sleep(1000); } catch(InterruptedException ex2) { } // Notifies the UI thread of the connection state change mHandler.obtainMessage(Constants.BT_CONNECT_FAILED).sendToTarget(); } finally { connected = false; ConnectThread.instance = null; } } public void write(byte[] buffer) { try { mmOutStream.write(buffer); } catch(IOException ex) { Log.e(TAG, "Error while talking to waky", ex); connected = false; ConnectThread.instance = null; } } private void connectedRoutine() { InputStream tmpIn = null; OutputStream tmpOut = null; try { tmpIn = mmSocket.getInputStream(); tmpOut = mmSocket.getOutputStream(); } catch (IOException e) { Log.e(TAG, "Error creating sockets", e); } mmInStream = tmpIn; mmOutStream = tmpOut; try { Dispatcher.queueMessage(new ClockMessage().getJSON()); } catch(JSONException ex) { } mHandler.obtainMessage(Constants.UPDATE_ALARM).sendToTarget(); byte[] buffer = new byte[1024]; while(true) { try { // Currently not handling these messages as they're not needed/implemented mmInStream.read(buffer); Log.d(TAG, "Received [" + new String(buffer) + "]"); // TODO Send read message to main thread } catch(IOException ex) { Log.e(TAG, "Connection to waky was lost", ex); connected = false; ConnectThread.instance = null; // Notifies the UI thread of the connection state change mHandler.obtainMessage(Constants.BT_DISCONNECT).sendToTarget(); break; } } } }