Bluetooth
Quickview
- Android's bluetooth APIs allow your application to perform wireless data transactions withother devices
In this document
- The Basics
- Bluetooth Permissions
- Setting Up Bluetooth
- Finding Devices
- Connecting Devices
- Managing a Connection
- Working with Profiles
Key classes
Related samples
The Android platform includes support for the Bluetooth network stack,which allows a device to wirelessly exchange data with other Bluetooth devices.The application framework provides access to the Bluetooth functionality throughthe Android Bluetooth APIs. These APIs let applications wirelesslyconnect to other Bluetooth devices, enabling point-to-point and multipointwireless features.
Using the Bluetooth APIs, an Android application can perform thefollowing:
- Scan for other Bluetooth devices
- Query the local Bluetooth adapter for paired Bluetooth devices
- Establish RFCOMM channels
- Connect to other devices through service discovery
- Transfer data to and from other devices
- Manage multiple connections
The Basics
This document describes how to use the Android Bluetooth APIs to accomplishthe four major tasks necessary to communicate using Bluetooth: setting upBluetooth, finding devices that are either paired or available in the localarea, connecting devices, and transferring data between devices.
All of the Bluetooth APIs are available in the android.bluetooth
package. Here's a summary of the classes and interfaces you will need to create Bluetoothconnections:
-
Represents the local Bluetooth adapter (Bluetooth radio). The
BluetoothAdapter
is the entry-point for all Bluetoothinteraction. Using this,you can discover other Bluetooth devices, query a list of bonded (paired)devices, instantiate aBluetoothDevice
using a knownMAC address, and create aBluetoothServerSocket
tolisten for communicationsfrom other devices. -
Represents a remote Bluetooth device. Use this to request a connectionwith a remote device through a
BluetoothSocket
orquery information about thedevice such as its name, address, class, and bonding state. -
Represents the interface for a Bluetooth socket (similar to a TCP
Socket
). This is the connection point that allowsan application to exchange data with another Bluetooth device via InputStreamand OutputStream. -
Represents an open server socket that listens for incoming requests(similar to a TCP
ServerSocket
). In order to connect twoAndroid devices, one device must open a server socket with this class. When aremote Bluetooth device makes a connection request to the this device, theBluetoothServerSocket
will return a connectedBluetoothSocket
when theconnection is accepted. - Describes the general characteristics and capabilities of a Bluetoothdevice. This is a read-only set of properties that define the device's major andminor device classes and its services. However, this does not reliably describeall Bluetooth profiles and services supported by the device, but is useful as ahint to the device type.
- An interface thatrepresents a Bluetooth profile. A Bluetooth profile is a wirelessinterface specification for Bluetooth-based communication between devices. Anexample is the Hands-Free profile. For more discussion of profiles, see Working with Profiles
- Provides support forBluetooth headsets to be used with mobile phones. This includes both BluetoothHeadset and Hands-Free (v1.5) profiles.
- Defines how high qualityaudio can be streamed from one device to another over a Bluetooth connection."A2DP" stands for Advanced Audio Distribution Profile.
-
An interface that notifies
BluetoothProfile
IPCclients when they have been connected to or disconnected from the service (thatis, the internal service that runs a particular profile).
BluetoothAdapter
BluetoothDevice
BluetoothSocket
BluetoothServerSocket
BluetoothClass
BluetoothProfile
BluetoothHeadset
BluetoothA2dp
BluetoothProfile.ServiceListener
Bluetooth Permissions
In order to use Bluetooth features in your application, you need to declareat least one of two Bluetooth permissions:BLUETOOTH
andBLUETOOTH_ADMIN
.
You must request the BLUETOOTH
permissionin order to perform any Bluetooth communication, such as requesting aconnection, accepting a connection, and transferring data.
You must request the BLUETOOTH_ADMIN
permission in order to initiate device discovery or manipulate Bluetoothsettings. Most applications need this permission solely for theability to discover local Bluetooth devices. The other abilities granted by thispermission should not be used, unless the application is a "power manager" thatwill modify Bluetooth settings upon user request.Note: If youuse BLUETOOTH_ADMIN
permission, then mustalso have theBLUETOOTH
permission.
Declare the Bluetooth permission(s) in your application manifest file. Forexample:
<manifest ... > <uses-permission android:name="android.permission.BLUETOOTH" /> ... </manifest>
See the <uses-permission> reference for more information about declaring application permissions.
Setting Up Bluetooth

Before your application can communicate over Bluetooth, you need to verifythat Bluetooth is supported on the device, and if so, ensure that it is enabled.
If Bluetooth is not supported, then you should gracefully disable anyBluetooth features. If Bluetooth is supported, but disabled, then you can request that theuser enable Bluetooth without leaving your application. This setup isaccomplished in two steps, using the BluetoothAdapter
.
- Get the
BluetoothAdapter
The
BluetoothAdapter
is required for any and all Bluetoothactivity. To get theBluetoothAdapter
, call the staticgetDefaultAdapter()
method. This returns aBluetoothAdapter
that represents the device's ownBluetooth adapter (the Bluetooth radio). There's one Bluetooth adapter for theentire system, and your application can interact with it using this object. IfgetDefaultAdapter()
returns null,then the device does not support Bluetooth and your story ends here. For example:BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { // Device does not support Bluetooth }
- Enable Bluetooth
Next, you need to ensure that Bluetooth is enabled. Call
isEnabled()
to check whether Bluetooth iscurrently enable. If this method returns false, then Bluetooth is disabled. Torequest that Bluetooth be enabled, callstartActivityForResult()
with theACTION_REQUEST_ENABLE
action Intent.This will issue a request to enable Bluetooth through the system settings (withoutstopping your application). For example:if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }
A dialog will appear requesting user permission to enable Bluetooth, as shownin Figure 1. If the user responds "Yes," the system will begin to enable Bluetoothand focus will return to your application once the process completes (or fails).
If enabling Bluetooth succeeds, your Activity will receive the
RESULT_OK
result code in theonActivityResult()
callback. If Bluetooth was not enableddue to an error (or the user responded "No") then the result code will beRESULT_CANCELED
.
Optionally, your application can also listen for theACTION_STATE_CHANGED
broadcast Intent, whichthe system will broadcast whenever the Bluetooth state has changed. This broadcast containsthe extra fields EXTRA_STATE
andEXTRA_PREVIOUS_STATE
, containing the new and oldBluetooth states, respectively. Possible values for these extra fields areSTATE_TURNING_ON
,STATE_ON
,STATE_TURNING_OFF
, andSTATE_OFF
. Listening for thisbroadcast can be useful to detect changes made to the Bluetooth state while yourapp is running.
Tip: Enabling discoverability will automaticallyenable Bluetooth. If you plan to consistently enable device discoverability beforeperforming Bluetooth activity, you can skipstep 2 above. Read aboutenabling discoverability,below.
Finding Devices
Using the BluetoothAdapter
, you can find remote Bluetoothdevices either through device discovery or by querying the list of paired (bonded)devices.
Device discovery is a scanning procedure that searches the local area forBluetooth enabled devices and then requesting some information about each one(this is sometimes referred to as "discovering," "inquiring" or "scanning").However, a Bluetooth device within the local area will respond to a discoveryrequest only if it is currently enabled to be discoverable. If a device isdiscoverable, it will respond to the discovery request by sharing someinformation, such as the device name, class, and its unique MAC address. Usingthis information, the device performing discovery can then choose to initiate aconnection to the discovered device.
Once a connection is made with a remote device for the first time, a pairingrequest is automatically presented to the user. When a device ispaired, the basic information about that device (such as the device name, class,and MAC address) is saved and can be read using the Bluetooth APIs. Using theknown MAC address for a remote device, a connection can be initiated with it atany time without performing discovery (assuming the device is within range).
Remember there is a difference between being paired and being connected. Tobe paired means that two devices are aware of each other's existence, have ashared link-key that can be used for authentication, and are capable ofestablishing an encrypted connection with each other. To be connected means thatthe devices currently share an RFCOMM channel and are able to transmit data witheach other. The current Android Bluetooth API's require devices to be pairedbefore an RFCOMM connection can be established. (Pairing is automatically performedwhen you initiate an encrypted connection with the Bluetooth APIs.)
The following sections describe how to find devices that have been paired, ordiscover new devices using device discovery.
Note: Android-powered devices are notdiscoverable by default. A user can makethe device discoverable for a limited time through the system settings, or anapplication can request that the user enable discoverability without leaving theapplication. How to enable discoverability is discussed below.
Querying paired devices
Before performing device discovery, its worth querying the setof paired devices to see if the desired device is already known. To do so,callgetBondedDevices()
. Thiswill return a Set ofBluetoothDevice
s representingpaired devices. For example, you can query all paired devices and thenshow the name of each device to the user, using an ArrayAdapter:
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); // If there are paired devices if (pairedDevices.size() > 0) { // Loop through paired devices for (BluetoothDevice device : pairedDevices) { // Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } }
All that's needed from the BluetoothDevice
objectin order to initiate a connection is the MAC address. In this example, it's savedas a part of an ArrayAdapter that's shown to the user. The MAC address can laterbe extracted in order to initiate the connection. You can learn more about creatinga connection in the section aboutConnecting Devices.
Discovering devices
To start discovering devices, simply call startDiscovery()
. Theprocess is asynchronous and the method will immediately return with a booleanindicating whether discovery has successfully started. The discovery processusually involves an inquiry scan of about 12 seconds, followed by a page scan ofeach found device to retrieve its Bluetooth name.
Your application must register a BroadcastReceiver for theACTION_FOUND
Intent inorder to receive information about eachdevice discovered. For each device, the system will broadcast theACTION_FOUND
Intent. ThisIntent carries the extra fieldsEXTRA_DEVICE
andEXTRA_CLASS
, containing aBluetoothDevice
and a BluetoothClass
, respectively. For example, here's how you canregister to handle the broadcast when devices are discovered:
// Create a BroadcastReceiver for ACTION_FOUND private final BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // When discovery finds a device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } }; // Register the BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
All that's needed from the BluetoothDevice
objectin order to initiate aconnection is the MAC address. In this example, it's saved as a part of anArrayAdapter that's shown to the user. The MAC address can later be extracted inorder to initiate the connection. You can learn more about creating a connectionin the section aboutConnecting Devices.
Caution: Performing device discovery isa heavy procedure for the Bluetoothadapter and will consume a lot of its resources. Once you have found a device toconnect, be certain that you always stop discovery withcancelDiscovery()
beforeattempting a connection. Also, if youalready hold a connection with a device, then performing discovery cansignificantly reduce the bandwidth available for the connection, so you shouldnot perform discovery while connected.
Enabling discoverability
If you would like to make the local device discoverable to other devices,call startActivityForResult(Intent, int)
with theACTION_REQUEST_DISCOVERABLE
actionIntent. This will issue a request to enable discoverable mode through the systemsettings (without stopping your application). By default, the device will becomediscoverable for 120 seconds. You can define a different duration by adding theEXTRA_DISCOVERABLE_DURATION
Intentextra. The maximum duration an app can set is 3600 seconds, and a value of 0means the device is always discoverable. Any value below 0 or above 3600 isautomatically set to 120 secs). For example, this snippet sets the duration to300:
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent);

A dialog will be displayed, requesting user permission to make the devicediscoverable, as shown in Figure 2. If the user responds "Yes," then the devicewill become discoverable for the specified amount of time. Your Activity willthen receive a call to theonActivityResult())
callback, with the result code equal to the duration that the deviceis discoverable. If the user responded "No" or if an error occurred, the result code willbe Activity.RESULT_CANCELLED.
Note: If Bluetooth has not been enabled on the device,then enabling device discoverability will automatically enable Bluetooth.
The device will silently remain in discoverable mode for the allotted time.If you would like to be notified when the discoverable mode has changed, you canregister a BroadcastReceiver for theACTION_SCAN_MODE_CHANGED
Intent. This will contain the extra fieldsEXTRA_SCAN_MODE
andEXTRA_PREVIOUS_SCAN_MODE
, which tell you thenew and old scan mode, respectively. Possible values for each areSCAN_MODE_CONNECTABLE_DISCOVERABLE
,SCAN_MODE_CONNECTABLE
, or SCAN_MODE_NONE
,which indicate that the device is either in discoverable mode, not indiscoverable mode but still able to receive connections, or not in discoverablemode and unable to receive connections, respectively.
You do not need to enable device discoverability if you will be initiatingthe connection to a remote device. Enabling discoverability is only necessary whenyou want your application to host a server socket that will accept incomingconnections, because the remote devices must be able to discover the devicebefore it can initiate the connection.
Connecting Devices
In order to create a connection between your application on two devices, youmust implement both the server-side and client-side mechanisms, because onedevice must open a server socket and the other one must initiate the connection(using the server device's MAC address to initiate a connection). The server andclient are considered connected to each other when they each have a connectedBluetoothSocket
on the same RFCOMM channel. At thispoint, each device can obtain input and output streams and data transfer canbegin, which is discussed in the section aboutManaging a Connection. This section describes howto initiate the connection between two devices.
The server device and the client device each obtain the required BluetoothSocket
in different ways. The server will receive itwhen an incoming connection is accepted. The client will receive it when itopens an RFCOMM channel to the server.

One implementation technique is to automatically prepare each device as aserver, so that each one has a server socket open and listening for connections.Then either device can initiate a connection with the other and become theclient. Alternatively, one device can explicitly "host" the connection and opena server socket on demand and the other device can simply initiate theconnection.
Note: If the two devices have not been previously paired,then the Android framework will automatically show a pairing request notification ordialog to the user during the connection procedure, as shown in Figure 3. Sowhen attempting to connect devices,your application does not need to be concerned about whether or not the devices arepaired. Your RFCOMM connection attempt will block until the user has successfully paired,or will fail if the user rejects pairing, or if pairing fails or times out.
Connecting as a server
When you want to connect two devices, one must act as a server by holding anopenBluetoothServerSocket
. The purpose of the serversocket is to listen for incoming connection requests and when one is accepted,provide a connectedBluetoothSocket
. When theBluetoothSocket
is acquired from theBluetoothServerSocket
,theBluetoothServerSocket
can (and should) bediscarded, unless you want to accept more connections.
About UUID
A Universally Unique Identifier (UUID) is a standardized 128-bit format for a stringID used to uniquely identify information. The point of a UUID is that it's bigenough that you can select any random and it won't clash. In this case, it'sused to uniquely identify your application's Bluetooth service. To get a UUID touse with your application, you can use one of the many random UUID generators onthe web, then initialize aUUID
withfromString(String)
.
Here's the basic procedure to set up a server socket and accept aconnection:
- Get a
BluetoothServerSocket
by calling thelistenUsingRfcommWithServiceRecord(String, UUID)
.The string is an identifiable name of your service, which the system willautomatically write to a new Service Discovery Protocol (SDP) database entry onthe device (the name is arbitrary and can simply be your application name). TheUUID is also included in the SDP entry and will be the basis for the connectionagreement with the client device. That is, when the client attempts to connectwith this device, it will carry a UUID that uniquely identifies the service withwhich it wants to connect. These UUIDs must match in order for the connection tobe accepted (in the next step).
- Start listening for connection requests by calling
accept()
.This is a blocking call. It will return when either a connection has beenaccepted or an exception has occurred. A connection is accepted only when aremote device has sent a connection request with a UUID matching the oneregistered with this listening server socket. When successful,
accept()
willreturn a connectedBluetoothSocket
. - Unless you want to accept additional connections, call
close()
.This releases the server socket and all its resources, but does not close theconnected
BluetoothSocket
that's been returned byaccept()
. Unlike TCP/IP, RFCOMM only allows oneconnected client per channel at a time, so in most cases it makes sense to callclose()
on theBluetoothServerSocket
immediately after accepting a connectedsocket.
The accept()
call should notbe executed in the main Activity UI thread because it is a blocking call andwill prevent any other interaction with the application. It usually makessense to do all work with a BluetoothServerSocket
orBluetoothSocket
in a newthread managed by your application. To abort a blocked call such asaccept()
, callclose()
on theBluetoothServerSocket
(orBluetoothSocket
) from another thread and the blocked call willimmediately return. Note that all methods on aBluetoothServerSocket
orBluetoothSocket
are thread-safe.
Example
Here's a simplified thread for the server component that accepts incomingconnections:
private class AcceptThread extends Thread { private final BluetoothServerSocket mmServerSocket; public AcceptThread() { // Use a temporary object that is later assigned to mmServerSocket, // because mmServerSocket is final BluetoothServerSocket tmp = null; try { // MY_UUID is the app's UUID string, also used by the client code tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID); } catch (IOException e) { } mmServerSocket = tmp; } public void run() { BluetoothSocket socket = null; // Keep listening until exception occurs or a socket is returned while (true) { try { socket = mmServerSocket.accept(); } catch (IOException e) { break; } // If a connection was accepted if (socket != null) { // Do work to manage the connection (in a separate thread) manageConnectedSocket(socket); mmServerSocket.close(); break; } } } /** Will cancel the listening socket, and cause the thread to finish */ public void cancel() { try { mmServerSocket.close(); } catch (IOException e) { } } }
In this example, only one incoming connection is desired, so as soon as aconnection is accepted and theBluetoothSocket
isacquired, the applicationsends the acquiredBluetoothSocket
to a separatethread, closes theBluetoothServerSocket
and breaks the loop.
Note that when accept()
returns theBluetoothSocket
, the socket is alreadyconnected, so you shouldnot call connect()
(as you do from theclient-side).
manageConnectedSocket()
is a fictional method in the applicationthat willinitiate the thread for transferring data, which is discussed in the sectionaboutManaging a Connection.
You should usually close your BluetoothServerSocket
as soon as you are done listening for incoming connections. In this example,close()
is called as soonas theBluetoothSocket
is acquired. You may also wantto provide a public method in your thread that can close the privateBluetoothSocket
in the event that you need to stop listening on theserver socket.
Connecting as a client
In order to initiate a connection with a remote device (a device holding anopenserver socket), you must first obtain aBluetoothDevice
object that represents the remote device.(Getting aBluetoothDevice
is covered in the abovesection aboutFinding Devices.) You must then use theBluetoothDevice
to acquire aBluetoothSocket
and initiate the connection.
Here's the basic procedure:
- Using the
BluetoothDevice
, get aBluetoothSocket
by callingcreateRfcommSocketToServiceRecord(UUID)
.This initializes a
BluetoothSocket
that willconnect to theBluetoothDevice
. The UUID passed heremust match the UUID used by the server device when it opened itsBluetoothServerSocket
(withlistenUsingRfcommWithServiceRecord(String, UUID)
). Using the same UUID is simply a matter of hard-coding the UUID stringinto your application and then referencing it from both the server and clientcode. - Initiate the connection by calling
connect()
.Upon this call, the system will perform an SDP lookup on the remote device inorder to match the UUID. If the lookup is successful and the remote deviceaccepts the connection, it will share the RFCOMM channel to use during theconnection and
connect()
will return. This method is ablocking call. If, forany reason, the connection fails or theconnect()
method times out (after about12 seconds), then it will throw an exception.Because
connect()
is a blocking call, this connectionprocedure should always be performed in a thread separate from the main Activitythread.Note: You should always ensure that the device is not performingdevice discovery when you call
connect()
. If discovery is in progress, thentheconnection attempt will be significantly slowed and is more likely to fail.
Example
Here is a basic example of a thread that initiates a Bluetoothconnection:
private class ConnectThread extends Thread { private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; public ConnectThread(BluetoothDevice device) { // Use a temporary object that is later assigned to mmSocket, // because mmSocket is final BluetoothSocket tmp = null; mmDevice = device; // Get a BluetoothSocket to connect with the given BluetoothDevice try { // MY_UUID is the app's UUID string, also used by the server code tmp = device.createRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e) { } mmSocket = tmp; } public void run() { // Cancel discovery because it will slow down the connection mBluetoothAdapter.cancelDiscovery(); try { // Connect the device through the socket. This will block // until it succeeds or throws an exception mmSocket.connect(); } catch (IOException connectException) { // Unable to connect; close the socket and get out try { mmSocket.close(); } catch (IOException closeException) { } return; } // Do work to manage the connection (in a separate thread) manageConnectedSocket(mmSocket); } /** Will cancel an in-progress connection, and close the socket */ public void cancel() { try { mmSocket.close(); } catch (IOException e) { } } }
Notice that cancelDiscovery()
is calledbefore the connection is made. You should always do this before connecting and it is safeto call without actually checking whether it is running or not (but if you do want tocheck, callisDiscovering()
).
manageConnectedSocket()
is a fictional method in the applicationthat will initiate the thread for transferring data, which is discussed in the sectionaboutManaging a Connection.
When you're done with your BluetoothSocket
, alwayscallclose()
to clean up.Doing so will immediately close the connected socket and clean up all internalresources.
Managing a Connection
When you have successfully connected two (or more) devices, each one willhave a connectedBluetoothSocket
. This is where the funbegins because you can share data between devices. Using theBluetoothSocket
, the general procedure to transfer arbitrary data issimple:
- Get the
InputStream
andOutputStream
thathandle transmissions through the socket, viagetInputStream()
andgetOutputStream()
, respectively. - Read and write data to the streams with
read(byte[])
andwrite(byte[])
.
That's it.
There are, of course, implementation details to consider. First and foremost,you should use a dedicated thread for all stream reading and writing. This isimportant because bothread(byte[])
andwrite(byte[])
methods are blocking calls.read(byte[])
will block until there is something to readfrom the stream.write(byte[])
does not usuallyblock, but can block for flow control if the remote device is not callingread(byte[])
quickly enough and the intermediate buffers are full.So, your main loop in the thread should be dedicated to reading from theInputStream
. A separate public method in the thread can be used to initiatewrites to theOutputStream
.
Example
Here's an example of how this might look:
private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) { mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the input and output streams, using temp objects because // member streams are final try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (IOException e) { } mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { byte[] buffer = new byte[1024]; // buffer store for the stream int bytes; // bytes returned from read() // Keep listening to the InputStream until an exception occurs while (true) { try { // Read from the InputStream bytes = mmInStream.read(buffer); // Send the obtained bytes to the UI Activity mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer) .sendToTarget(); } catch (IOException e) { break; } } } /* Call this from the main Activity to send data to the remote device */ public void write(byte[] bytes) { try { mmOutStream.write(bytes); } catch (IOException e) { } } /* Call this from the main Activity to shutdown the connection */ public void cancel() { try { mmSocket.close(); } catch (IOException e) { } } }
The constructor acquires the necessary streams and once executed, the threadwill wait for data to come through the InputStream. Whenread(byte[])
returns withbytes from the stream, the data is sent to the main Activity using a memberHandler from the parent class. Then it goes back and waits for more bytes fromthe stream.
Sending outgoing data is as simple as calling the thread'swrite()
method from the main Activity and passing in the bytes tobe sent. This method then simply callswrite(byte[])
to send the data to the remote device.
The thread's cancel()
method is important so that the connectioncan beterminated at any time by closing theBluetoothSocket
.This should always be called when you're done using the Bluetoothconnection.
For a demonstration of using the Bluetooth APIs, see the Bluetooth Chat sample app.
Working with Profiles
Starting in Android 3.0, the Bluetooth API includes support for working withBluetooth profiles. ABluetooth profile is a wireless interfacespecification for Bluetooth-based communication between devices. An exampleis the Hands-Free profile. For a mobile phone to connect to a wireless headset,both devices must support the Hands-Free profile.
You can implement the interface BluetoothProfile
to writeyour own classes to support a particular Bluetooth profile. The AndroidBluetooth API provides implementations for the following Bluetoothprofiles:
- Headset. The Headset profile provides support forBluetooth headsets to be used with mobile phones. Android provides the
BluetoothHeadset
class, which is a proxy for controlling theBluetooth Headset Service via interprocess communication (IPC). This includes both Bluetooth Headset and Hands-Free (v1.5) profiles. TheBluetoothHeadset
class includes support for AT commands.For more discussion of this topic, seeVendor-specific AT commands - A2DP. The Advanced Audio Distribution Profile (A2DP)profile defines how high quality audio can be streamed from one device toanother over a Bluetooth connection. Android provides the
BluetoothA2dp
class, which is a proxy for controllingthe Bluetooth A2DP Service via IPC.
Here are the basic steps for working with a profile:
- Get the default adapter, as described in Setting Up Bluetooth.
- Use
getProfileProxy()
toestablish a connection to the profile proxy object associated with the profile.In the example below, the profile proxy object is an instance ofBluetoothHeadset
. - Set up a
BluetoothProfile.ServiceListener
. Thislistener notifiesBluetoothProfile
IPC clients whenthey have been connected to or disconnected from the service. - In
onServiceConnected()
, get a handleto the profile proxy object. - Once you have the profile proxy object, you can use it to monitor thestate of the connection and perform other operations that are relevant to thatprofile.
For example, this code snippet shows how to connect to a BluetoothHeadset
proxy object so that you can control theHeadset profile:
BluetoothHeadset mBluetoothHeadset; // Get the default adapter BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // Establish connection to the proxy. mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET); private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() { public void onServiceConnected(int profile, BluetoothProfile proxy) { if (profile == BluetoothProfile.HEADSET) { mBluetoothHeadset = (BluetoothHeadset) proxy; } } public void onServiceDisconnected(int profile) { if (profile == BluetoothProfile.HEADSET) { mBluetoothHeadset = null; } } }; // ... call functions on mBluetoothHeadset // Close proxy connection after use. mBluetoothAdapter.closeProfileProxy(mBluetoothHeadset);
Vendor-specific AT commands
Starting in Android 3.0, applications can register to receive systembroadcasts of pre-defined vendor-specific AT commands sent by headsets (such asa Plantronics +XEVENT command). For example, an application could receivebroadcasts that indicate a connected device's battery level and could notify theuser or take other action as needed. Create a broadcast receiver for theACTION_VENDOR_SPECIFIC_HEADSET_EVENT
intentto handle vendor-specific AT commands for the headset.