Android蓝牙通信总结
BluetoothAdapter
- Represents the local Bluetooth adapter (Bluetooth radio). The
BluetoothAdapter
is the entry-point for all Bluetooth interaction. Using this, you can discover other Bluetooth devices, query a list of bonded (paired) devices, instantiate aBluetoothDevice
using a known MAC address, and create aBluetoothServerSocket
to listen for communications from other devices.
BluetoothDevice
- Represents a remote Bluetooth device. Use this to request a connection with a remote device through a
BluetoothSocket
or query information about the device such as its name, address, class, and bonding state.
BluetoothSocket
- Represents the interface for a Bluetooth socket (similar to a TCP
Socket
). This is the connection point that allows an application to exchange data with another Bluetooth device via InputStream and OutputStream.
private class ConnectThread extends Thread { private final BluetoothSocket mmSocket ; private final BluetoothDevice mmDevice ; public ConnectThread(BluetoothDevice device, boolean secure) { mmDevice = device; BluetoothSocket tmp = null ; // Get a BluetoothSocket for a connection with the // given BluetoothDevice try { tmp = device.createRfcommSocketToServiceRecord( MY_UUID ); } catch (IOException e) { Log. e( TAG,e); } mmSocket = tmp; } public void run() { // Always cancel discovery because it will slow down a connection mAdapter.cancelDiscovery(); try { mmSocket .connect(); } catch (IOException e) { // Close the socket try { mmSocket .close(); } catch (IOException e2) { Log. e( TAG,e2); } connectionFailed(); return ; } synchronized (BluetoothService. this ) { mConnectThread = null ; } // Start the connected thread connected(mmSocket); } public void cancel() { try { mmSocket .close(); } catch (IOException e) { Log. e( TAG, "close() of connect " + mSocketType + " socket failed", e); } } }
BluetoothServerSocket
- Represents an open server socket that listens for incoming requests (similar to a TCP
ServerSocket
). In order to connect two Android devices, one device must open a server socket with this class. When a remote Bluetooth device makes a connection request to the this device, theBluetoothServerSocket
will return a connectedBluetoothSocket
when the connection is accepted.
状态转换顺序:
public class MainActivity extends Activity implements View.OnClickListener { private BluetoothAdapter mBluetoothAdapter = null; private BluetoothService mService = null; private BluetoothDevice mOnePairedDevice; private final String DeviceName = "LILEI" ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. activity_main); mBluetoothAdapter = BluetoothAdapter. getDefaultAdapter(); if ( mBluetoothAdapter == null ) { Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG ).show(); finish(); } .... } @Override public void onStart() { super.onStart(); if (! mBluetoothAdapter.isEnabled()) { // Enable Bluetooth function Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE ); startActivityForResult(enableIntent, REQUEST_ENABLE_BT); } else if (mService == null) { setupBluetoothService(); } } @Override public void onResume() { super.onResume(); // Performing this check in onResume() covers the case in which BT was // not enabled during onStart(), so we were paused to enable it... // onResume() will be called when ACTION_REQUEST_ENABLE activity returns. if ( mService != null ) { // Only if the state is STATE_NONE, do we know that we haven‘t started already if ( mService.getState() == BluetoothService.STATE_NONE) { if (mOnePairedDevice == null) { mOnePairedDevice = getASpecificPairedDevice(DeviceName ); } if (mOnePairedDevice != null) { mService.start(mOnePairedDevice ); } else { Toast. makeText(this, "Not Found the paired Device." , Toast.LENGTH_LONG ).show(); } } } } @Override public void onDestroy() { super.onDestroy(); if ( mService != null ) { mService.stop(); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_ENABLE_BT: // When the request to enable Bluetooth returns if (resultCode == Activity.RESULT_OK) { setupBluetoothService(); } else { // User did not enable Bluetooth or an error occurred Log. d(TAG, "BT not enabled"); Toast. makeText(this, R.string. bt_not_enabled_leaving, Toast.LENGTH_SHORT ).show(); finish(); } } } public void setupBluetoothService() { mService = new BluetoothService(mHandler ); } private BluetoothDevice getASpecificPairedDevice(String name) { Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); // If there are paired devices if (pairedDevices.size() > 0) { // Loop through paired devices for (BluetoothDevice device : pairedDevices) { if (name.equals(device.getName())) { return device; } } } return null; } ... }
public class BluetoothService { private static final String TAG = "BluetoothService" ; private static final UUID MY_UUID = UUID.fromString( "00001101-0000-1000-8000-00805F9B34FB"); // 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 private final BluetoothAdapter mAdapter ; private Handler mHandler ; private ConnectThread mConnectThread ; private ConnectedThread mConnectedThread ; private int mState ; public BluetoothService(Handler handler) { mAdapter = BluetoothAdapter.getDefaultAdapter(); mHandler = handler; mState = STATE_NONE ; } public void setHandler(Handler handler) { mHandler = handler; } public void start(BluetoothDevice remoteDevice) { connect(remoteDevice, false ); } public int getState() { return mState ; } public void stop() { Log. d( TAG, "stop" ); if (mConnectThread != null) { mConnectThread .cancel(); mConnectThread = null ; } if (mConnectedThread != null) { mConnectedThread .cancel(); mConnectedThread = null ; } setState( STATE_NONE ); } /** * 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 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 { tmp = device.createRfcommSocketToServiceRecord( MY_UUID ); } 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 mmSocket .connect(); } catch (IOException e) { // Close the socket try { mmSocket .close(); } catch (IOException e2) { Log. e( TAG, "unable to close() " + mSocketType + " socket during connection failure" , e2); } connectionFailed(); return ; } // 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); } } } /** * Indicate that the connection attempt failed and notify the UI Activity. */ private void connectionFailed() { // Send a failure message back to the Activity Message msg = mHandler .obtainMessage(Constants. MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(Constants. TOAST , "Unable to connect device" ); msg.setData(bundle); mHandler .sendMessage(msg); } /** * Set the current state of the chat connection * * @param state An integer defining the current connection state */ private synchronized void setState( int state) { Log. d( TAG, "setState() " + mState + " -> " + state); mState = state; // Give the new state to the Handler so the UI Activity can update mHandler .obtainMessage(Constants. MESSAGE_STATE_CHANGE, state, -1).sendToTarget(); } /** * 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, final String socketType) { Log. d( TAG, "connected, Socket Type:" + socketType); // 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 ; } // Start the thread to manage the connection and perform transmissions mConnectedThread = new ConnectedThread(socket, socketType); mConnectedThread .start(); // Send the name of the connected device back to the UI Activity Message msg = mHandler .obtainMessage(Constants. MESSAGE_DEVICE_NAME); Bundle bundle = new Bundle(); bundle.putString(Constants. DEVICE_NAME , device.getName()); msg.setData(bundle); mHandler .sendMessage(msg); setState( STATE_CONNECTED ); } /** * 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, String socketType) { Log. d( TAG, "create ConnectedThread: " + socketType); 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[3024]; 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(Constants. MESSAGE_READ, bytes, -1, buffer) .sendToTarget(); } catch (IOException e) { Log. e( TAG, "disconnected" , e); connectionLost(); 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(Constants. MESSAGE_WRITE, -1, -1, buffer).sendToTarget(); } catch (IOException e) { Log. e( TAG, "Exception during write" , e); } } public void writeFileMessage( byte[] buffer) { try { mmOutStream .write(buffer); } catch (IOException e) { Log. e( TAG, "Exception during write" , e); } } public void writeFileStream (InputStream input) { byte [] buffer = new byte[1024]; int readLengh; try { while ((readLengh = input.read(buffer)) != -1) { mmOutStream .write(buffer, 0, readLengh); } mHandler .obtainMessage(Constants. MESSAGE_WRITE , -1, -1, "Finish send file to remoteDevice." ) .sendToTarget(); } catch (IOException e) { Log. e( TAG, "Exception during write" , e); mHandler .obtainMessage(Constants. MESSAGE_WRITE, -1, -1, "Error when send file to remoteDevice").sendToTarget(); } } public void cancel() { try { mmSocket .close(); } catch (IOException e) { Log. e( TAG, "close() of connect socket failed" , e); } } } /** * Indicate that the connection was lost and notify the UI Activity. */ private void connectionLost() { // Send a failure message back to the Activity Message msg = mHandler .obtainMessage(Constants. MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(Constants. TOAST , "Device connection was lost" ); msg.setData(bundle); mHandler .sendMessage(msg); // Start the service over to restart listening mode } /** * Start the ConnectThread to initiate a connection to a remote device. * * @param device The BluetoothDevice to connect * @param secure Socket Security type - Secure (true) , Insecure (false) */ public synchronized void connect(BluetoothDevice device, boolean secure) { 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 ); } /** * Write to the ConnectedThread in an unsynchronized manner * * @param out The bytes to write * @see ConnectedThread#write(byte[]) */ public void write( byte[] out, boolean isFile) { // Create temporary object ConnectedThread r; // Synchronize a copy of the ConnectedThread synchronized (this ) { if (mState != STATE_CONNECTED) return ; r = mConnectedThread ; } // Perform the write unsynchronized if (isFile) { r.writeFileMessage(out); } else { r.write(out); } } public void write(InputStream in) { // Create temporary object ConnectedThread r; // Synchronize a copy of the ConnectedThread synchronized (this ) { if (mState != STATE_CONNECTED) return ; r = mConnectedThread ; } // Perform the write unsynchronized r. writeFileStream(in); } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。