<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
public interface BluetoothListener { void bluetoothMessage(final String message); void bluetoothError(final String error); void bluetoothConnectionSate(final boolean connected); }
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Set; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; public class BluetoothClient implements Runnable { private final static String TAG = BluetoothClient.class .getSimpleName(); /* Messages echangés via le handler */ private static final int READY_TO_CONN = 0; private static final int CANCEL_CONN = 1; private static final int MESSAGE_READ = 2; private static final java.util.UUID UUID = java.util.UUID .fromString("05f2934c-1e81-4554-bb08-44aa761afbfb"); /* Ici je ne gère qu'un device de connecté */ private String deviceAddr = null; private boolean mCancel = false; private Handler mHandler = null; private BluetoothAdapter mAdapter = null; private InputStream mInStream = null; private OutputStream mOutStream = null; private BluetoothSocket mSocket = null; public BluetoothClient(final BluetoothListener listener) { mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(final Message msg) { switch (msg.what) { case READY_TO_CONN: /* Etat de la connection */ listener.bluetoothConnectionSate(true); break; case CANCEL_CONN: /* Etat de la connection */ listener.bluetoothConnectionSate(false); break; case MESSAGE_READ: /* reception d'un message */ final String readMessage = new String((byte[]) msg.obj, 0, msg.arg1); listener.bluetoothMessage(readMessage); break; default: break; } } }; mAdapter = BluetoothAdapter.getDefaultAdapter(); if (mAdapter == null) listener.bluetoothError("Bluetooth non supporté"); else if (!mAdapter.isEnabled()) { listener.bluetoothError("Bluetooth non activé"); } else { /* ok on commence */ final Set<BluetoothDevice> pairedDevices = mAdapter.getBondedDevices(); // If there are paired devices if (pairedDevices.size() > 0) { final BluetoothDevice device = pairedDevices.iterator().next(); /* Stock l'adresse pour créer le device bluetooth */ deviceAddr = device.getAddress(); mCancel = false; /* * démarre le thread pour la connection et la lecture de nouveaux * messages */ final Thread t = new Thread(this); t.start(); } else { Log.i(TAG, "startDiscovery"); mAdapter.startDiscovery(); // normalement il faut gérer plus à ce niveau // si tu veux supporter le process de // pairing. } } } private void sleep5s() { try { Thread.sleep(5000); } catch (final InterruptedException ex) { } } @Override public void run() { final BluetoothDevice dev = mAdapter.getRemoteDevice(deviceAddr); // Tentative de connexion. try { if (mSocket != null) mSocket.close(); // J'ai moins de problèmes en insecure mais tu peux essayer sans. mSocket = dev.createInsecureRfcommSocketToServiceRecord(UUID); } catch (final Exception e) { Log.e(TAG, "createInsecureRfcommSocketToServiceRecord", e); e.printStackTrace(); sleep5s(); // petite attente pour ne pas flooder avec des retry de // connexions */ /* evite la reentrance au moment du cancel */ if (!mCancel) ioError(); return; } // Stop de toutes discovery ; les inquiry en bluetooth satures les chip mAdapter.cancelDiscovery(); Log.i(TAG, "Stopping discovery"); try { // Connection avec le serveur. Log.i(TAG, "Connecting!"); mSocket.connect(); } catch (final IOException connectException) { Log.e(TAG, "failed to connect", connectException); sleep5s(); // petite attente pour ne pas flooder avec des retry de // connexions */ if (!mCancel) ioError(); return; } Log.e(TAG, "Connected"); // Récupération des flux IO pour dialoguer avec le serveur. try { mInStream = mSocket.getInputStream(); mOutStream = mSocket.getOutputStream(); } catch (final IOException e) { Log.e(TAG, "disconnected", e); ioError(); return; } /* petite notification pur savoir que la connexion est faite */ final Message msg = mHandler.obtainMessage(READY_TO_CONN); mHandler.sendMessage(msg); final byte[] buffer = new byte[1024]; int bytes; // boucle de lecture des messages envoyés par le serveur. while (!mCancel) { try { // Lecture du message. bytes = mInStream.read(buffer); if (bytes == -1) { Log.e(TAG, "disconnected"); ioError(); break; } // Propagation du message recu. mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget(); } catch (final Exception e) { Log.e(TAG, "disconnected", e); ioError(); break; } } } /** Permet l'ecriture d'un message sur le socket */ public void write(final String buffer) { try { if (mOutStream != null) mOutStream.write(buffer.getBytes()); } catch (final IOException e) { Log.e(TAG, "Exception during write", e); ioError(); } } private void ioError() { Log.i(TAG, "connectionLost"); cancel(); /* ferme le socket */ /* notifie le handler pour l'activity */ final Message msg = mHandler.obtainMessage(CANCEL_CONN); mHandler.sendMessage(msg); } /** Stop la connection et ferme le socket bluetooth */ public void cancel() { mCancel = true; try { if (mSocket != null) mSocket.close(); } catch (final IOException e) { } mSocket = null; mInStream = null; mOutStream = null; } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:weightSum="5" > <TextView android:id="@+id/statusTV" android:layout_width="fill_parent" android:layout_height="0sp" android:layout_weight="1" android:text="statusTV"/> <TextView android:id="@+id/messageTV" android:layout_width="fill_parent" android:layout_height="0sp" android:layout_weight="3" android:text="messageTV" /> <EditText android:id="@+id/messageET" android:layout_width="fill_parent" android:layout_height="0sp" android:layout_weight="1" android:inputType="text"/> <Button android:id="@+id/button" android:layout_gravity="end" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="sendBluetooth" android:text="Send" /> </LinearLayout>
import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity implements BluetoothListener { private TextView statusTV = null; private TextView messageTV = null; private EditText messageET = null; private Button button = null; private BluetoothClient btClient = null; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); statusTV = (TextView) findViewById(R.id.statusTV); messageTV = (TextView) findViewById(R.id.messageTV); messageET = (EditText) findViewById(R.id.messageET); button = (Button) findViewById(R.id.button); buttonEnable(button, false); btClient = new BluetoothClient(this); } public void sendBluetooth(final View v) { btClient.write(messageET.getText().toString()); } @Override public void bluetoothMessage(final String message) { messageTV.append(message); messageTV.append("\n"); } @Override public void bluetoothError(final String error) { statusTV.setText("ERROR: " + error); } @Override public void bluetoothConnectionSate(final boolean connected) { statusTV.setText("Bluetooth connection " + (connected ? "DONE" : "LOST")); buttonEnable(button, connected); if (!connected) btClient.setUp(); } @Override public void onBackPressed() { super.onBackPressed(); btClient.cancel(); } private void buttonEnable(Button bt, final boolean en) { bt.setEnabled(en); bt.setClickable(en); } }
/** Permet l'ecriture d'un message sur le socket */
public void write(final String buffer) {
try {
if (mOutStream != null)
mOutStream.write(buffer.getBytes());
} catch (final IOException e) {
Log.e(TAG, "Exception during write", e);
ioError();
}
}
BluetoothSocket socket = null;
socketTmp = device.createRfcommSocketToServiceRecord(serverUuid);
socket = socketTmp;
socket.connect();