Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <pre><code>package com.switching.bluetooth; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.UUID; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import com.switching.ServerMainActivity; /** * This class does all the work for setting up and managing Bluetooth * connections with other devices. It has a thread that listens for incoming * connections, a thread for connecting with a device, and a thread for * performing data transmissions when connected. */ public class BluetoothService { // Debugging private static final String TAG = "BluetoothService iBT"; private static final boolean D = true; // Name for the SDP record when creating server socket private static final String NAME = "i BT"; // Unique UUID for this application private static UUID MY_UUID; // Member fields private final BluetoothAdapter mAdapter; private final Handler mHandler; private AcceptThread mAcceptThread; private ConnectThread mConnectThread; private ConnectedThread mConnectedThread; private int mState; private ArrayList&lt;String&gt; mDeviceAddresses; private ArrayList&lt;String&gt; mDeviceNames; private ArrayList&lt;ConnectedThread&gt; mConnThreads; private ArrayList&lt;BluetoothSocket&gt; mSockets; /** * A bluetooth piconet can support up to 7 connections. This array holds 7 * unique UUIDs. When attempting to make a connection, the UUID on the * client must match one that the server is listening for. When accepting * incoming connections server listens for all 7 UUIDs. When trying to form * an outgoing connection, the client tries each UUID one at a time. */ private ArrayList&lt;UUID&gt; mUuids; // 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 /** * Constructor. Prepares a new BluetoothChat session. * * @param context * The UI Activity Context * @param handler * A Handler to send messages back to the UI Activity */ public BluetoothService(Context context, Handler handler) { mAdapter = BluetoothAdapter.getDefaultAdapter(); mState = STATE_NONE; mHandler = handler; initializeArrayLists(); // 7 randomly-generated UUIDs. These must match on both server and // client. // mUuids.add(UUID.fromString("b7746a40-c758-4868-aa19-7ac6b3475dfc")); // mUuids.add(UUID.fromString("2d64189d-5a2c-4511-a074-77f199fd0834")); // mUuids.add(UUID.fromString("e442e09a-51f3-4a7b-91cb-f638491d1412")); // mUuids.add(UUID.fromString("a81d6504-4536-49ee-a475-7d96d09439e4")); // mUuids.add(UUID.fromString("aa91eab1-d8ad-448e-abdb-95ebba4a9b55")); // mUuids.add(UUID.fromString("4d34da73-d0a4-4f40-ac38-917e0a9dee97")); // mUuids.add(UUID.fromString("5e14d4df-9c8a-4db7-81e4-c937564c86e0")); } public static UUID getMY_UUID() { return MY_UUID; } public static void setMY_UUID(UUID mY_UUID) { MY_UUID = mY_UUID; } public boolean isDeviceConnectedAtPosition(int position) { if (mConnThreads.get(position) == null) { return false; } return true; } private void initializeArrayLists() { mDeviceAddresses = new ArrayList&lt;String&gt;(5); mDeviceNames = new ArrayList&lt;String&gt;(5); mConnThreads = new ArrayList&lt;ConnectedThread&gt;(5); mSockets = new ArrayList&lt;BluetoothSocket&gt;(5); mUuids = new ArrayList&lt;UUID&gt;(5); for (int i = 0; i &lt; 5; i++) { mDeviceAddresses.add(null); mDeviceNames.add(null); mConnThreads.add(null); mSockets.add(null); mUuids.add(null); } Log.i(TAG, "mConnThreads.size() in Service Constructor--" + mConnThreads.size()); } public ArrayList&lt;String&gt; getmDeviceNames() { return this.mDeviceNames; } public void setmDeviceNames(ArrayList&lt;String&gt; mDeviceNames) { this.mDeviceNames = mDeviceNames; } public ArrayList&lt;String&gt; getmDeviceAddresses() { return mDeviceAddresses; } public void setmDeviceAddresses(ArrayList&lt;String&gt; mDeviceAddresses) { this.mDeviceAddresses = mDeviceAddresses; } /** * Set the current state of the chat connection * * @param state * An integer defining the current connection state */ private synchronized void setState(int state) { if (D) Log.d(TAG, "setState() " + mState + " -&gt; " + state); mState = state; // Give the new state to the Handler so the UI Activity can update mHandler.obtainMessage(ServerMainActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget(); } /** * Return the current connection state. */ public synchronized int getState() { return mState; } /** * Start the chat service. Specifically start AcceptThread to begin a * session in listening (server) mode. Called by the Activity onResume() */ public synchronized void start() { if (D) Log.d(TAG, "start"); // Cancel any thread attempting to make a connection 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 listen on a BluetoothServerSocket if (mAcceptThread == null) { mAcceptThread = new AcceptThread(); mAcceptThread.start(); } setState(STATE_LISTEN); } /** * Start the ConnectThread to initiate a connection to a remote device. * * @param device * The BluetoothDevice to connect */ public synchronized void connect(BluetoothDevice device, int selectedPosition) { if (getPositionIndexOfDevice(device) == -1) { 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 (mConnThreads.get(selectedPosition) != null) { mConnThreads.get(selectedPosition).cancel(); // mConnectedThread = null; mConnThreads.set(selectedPosition, null); } // Create a new thread and attempt to connect to each UUID // one-by-one. try { // String // s="00001101-0000-1000-8000"+device.getAddress().split(":"); ConnectThread mConnectThread = new ConnectThread(device, UUID.fromString("00001101-0000-1000-8000-" + device.getAddress().replace(":", "")), selectedPosition); Log.i(TAG, "uuid-string at server side" + ("00001101-0000-1000-8000" + device.getAddress() .replace(":", ""))); mConnectThread.start(); setState(STATE_CONNECTING); } catch (Exception e) { } } else { Message msg = mHandler .obtainMessage(ServerMainActivity.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(ServerMainActivity.TOAST, "This device " + device.getName() + " Already Connected"); msg.setData(bundle); mHandler.sendMessage(msg); } } /** * Start the ConnectedThread to begin managing a Bluetooth connection * * @param socket * The BluetoothSocket on which the connection was made * @param device * The BluetoothDevice that has been connected */ public synchronized void connected(BluetoothSocket socket, BluetoothDevice device, int selectedPosition) { if (D) Log.d(TAG, "connected"); /* * // Cancel the thread that completed the connection if (mConnectThread * != null) { mConnectThread.cancel(); mConnectThread = null; } * * // Cancel any thread currently running a connection if * (mConnectedThread != null) { mConnectedThread.cancel(); * mConnectedThread = null; } * * // Cancel the accept thread because we only want to connect to one // * device if (mAcceptThread != null) { mAcceptThread.cancel(); * mAcceptThread = null; } */ // Start the thread to manage the connection and perform transmissions ConnectedThread mConnectedThread = new ConnectedThread(socket); mConnectedThread.start(); // Add each connected thread to an array mConnThreads.set(selectedPosition, mConnectedThread); // Send the name of the connected device back to the UI Activity Message msg = mHandler .obtainMessage(ServerMainActivity.MESSAGE_DEVICE_NAME); Bundle bundle = new Bundle(); bundle.putString(ServerMainActivity.DEVICE_NAME, device.getName()); msg.setData(bundle); mHandler.sendMessage(msg); setState(STATE_CONNECTED); } /** * Stop all threads */ public synchronized void stop() { if (D) Log.d(TAG, "stop"); if (mConnectThread != null) { mConnectThread.cancel(); mConnectThread = null; } if (mConnectedThread != null) { mConnectedThread.cancel(); mConnectedThread = null; } if (mAcceptThread != null) { mAcceptThread.cancel(); mAcceptThread = null; } for (int i = 0; i &lt; 5; i++) { mDeviceNames.set(i, null); mDeviceAddresses.set(i, null); mSockets.set(i, null); if (mConnThreads.get(i) != null) { mConnThreads.get(i).cancel(); mConnThreads.set(i, null); } } setState(STATE_NONE); } /** * Write to the ConnectedThread in an unsynchronized manner * * @param out * The bytes to write * @see ConnectedThread#write(byte[]) */ public void write(byte[] out) { // When writing, try to write out to all connected threads for (int i = 0; i &lt; mConnThreads.size(); i++) { try { // Create temporary object ConnectedThread r; // Synchronize a copy of the ConnectedThread synchronized (this) { if (mState != STATE_CONNECTED) return; r = mConnThreads.get(i); } // Perform the write unsynchronized r.write(out); } catch (Exception e) { } } } /** * Indicate that the connection attempt failed and notify the UI Activity. */ private void connectionFailed() { setState(STATE_LISTEN); // Send a failure message back to the Activity Message msg = mHandler.obtainMessage(ServerMainActivity.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(ServerMainActivity.TOAST, "Unable to connect device"); msg.setData(bundle); mHandler.sendMessage(msg); } /** * Indicate that the connection was lost and notify the UI Activity. */ private void connectionLost(BluetoothDevice device) { // setState(STATE_LISTEN); int positionIndex = getPositionIndexOfDevice(device); if (positionIndex != -1) { Log.i(TAG, "getPositionIndexOfDevice(device) ===" + mDeviceAddresses.get(getPositionIndexOfDevice(device))); mDeviceAddresses.set(positionIndex, null); mDeviceNames.set(positionIndex, null); mConnThreads.set(positionIndex, null); Message msg = mHandler .obtainMessage(ServerMainActivity.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(ServerMainActivity.TOAST, "Device connection was lost from " + device.getName()); msg.setData(bundle); mHandler.sendMessage(msg); } // Send a failure message back to the Activity } private class AcceptThread extends Thread { // The local server socket private final BluetoothServerSocket mmServerSocket; public AcceptThread() { BluetoothServerSocket tmp = null; // Create a new listening server socket try { if (mAdapter.isEnabled()) { BluetoothService.setMY_UUID(UUID .fromString("00001101-0000-1000-8000-" + mAdapter.getAddress().replace(":", ""))); } Log.i(TAG, "MY_UUID.toString()==" + BluetoothService.getMY_UUID().toString()); tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, BluetoothService.getMY_UUID()); } catch (IOException e) { Log.e(TAG, "listen() failed", e); } mmServerSocket = tmp; } public void run() { if (D) Log.d(TAG, "BEGIN mAcceptThread" + this); setName("AcceptThread"); BluetoothSocket socket = null; Log.i(TAG, "mState in acceptThread==" + mState); // Listen to the server socket if we're not connected while (mState != STATE_CONNECTED) { try { // This is a blocking call and will only return on a // successful connection or an exception socket = mmServerSocket.accept(); } catch (IOException e) { Log.e(TAG, "accept() failed", e); break; } // If a connection was accepted if (socket != null) { synchronized (BluetoothService.this) { switch (mState) { case STATE_LISTEN: case STATE_CONNECTING: // Situation normal. Start the connected thread. connected(socket, socket.getRemoteDevice(),getAvailablePositionIndexForNewConnection(socket.getRemoteDevice())); break; case STATE_NONE: case STATE_CONNECTED: // Either not ready or already connected. Terminate // new socket. try { socket.close(); } catch (IOException e) { Log.e(TAG, "Could not close unwanted socket", e); } break; } } } } if (D) Log.i(TAG, "END mAcceptThread"); } public void cancel() { if (D) Log.d(TAG, "cancel " + this); try { mmServerSocket.close(); } catch (IOException e) { Log.e(TAG, "close() of server failed", e); } } } /** * This thread runs while listening for incoming connections. It behaves * like a server-side client. It runs until a connection is accepted (or * until cancelled). */ // private class AcceptThread extends Thread { // BluetoothServerSocket serverSocket = null; // // public AcceptThread() { // } // // public void run() { // if (D) // Log.d(TAG, "BEGIN mAcceptThread" + this); // setName("AcceptThread"); // BluetoothSocket socket = null; // try { // // Listen for all 7 UUIDs // serverSocket = mAdapter.listenUsingRfcommWithServiceRecord( // NAME, MY_UUID); // socket = serverSocket.accept(); // if (socket != null) { // String address = socket.getRemoteDevice().getAddress(); // mSockets.add(socket); // mDeviceAddresses.add(address); // mDeviceNames.add(socket.getRemoteDevice().getName()); // // connected(socket, socket.getRemoteDevice()); // } // } catch (IOException e) { // Log.e(TAG, "accept() failed", e); // } // if (D) // Log.i(TAG, "END mAcceptThread"); // } // // public void cancel() { // if (D) // Log.d(TAG, "cancel " + this); // try { // serverSocket.close(); // } catch (IOException e) { // Log.e(TAG, "close() of server failed", e); // } // } // } /** * This thread runs while attempting to make an outgoing connection with a * device. It runs straight through; the connection either succeeds or * fails. */ private class ConnectThread extends Thread { private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; private UUID tempUuid; private int selectedPosition; public ConnectThread(BluetoothDevice device, UUID uuidToTry, int selectedPosition) { mmDevice = device; BluetoothSocket tmp = null; tempUuid = uuidToTry; this.selectedPosition = selectedPosition; // Get a BluetoothSocket for a connection with the // given BluetoothDevice try { tmp = device.createRfcommSocketToServiceRecord(uuidToTry); } catch (IOException e) { Log.e(TAG, "create() failed", e); } mmSocket = tmp; } public void run() { Log.i(TAG, "BEGIN mConnectThread"); setName("ConnectThread"); // 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 mmSocket.connect(); } catch (IOException e) { // if // (tempUuid.toString().contentEquals(mUuids.get(6).toString())) // { connectionFailed(); // } // Close the socket try { mmSocket.close(); } catch (IOException e2) { Log.e(TAG, "unable to close() socket during connection failure", e2); } // Start the service over to restart listening mode BluetoothService.this.start(); return; } // Reset the ConnectThread because we're done synchronized (BluetoothService.this) { mConnectThread = null; } mDeviceAddresses.set(selectedPosition, mmDevice.getAddress()); mDeviceNames.set(selectedPosition, mmDevice.getName()); // Start the connected thread connected(mmSocket, mmDevice, selectedPosition); } public void cancel() { try { mmSocket.close(); } catch (IOException e) { Log.e(TAG, "close() of connect socket failed", e); } } } /** * This thread runs during a connection with a remote device. It handles all * incoming and outgoing transmissions. */ private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) { Log.d(TAG, "create ConnectedThread"); mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the BluetoothSocket input and output streams try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (IOException e) { Log.e(TAG, "temp sockets not created", e); } mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { Log.i(TAG, "BEGIN mConnectedThread"); byte[] buffer = new byte[1024]; int bytes; // Keep listening to the InputStream while connected while (true) { try { // Read from the InputStream bytes = mmInStream.read(buffer); // Send the obtained bytes to the UI Activity mHandler.obtainMessage( ServerMainActivity.MESSAGE_READ, bytes, getPositionIndexOfDevice(mmSocket.getRemoteDevice()), buffer).sendToTarget(); Log.i("**********read", "read Called........"); } catch (IOException e) { Log.e(TAG, "disconnected", e); connectionLost(mmSocket.getRemoteDevice()); break; } } } /** * Write to the connected OutStream. * * @param buffer * The bytes to write */ public void write(byte[] buffer) { try { mmOutStream.write(buffer); // Share the sent message back to the UI Activity mHandler.obtainMessage(ServerMainActivity.MESSAGE_WRITE, -1, -1, buffer).sendToTarget(); } catch (IOException e) { Log.e(TAG, "Exception during write", e); } } public void cancel() { try { mmSocket.close(); } catch (IOException e) { Log.e(TAG, "close() of connect socket failed", e); } } } public int getPositionIndexOfDevice(BluetoothDevice device) { for (int i = 0; i &lt; mDeviceAddresses.size(); i++) { if (mDeviceAddresses.get(i) != null &amp;&amp; mDeviceAddresses.get(i).equalsIgnoreCase( device.getAddress())) return i; } return -1; } public int getAvailablePositionIndexForNewConnection(BluetoothDevice device) { if (getPositionIndexOfDevice(device) == -1) { for (int i = 0; i &lt; mDeviceAddresses.size(); i++) { if (mDeviceAddresses.get(i) == null) { return i; } } } return -1; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload