A very good Bluetooth communication demo implements the sending and receiving functions, so it is implemented with two classes. The specific content is as follows
Let's talk about the idea, there are two main categoriesMain interface classandBluetooth chat service category. First, create the thread, actuallyCreate BluetoothChatService()(Bluetooth chat service class) At this time, pass the handler over so that you can operate the UI interface, in the threadContinuous polling to read Bluetooth messages, when the send button is clicked on the main interfaceCall BluetoothChatServiceThe sending method write method here uses handler to send messages, which is displayed on the main interface, and another client constantly reads Bluetooth messages. Similarly, there is a read method that is also displayed on the interface, so that the communication is completed.
import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; public class BluetoothChat extends Activity { // Message types sent from the BluetoothChatService Handler public static final int MESSAGE_STATE_CHANGE = 1; public static final int MESSAGE_READ = 2; public static final int MESSAGE_WRITE = 3; public static final int MESSAGE_DEVICE_NAME = 4; public static final int MESSAGE_TOAST = 5; // Key names received from the BluetoothChatService Handler public static final String DEVICE_NAME = "device_name"; public static final String TOAST = "toast"; // Intent request codes private static final int REQUEST_CONNECT_DEVICE = 1; private static final int REQUEST_ENABLE_BT = 2; private TextView mTitle; private EditText text_chat; private EditText text_input; private Button but_On_Off; private Button but_search; // ------> You can search in the menu private Button but_create; // ------> Set "Can be discovered" in the menu private Button mSendButton; // The name of the Bluetooth device to be connected to private String mConnectedDeviceName; // String buffer for outgoing messages private StringBuffer mOutStringBuffer; // Local Bluetooth adapter private BluetoothAdapter mBluetoothAdapter = null; // Member object for the chat services private BluetoothChatService mChatService = null; private ArrayList<String> mPairedDevicesList = new ArrayList<String>(); private ArrayList<String> mNewDevicesList = new ArrayList<String>(); private String[] strName; private String address; @Override public void onCreate(Bundle savedInstanceState) { (savedInstanceState); requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(); mTitle = (TextView) (.text_title); text_chat = (EditText) (.text_chat); text_input = (EditText) (.text_input); but_On_Off = (Button) (.but_off_on); but_search = (Button) (.but_search_div); but_create = (Button) (.but_cjlj); mSendButton = (Button) (.but_fsxx); // Get a local Bluetooth adapter mBluetoothAdapter = (); // If null, there is no Bluetooth device if (mBluetoothAdapter == null) { (this, "No Bluetooth device", Toast.LENGTH_LONG).show(); finish(); return; } if (()) { but_On_Off.setText("Down Bluetooth"); } else { but_On_Off.setText("Open Bluetooth"); } but_On_Off.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (!()) { (); (, "Bluetooth is on", Toast.LENGTH_SHORT).show(); but_On_Off.setText("Down Bluetooth"); } else { (); (, "Bluetooth is turned off", Toast.LENGTH_SHORT).show(); but_On_Off.setText("Open Bluetooth"); } } }); but_search.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { searchDevice(); } }); but_create.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { final EditText et = new EditText(); (); (()); new () .setTitle("Please enter the room name:") .setView(et) .setPositiveButton("Sure", new () { @Override public void onClick(DialogInterface dialog, int which) { String name = ().toString() .trim(); if (("")) { (, "Please enter the room name", Toast.LENGTH_SHORT).show(); return; } // Set the room name (name); } }) .setNegativeButton("Cancel", new () { @Override public void onClick(DialogInterface dialog, int which) { } }).create().show(); // Create a connection, that is, the device's local Bluetooth device can be searched by other users' Bluetooth ensureDiscoverable(); } }); // Get a set set of already paired Bluetooth devices Set<BluetoothDevice> pairedDevices = mBluetoothAdapter .getBondedDevices(); if (() > 0) { for (BluetoothDevice device : pairedDevices) { ("Paired:" + () + "\n" + ()); } } else { (this, "No paired devices", Toast.LENGTH_SHORT).show(); } // Register the broadcast when a new Bluetooth device is discovered IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); (mReceiver, filter); // Register for broadcast after search filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); (mReceiver, filter); } @Override public void onStart() { (); // If BT is not on, request that it be enabled. // setupChat() will then be called during onActivityResult if (!()) { Intent enableIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, REQUEST_ENABLE_BT); // Otherwise, setup the chat session } else { if (mChatService == null) setupChat(); } } @Override public synchronized void 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 (mChatService != null) { // Only if the state is STATE_NONE, do we know that we haven't // started already if (() == BluetoothChatService.STATE_NONE) { // Start the Bluetooth chat services (); } } } private void setupChat() { (new OnClickListener() { public void onClick(View v) { // Send a message using content of the edit text widget String message = text_input.getText().toString(); sendMessage(message); } }); // Initialize the BluetoothChatService to perform bluetooth connections mChatService = new BluetoothChatService(this, mHandler); // Initialize the buffer for outgoing messages mOutStringBuffer = new StringBuffer(""); } @Override public void onDestroy() { (); // Stop the Bluetooth chat services if (mChatService != null) (); // Make sure we're not doing discovery anymore if (mBluetoothAdapter != null) { (); } // Unregister broadcast listeners (mReceiver); } /** Make local Bluetooth devices discoverable */ private void ensureDiscoverable() { if (() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { Intent discoverableIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); ( BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent); } } /** * Sends a message. * * @param message * A string of text to send. */ private void sendMessage(String message) { // Check that we're actually connected before trying anything if (() != BluetoothChatService.STATE_CONNECTED) { (this, "Not connected", Toast.LENGTH_SHORT).show(); return; } // Check that there's actually something to send if (() > 0) { // Get the message bytes and tell the BluetoothChatService to write byte[] send = (); (send); // Reset out string buffer to zero and clear the edit text field (0); text_input.setText(mOutStringBuffer); } } // The Handler that gets information back from the BluetoothChatService private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch () { case MESSAGE_STATE_CHANGE: switch (msg.arg1) { case BluetoothChatService.STATE_CONNECTED: ("Already connected"); (mConnectedDeviceName); // (); break; case BluetoothChatService.STATE_CONNECTING: ("Connecting..."); break; case BluetoothChatService.STATE_LISTEN: case BluetoothChatService.STATE_NONE: ("Not connected"); break; } break; case MESSAGE_WRITE: byte[] writeBuf = (byte[]) ; // construct a string from the buffer String writeMessage = new String(writeBuf); // ("Me: " + writeMessage); text_chat.append("I:" + writeMessage + "\n"); break; case MESSAGE_READ: byte[] readBuf = (byte[]) ; // construct a string from the valid bytes in the buffer String readMessage = new String(readBuf, 0, msg.arg1); // (mConnectedDeviceName+": " + // readMessage); text_chat.append(mConnectedDeviceName + ":" + readMessage + "\n"); break; case MESSAGE_DEVICE_NAME: // save the connected device's name mConnectedDeviceName = ().getString(DEVICE_NAME); (getApplicationContext(), "Connect to" + mConnectedDeviceName, Toast.LENGTH_SHORT) .show(); break; case MESSAGE_TOAST: (getApplicationContext(), ().getString(TOAST), Toast.LENGTH_SHORT) .show(); break; } } }; // Connect to Bluetooth device private void linkDevice() { if (()) { (); } int cou = () + (); if (cou == 0) { (, "No Bluetooth devices available were found", Toast.LENGTH_SHORT).show(); return; } // Put the names of the paired Bluetooth devices and newly discovered Bluetooth devices into the array to display in the dialog list strName = new String[cou]; for (int i = 0; i < (); i++) { strName[i] = (i); } for (int i = (); i < ; i++) { strName[i] = (i - ()); } address = strName[0].substring(strName[0].length() - 17); new () .setTitle("Bluetooth device searched:") .setSingleChoiceItems(strName, 0, new () { @Override public void onClick(DialogInterface dialog, int which) { // When the user clicks on the selected Bluetooth device, remove the MAC address of the selected Bluetooth device address = strName[which].split("\\n")[1].trim(); } }) .setPositiveButton("connect", new () { @Override public void onClick(DialogInterface dialog, int which) { if (address == null) { (, "Please connect to an external Bluetooth device first", Toast.LENGTH_SHORT).show(); return; } ("sxd", "address:" + address); // Get the BLuetoothDevice object BluetoothDevice device = mBluetoothAdapter .getRemoteDevice(address); // Attempt to connect to the device (device); } }) .setNegativeButton("Cancel", new () { @Override public void onClick(DialogInterface dialog, int which) { } }).create().show(); } // Search for Bluetooth devices Bluetooth devices private void searchDevice() { ("Search hard..."); setProgressBarIndeterminateVisibility(true); if (()) { (); } (); (); } @Override public boolean onCreateOptionsMenu(Menu menu) { (0, 1, 0, "Search for Devices"); (0, 2, 0, "Can be discovered"); return true; } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = (); // When a new Bluetooth device is discovered if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // If it's already paired, skip it, because it's been listed // already if (() != BluetoothDevice.BOND_BONDED) { String s = "Unpaired: " + () + "\n" + (); if (!(s)) (s); } // When discovery is finished, change the Activity title } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED .equals(action)) { setProgressBarIndeterminateVisibility(false); if (() == 0) { (, "No new equipment was found", Toast.LENGTH_SHORT).show(); } ("Not connected"); linkDevice(); } } }; @Override public boolean onOptionsItemSelected(MenuItem item) { switch (()) { case 1: searchDevice(); return true; case 2: // Ensure this device is discoverable by others ensureDiscoverable(); return true; } return false; } }
package com.; /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * /licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; /** * 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. * * * This class does all the work, establishes and manages Bluetooth connections with other devices. It has a thread listening for incoming connections, a thread used to connect to a device, and a thread that performs data transfer when connecting. */ public class BluetoothChatService { // Debugging private static final String TAG = "BluetoothChatService"; private static final boolean D = true; // Name for the SDP record when creating server socket When creating server socket private static final String NAME = "BluetoothChat"; // Unique UUID for this application private static final UUID MY_UUID = UUID .fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"); // Member fields private final BluetoothAdapter mAdapter; private final Handler mHandler; private AcceptThread mAcceptThread; 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 // Start an outgoing // connection public static final int STATE_CONNECTED = 3; // now connected to a remote // Connect 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 BluetoothChatService(Context context, Handler handler) { mAdapter = (); mState = STATE_NONE; mHandler = handler; } /** * 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) (TAG, "setState() " + mState + " -> " + state); mState = state; // Give the new state to the Handler so the UI Activity can update (BluetoothChat.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) (TAG, "start"); // Cancel any thread attempting to make a connection if (mConnectThread != null) { (); mConnectThread = null; } // Cancel any thread currently running a connection if (mConnectedThread != null) { (); mConnectedThread = null; } // Start the thread to listen on a BluetoothServerSocket if (mAcceptThread == null) { mAcceptThread = new AcceptThread(); (); } 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) { if (D) (TAG, "connect to: " + device); // Cancel any thread attempting to make a connection if (mState == STATE_CONNECTING) { if (mConnectThread != null) { (); mConnectThread = null; } } // Cancel any thread currently running a connection if (mConnectedThread != null) { (); mConnectedThread = null; } // Start the thread to connect with the given device mConnectThread = new ConnectThread(device); (); setState(STATE_CONNECTING); } /** * 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) { if (D) (TAG, "connected"); // Cancel the thread that completed the connection if (mConnectThread != null) { (); mConnectThread = null; } // Cancel any thread currently running a connection if (mConnectedThread != null) { (); mConnectedThread = null; } // Cancel the accept thread because we only want to connect to one // device if (mAcceptThread != null) { (); mAcceptThread = null; } // Start the thread to manage the connection and perform transmissions mConnectedThread = new ConnectedThread(socket); (); // Send the name of the connected device back to the UI Activity Message msg = (BluetoothChat.MESSAGE_DEVICE_NAME); Bundle bundle = new Bundle(); (BluetoothChat.DEVICE_NAME, ()); (bundle); (msg); setState(STATE_CONNECTED); } /** * Stop all threads */ public synchronized void stop() { if (D) (TAG, "stop"); if (mConnectThread != null) { (); mConnectThread = null; } if (mConnectedThread != null) { (); mConnectedThread = null; } if (mAcceptThread != null) { (); mAcceptThread = 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) { // Create temporary object ConnectedThread r; // Synchronize a copy of the ConnectedThread synchronized (this) { if (mState != STATE_CONNECTED) return; r = mConnectedThread; } // Perform the write unsynchronized (out); } /** * 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 = (BluetoothChat.MESSAGE_TOAST); Bundle bundle = new Bundle(); (, "Cannot connect to the device"); (bundle); (msg); } /** * Indicate that the connection was lost and notify the UI Activity. */ private void connectionLost() { setState(STATE_LISTEN); // Send a failure message back to the Activity Message msg = (BluetoothChat.MESSAGE_TOAST); Bundle bundle = new Bundle(); (, "Disconnection of device"); (bundle); (msg); } /** * 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 { // The local server socket private final BluetoothServerSocket mmServerSocket; public AcceptThread() { BluetoothServerSocket tmp = null; // Create a new listening server socket try { tmp = mAdapter .listenUsingRfcommWithServiceRecord(NAME, MY_UUID); } catch (IOException e) { ("sxd", " ======== ufcomm exception =======", e); } mmServerSocket = tmp; } public void run() { if (D) (TAG, "BEGIN mAcceptThread" + this); setName("AcceptThread"); BluetoothSocket socket = null; // 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 = (); } catch (IOException e) { ("sxd", "---> accept socket failed <---", e); break; } // If a connection was accepted if (socket != null) { synchronized () { switch (mState) { case STATE_LISTEN: case STATE_CONNECTING: // Situation normal. Start the connected thread. connected(socket, ()); break; case STATE_NONE: case STATE_CONNECTED: // Either not ready or already connected. Terminate // new socket. try { (); } catch (IOException e) { (TAG, "Could not close unwanted socket", e); } break; } } } } if (D) (TAG, "END mAcceptThread"); } public void cancel() { if (D) (TAG, "cancel " + this); try { (); } catch (IOException 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; public ConnectThread(BluetoothDevice device) { mmDevice = device; BluetoothSocket tmp = null; // Get a BluetoothSocket for a connection with the // given BluetoothDevice try { tmp = (MY_UUID); } catch (IOException e) { (TAG, "create() failed", e); } mmSocket = tmp; } public void run() { (TAG, "BEGIN mConnectThread"); setName("ConnectThread"); // Always cancel discovery because it will slow down a connection (); // Make a connection to the BluetoothSocket try { // This is a blocking call and will only return on a // successful connection or an exception (); } catch (IOException e) { ("sxd", "The link has an exception", e); connectionFailed(); // Close the socket try { (); } catch (IOException e2) { (TAG, "unable to close() socket during connection failure", e2); } // Start the service over to restart listening mode (); return; } // Reset the ConnectThread because we're done synchronized () { mConnectThread = null; } // Start the connected thread connected(mmSocket, mmDevice); } public void cancel() { try { (); } catch (IOException 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. * * Transfer data with settings that have already established a connection */ private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) { (TAG, "create ConnectedThread"); mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the BluetoothSocket input and output streams try { tmpIn = (); tmpOut = (); } catch (IOException e) { (TAG, "temp sockets not created", e); } mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { (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 = (buffer); // Send the obtained bytes to the UI Activity (BluetoothChat.MESSAGE_READ, bytes, -1, buffer).sendToTarget(); } catch (IOException e) { (TAG, "disconnected", e); connectionLost(); break; } } } /** * Write to the connected OutStream. * * @param buffer * The bytes to write */ public void write(byte[] buffer) { try { (buffer); // Share the sent message back to the UI Activity (BluetoothChat.MESSAGE_WRITE, -1, -1, buffer).sendToTarget(); } catch (IOException e) { (TAG, "Exception during write", e); } } public void cancel() { try { (); } catch (IOException e) { (TAG, "close() of connect socket failed", e); } } } }
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.