Home | History | Annotate | Download | only in connectivity
      1 page.title=Bluetooth
      2 page.tags="wireless","bluetoothadapter","bluetoothdevice"
      3 @jd:body
      4 
      5 <div id="qv-wrapper">
      6 <div id="qv">
      7  
      8   <h2>In this document</h2>
      9   <ol> 
     10     <li><a href="#TheBasics">The Basics</a></li>
     11     <li><a href="#Permissions">Bluetooth Permissions</a></li>
     12     <li><a href="#SettingUp">Setting Up Bluetooth</a></li> 
     13     <li><a href="#FindingDevices">Finding Devices</a> 
     14       <ol> 
     15         <li><a href="#QueryingPairedDevices">Querying paired devices</a></li> 
     16         <li><a href="#DiscoveringDevices">Discovering devices</a></li> 
     17       </ol></li> 
     18     <li><a href="#ConnectingDevices">Connecting Devices</a> 
     19       <ol> 
     20         <li><a href="#ConnectingAsAServer">Connecting as a server</a></li> 
     21         <li><a href="#ConnectingAsAClient">Connecting as a client</a></li> 
     22       </ol></li> 
     23     <li><a href="#ManagingAConnection">Managing a Connection</a></li>
     24     <li><a href="#Profiles">Working with Profiles</a> 
     25       <ol>
     26         <li><a href="#AT-Commands">Vendor-specific AT commands</a>
     27         <li><a href="#HDP">Health Device Profile</a>
     28       </ol></li>
     29   </ol> 
     30  
     31   <h2>Key classes</h2> 
     32   <ol> 
     33     <li>{@link android.bluetooth.BluetoothAdapter}</li> 
     34     <li>{@link android.bluetooth.BluetoothDevice}</li> 
     35     <li>{@link android.bluetooth.BluetoothSocket}</li> 
     36     <li>{@link android.bluetooth.BluetoothServerSocket}</li> 
     37   </ol> 
     38  
     39   <h2>Related samples</h2> 
     40   <ol> 
     41     <li><a href="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat</a></li> 
     42     <li><a href="{@docRoot}resources/samples/BluetoothHDP/index.html">Bluetooth HDP (Health Device Profile)</a></li>
     43   </ol> 
     44  
     45 </div> 
     46 </div> 
     47  
     48  
     49 <p>The Android platform includes support for the Bluetooth network stack,
     50 which allows a device to wirelessly exchange data with other Bluetooth devices.
     51 The application framework provides access to the Bluetooth functionality through
     52 the Android Bluetooth APIs. These APIs let applications wirelessly
     53 connect to other Bluetooth devices, enabling point-to-point and multipoint
     54 wireless features.</p> 
     55  
     56 <p>Using the Bluetooth APIs, an Android application can perform the
     57 following:</p>
     58 <ul>
     59   <li>Scan for other Bluetooth devices</li>
     60   <li>Query the local Bluetooth adapter for paired Bluetooth devices</li>
     61   <li>Establish RFCOMM channels</li>
     62   <li>Connect to other devices through service discovery</li>
     63   <li>Transfer data to and from other devices</li>
     64   <li>Manage multiple connections</li>
     65 </ul>
     66 
     67 <p>This document describes how to use <em>Classic Bluetooth</em>. Classic
     68 Bluetooth is the right choice for more battery-intensive operations such as streaming
     69 and communicating between Android devices. For Bluetooth devices with low power requirements,
     70 Android 4.3 (API Level 18) introduces API support for Bluetooth Low Energy. To learn more,
     71 see <a href="{@docRoot}guide/topics/connectivity/bluetooth-le.html">Bluetooth Low Energy</a>.</p>
     72 
     73 <h2 id="TheBasics">The Basics</h2>
     74 
     75 <p>This document describes how to use the Android Bluetooth APIs to accomplish
     76 the four major tasks necessary to communicate using Bluetooth: setting up
     77 Bluetooth, finding devices that are either paired or available in the local
     78 area, connecting devices, and transferring data between devices.</p> 
     79  
     80 <p>All of the Bluetooth APIs are available in the {@link android.bluetooth}
     81 package. Here's a summary of the classes and interfaces you will need to create Bluetooth
     82 connections:</p> 
     83  
     84 <dl> 
     85 <dt>{@link android.bluetooth.BluetoothAdapter}</dt> 
     86 <dd>Represents the local Bluetooth adapter (Bluetooth radio). The
     87 {@link android.bluetooth.BluetoothAdapter} is the entry-point for all Bluetooth
     88 interaction. Using this,
     89 you can discover other Bluetooth devices, query a list of bonded (paired)
     90 devices, instantiate a {@link android.bluetooth.BluetoothDevice} using a known
     91 MAC address, and create a {@link android.bluetooth.BluetoothServerSocket} to
     92 listen for communications
     93 from other devices.</dd> 
     94  
     95 <dt>{@link android.bluetooth.BluetoothDevice}</dt> 
     96 <dd>Represents a remote Bluetooth device. Use this to request a connection
     97 with a remote device through a {@link android.bluetooth.BluetoothSocket} or
     98 query information about the
     99 device such as its name, address, class, and bonding state.</dd> 
    100  
    101 <dt>{@link android.bluetooth.BluetoothSocket}</dt> 
    102 <dd>Represents the interface for a Bluetooth socket (similar to a TCP
    103 {@link java.net.Socket}). This is the connection point that allows
    104 an application to exchange data with another Bluetooth device via InputStream
    105 and OutputStream.</dd> 
    106  
    107 <dt>{@link android.bluetooth.BluetoothServerSocket}</dt> 
    108 <dd>Represents an open server socket that listens for incoming requests
    109 (similar to a TCP {@link java.net.ServerSocket}). In order to connect two
    110 Android devices, one device must open a server socket with this class. When a
    111 remote Bluetooth device makes a connection request to the this device, the
    112 {@link android.bluetooth.BluetoothServerSocket} will return a connected {@link
    113 android.bluetooth.BluetoothSocket} when the
    114 connection is accepted.</dd> 
    115  
    116 <dt>{@link android.bluetooth.BluetoothClass}</dt> 
    117 <dd>Describes the general characteristics and capabilities of a Bluetooth
    118 device. This is a read-only set of properties that define the device's major and
    119 minor device classes and its services. However, this does not reliably describe
    120 all Bluetooth profiles and services supported by the device, but is useful as a
    121 hint to the device type.</dd> 
    122  
    123 <dt>{@link android.bluetooth.BluetoothProfile}</dt> <dd>An interface that
    124 represents a Bluetooth profile. A <em>Bluetooth profile</em> is a wireless
    125 interface specification for Bluetooth-based communication between devices. An
    126 example is the Hands-Free profile.  For more discussion of profiles, see <a
    127 href="#Profiles">Working with Profiles</a></dd> 
    128 
    129 <dt>{@link android.bluetooth.BluetoothHeadset}</dt> <dd>Provides support for
    130 Bluetooth headsets to be used with mobile phones. This includes both  Bluetooth
    131 Headset and Hands-Free (v1.5) profiles.</dd> 
    132 
    133 <dt>{@link android.bluetooth.BluetoothA2dp}</dt> <dd> Defines how high quality
    134 audio can be streamed from one device to another over a Bluetooth connection.
    135 "A2DP" stands for Advanced Audio Distribution Profile.</dd> 
    136 
    137 <dt>{@link android.bluetooth.BluetoothHealth}</dt>
    138 <dd> Represents a Health Device Profile proxy that controls the Bluetooth service.</dd>
    139 
    140 <dt>{@link android.bluetooth.BluetoothHealthCallback}</dt>
    141 
    142 <dd>An abstract class that you use to implement {@link
    143 android.bluetooth.BluetoothHealth} callbacks. You must extend this class and
    144 implement the callback methods to receive updates about changes in the
    145 applications registration state and Bluetooth channel state.</dd>
    146 
    147 <dt>{@link android.bluetooth.BluetoothHealthAppConfiguration}</dt>
    148 
    149 <dd>Represents an application configuration that the Bluetooth Health third-party 
    150 application registers to communicate with a remote Bluetooth health
    151 device.</dd> 
    152 
    153 <dt>{@link android.bluetooth.BluetoothProfile.ServiceListener}</dt>
    154 
    155 <dd>An interface that notifies {@link android.bluetooth.BluetoothProfile} IPC
    156 clients when they have  been connected to or disconnected from the service (that
    157 is, the internal service that runs a particular profile). </dd>
    158  
    159 </dl> 
    160  
    161  
    162  
    163  
    164 <h2 id="Permissions">Bluetooth Permissions</h2> 
    165  
    166 <p>In order to use Bluetooth features in your application, you must declare
    167 the Bluetooth permission {@link android.Manifest.permission#BLUETOOTH}.
    168 You need this permission to perform any Bluetooth communication,
    169 such as requesting a connection, accepting a connection, and transferring data.</p>
    170 
    171 <p>If you want your app to initiate device discovery or manipulate Bluetooth
    172 settings, you must also declare the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
    173 permission. Most applications need this permission solely for the
    174 ability to discover local Bluetooth devices. The other abilities granted by this
    175 permission should not be used, unless the application is a "power manager" that
    176 will modify Bluetooth settings upon user request. <strong>Note:</strong> If you
    177 use {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission, then you must
    178 also have the {@link android.Manifest.permission#BLUETOOTH} permission.</p> 
    179  
    180 <p>Declare the Bluetooth permission(s) in your application manifest file. For
    181 example:</p> 
    182  
    183 <pre> 
    184 &lt;manifest ... >
    185   &lt;uses-permission android:name="android.permission.BLUETOOTH" />
    186   ...
    187 &lt;/manifest>
    188 </pre> 
    189  
    190 <p>See the <a
    191 href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission></a> 
    192 reference for more information about declaring application permissions.</p> 
    193  
    194  
    195 <h2 id="SettingUp">Setting Up Bluetooth</h2> 
    196  
    197 <div class="figure" style="width:200px"> 
    198 <img src="{@docRoot}images/bt_enable_request.png" /> 
    199 <strong>Figure 1:</strong> The enabling Bluetooth dialog.
    200 </div> 
    201  
    202 <p>Before your application can communicate over Bluetooth, you need to verify
    203 that Bluetooth is supported on the device, and if so, ensure that it is enabled.</p> 
    204  
    205 <p>If Bluetooth is not supported, then you should gracefully disable any
    206 Bluetooth features. If Bluetooth is supported, but disabled, then you can request that the
    207 user enable Bluetooth without leaving your application. This setup is
    208 accomplished in two steps, using the {@link android.bluetooth.BluetoothAdapter}.</p> 
    209  
    210  
    211 <ol> 
    212 <li>Get the {@link android.bluetooth.BluetoothAdapter}
    213 <p>The {@link android.bluetooth.BluetoothAdapter} is required for any and all Bluetooth
    214 activity. To get the {@link android.bluetooth.BluetoothAdapter}, call the static {@link
    215 android.bluetooth.BluetoothAdapter#getDefaultAdapter()} method. This returns a
    216 {@link android.bluetooth.BluetoothAdapter} that represents the device's own
    217 Bluetooth adapter (the Bluetooth radio). There's one Bluetooth adapter for the
    218 entire system, and your application can interact with it using this object. If
    219 {@link android.bluetooth.BluetoothAdapter#getDefaultAdapter()} returns null,
    220 then the device does not support Bluetooth and your story ends here. For example:</p> 
    221 <pre> 
    222 BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    223 if (mBluetoothAdapter == null) {
    224     // Device does not support Bluetooth
    225 }
    226 </pre> 
    227 </li> 
    228  
    229 <li>Enable Bluetooth
    230 <p>Next, you need to ensure that Bluetooth is enabled. Call {@link
    231 android.bluetooth.BluetoothAdapter#isEnabled()} to check whether Bluetooth is
    232 currently enable. If this method returns false, then Bluetooth is disabled. To
    233 request that Bluetooth be enabled, call {@link
    234 android.app.Activity#startActivityForResult(Intent,int) startActivityForResult()}
    235 with the {@link android.bluetooth.BluetoothAdapter#ACTION_REQUEST_ENABLE} action Intent.
    236 This will issue a request to enable Bluetooth through the system settings (without
    237 stopping your application). For example:</p> 
    238 <pre> 
    239 if (!mBluetoothAdapter.isEnabled()) {
    240     Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    241     startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    242 }
    243 </pre> 
    244  
    245 <p>A dialog will appear requesting user permission to enable Bluetooth, as shown
    246 in Figure 1. If the user responds "Yes," the system will begin to enable Bluetooth
    247 and focus will return to your application once the process completes (or fails).</p> 
    248 
    249 <p>The {@code REQUEST_ENABLE_BT} constant passed to {@link
    250 android.app.Activity#startActivityForResult(Intent,int) startActivityForResult()} is a locally
    251 defined integer (which must be greater than 0), that the system passes back to you in your
    252 {@link
    253 android.app.Activity#onActivityResult(int,int,Intent) onActivityResult()} implementation as the
    254 <code>requestCode</code> parameter.</p>
    255 
    256 <p>If enabling Bluetooth succeeds, your activity receives the {@link
    257 android.app.Activity#RESULT_OK} result code in the {@link
    258 android.app.Activity#onActivityResult(int,int,Intent) onActivityResult()}
    259 callback. If Bluetooth was not enabled
    260 due to an error (or the user responded "No") then the result code is {@link
    261 android.app.Activity#RESULT_CANCELED}.</p>
    262 </li> 
    263 </ol> 
    264  
    265 <p>Optionally, your application can also listen for the
    266 {@link android.bluetooth.BluetoothAdapter#ACTION_STATE_CHANGED} broadcast Intent, which
    267 the system will broadcast whenever the Bluetooth state has changed. This broadcast contains
    268 the extra fields {@link android.bluetooth.BluetoothAdapter#EXTRA_STATE} and {@link
    269 android.bluetooth.BluetoothAdapter#EXTRA_PREVIOUS_STATE}, containing the new and old
    270 Bluetooth states, respectively. Possible values for these extra fields are
    271 {@link android.bluetooth.BluetoothAdapter#STATE_TURNING_ON}, {@link
    272 android.bluetooth.BluetoothAdapter#STATE_ON}, {@link
    273 android.bluetooth.BluetoothAdapter#STATE_TURNING_OFF}, and {@link
    274 android.bluetooth.BluetoothAdapter#STATE_OFF}. Listening for this
    275 broadcast can be useful to detect changes made to the Bluetooth state while your
    276 app is running.</p> 
    277  
    278 <p class="note"><strong>Tip:</strong> Enabling discoverability will automatically
    279 enable Bluetooth. If you plan to consistently enable device discoverability before
    280 performing Bluetooth activity, you can skip
    281 step 2 above. Read about <a href="#EnablingDiscoverability">enabling discoverability</a>,
    282 below.</p> 
    283  
    284  
    285 <h2 id="FindingDevices">Finding Devices</h2> 
    286  
    287 <p>Using the {@link android.bluetooth.BluetoothAdapter}, you can find remote Bluetooth
    288 devices either through device discovery or by querying the list of paired (bonded)
    289 devices.</p> 
    290  
    291 <p>Device discovery is a scanning procedure that searches the local area for
    292 Bluetooth enabled devices and then requesting some information about each one
    293 (this is sometimes referred to as "discovering," "inquiring" or "scanning").
    294 However, a Bluetooth device within the local area will respond to a discovery
    295 request only if it is currently enabled to be discoverable. If a device is
    296 discoverable, it will respond to the discovery request by sharing some
    297 information, such as the device name, class, and its unique MAC address. Using
    298 this information, the device performing discovery can then choose to initiate a
    299 connection to the discovered device.</p> 
    300  
    301 <p>Once a connection is made with a remote device for the first time, a pairing
    302 request is automatically presented to the user. When a device is
    303 paired, the basic information about that device (such as the device name, class,
    304 and MAC address) is saved and can be read using the Bluetooth APIs. Using the
    305 known MAC address for a remote device, a connection can be initiated with it at
    306 any time without performing discovery (assuming the device is within range).</p> 
    307  
    308 <p>Remember there is a difference between being paired and being connected. To
    309 be paired means that two devices are aware of each other's existence, have a
    310 shared link-key that can be used for authentication, and are capable of
    311 establishing an encrypted connection with each other. To be connected means that
    312 the devices currently share an RFCOMM channel and are able to transmit data with
    313 each other. The current Android Bluetooth API's require devices to be paired
    314 before an RFCOMM connection can be established. (Pairing is automatically performed
    315 when you initiate an encrypted connection with the Bluetooth APIs.)</p> 
    316  
    317 <p>The following sections describe how to find devices that have been paired, or
    318 discover new devices using device discovery.</p> 
    319  
    320 <p class="note"><strong>Note:</strong> Android-powered devices are not
    321 discoverable by default. A user can make
    322 the device discoverable for a limited time through the system settings, or an
    323 application can request that the user enable discoverability without leaving the
    324 application. How to <a href="#EnablingDiscoverability">enable discoverability</a> 
    325 is discussed below.</p> 
    326  
    327  
    328 <h3 id="QueryingPairedDevices">Querying paired devices</h3> 
    329  
    330 <p>Before performing device discovery, its worth querying the set
    331 of paired devices to see if the desired device is already known. To do so,
    332 call {@link android.bluetooth.BluetoothAdapter#getBondedDevices()}. This
    333 will return a Set of {@link android.bluetooth.BluetoothDevice}s representing
    334 paired devices. For example, you can query all paired devices and then
    335 show the name of each device to the user, using an ArrayAdapter:</p> 
    336 <pre> 
    337 Set&lt;BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    338 // If there are paired devices
    339 if (pairedDevices.size() > 0) {
    340     // Loop through paired devices
    341     for (BluetoothDevice device : pairedDevices) {
    342         // Add the name and address to an array adapter to show in a ListView
    343         mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
    344     }
    345 }
    346 </pre> 
    347  
    348 <p>All that's needed from the {@link android.bluetooth.BluetoothDevice} object
    349 in order to initiate a connection is the MAC address. In this example, it's saved
    350 as a part of an ArrayAdapter that's shown to the user. The MAC address can later
    351 be extracted in order to initiate the connection. You can learn more about creating
    352 a connection in the section about <a href="#ConnectingDevices">Connecting Devices</a>.</p> 
    353  
    354  
    355 <h3 id="DiscoveringDevices">Discovering devices</h3> 
    356  
    357 <p>To start discovering devices, simply call {@link
    358 android.bluetooth.BluetoothAdapter#startDiscovery()}. The
    359 process is asynchronous and the method will immediately return with a boolean
    360 indicating whether discovery has successfully started. The discovery process
    361 usually involves an inquiry scan of about 12 seconds, followed by a page scan of
    362 each found device to retrieve its Bluetooth name.</p> 
    363  
    364 <p>Your application must register a BroadcastReceiver for the
    365 {@link android.bluetooth.BluetoothDevice#ACTION_FOUND} Intent in
    366 order to receive information about each
    367 device discovered. For each device, the system will broadcast the
    368 {@link android.bluetooth.BluetoothDevice#ACTION_FOUND} Intent. This
    369 Intent carries the extra fields
    370 {@link android.bluetooth.BluetoothDevice#EXTRA_DEVICE} and
    371 {@link android.bluetooth.BluetoothDevice#EXTRA_CLASS}, containing a
    372 {@link android.bluetooth.BluetoothDevice} and a {@link
    373 android.bluetooth.BluetoothClass}, respectively. For example, here's how you can
    374 register to handle the broadcast when devices are discovered:</p> 
    375 <pre> 
    376 // Create a BroadcastReceiver for ACTION_FOUND
    377 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    378     public void onReceive(Context context, Intent intent) {
    379         String action = intent.getAction();
    380         // When discovery finds a device
    381         if (BluetoothDevice.ACTION_FOUND.equals(action)) {
    382             // Get the BluetoothDevice object from the Intent
    383             BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    384             // Add the name and address to an array adapter to show in a ListView
    385             mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
    386         }
    387     }
    388 };
    389 // Register the BroadcastReceiver
    390 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    391 registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
    392 </pre> 
    393  
    394 <p>All that's needed from the {@link android.bluetooth.BluetoothDevice} object
    395 in order to initiate a
    396 connection is the MAC address. In this example, it's saved as a part of an
    397 ArrayAdapter that's shown to the user. The MAC address can later be extracted in
    398 order to initiate the connection. You can learn more about creating a connection
    399 in the section about <a href="#ConnectingDevices">Connecting Devices</a>.</p> 
    400  
    401 <p class="caution"><strong>Caution:</strong> Performing device discovery is
    402 a heavy procedure for the Bluetooth
    403 adapter and will consume a lot of its resources. Once you have found a device to
    404 connect, be certain that you always stop discovery with
    405 {@link android.bluetooth.BluetoothAdapter#cancelDiscovery()} before
    406 attempting a connection. Also, if you
    407 already hold a connection with a device, then performing discovery can
    408 significantly reduce the bandwidth available for the connection, so you should
    409 not perform discovery while connected.</p> 
    410  
    411 <h4 id="EnablingDiscoverability">Enabling discoverability</h4> 
    412  
    413 <p>If you would like to make the local device discoverable to other devices,
    414 call {@link android.app.Activity#startActivityForResult(Intent,int)} with the
    415 {@link android.bluetooth.BluetoothAdapter#ACTION_REQUEST_DISCOVERABLE} action
    416 Intent. This will issue a request to enable discoverable mode through the system
    417 settings (without stopping your application). By default, the device will become
    418 discoverable for 120 seconds. You can define a different duration by adding the
    419 {@link android.bluetooth.BluetoothAdapter#EXTRA_DISCOVERABLE_DURATION} Intent
    420 extra. The maximum duration an app can set is 3600 seconds, and a value of 0
    421 means the device is always discoverable. Any value below 0 or above 3600 is
    422 automatically set to 120 secs). For example, this snippet sets the duration to
    423 300:</p> 
    424 
    425 <pre>Intent discoverableIntent = new
    426 Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    427 discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
    428 startActivity(discoverableIntent);
    429 </pre> 
    430  
    431 <div class="figure" style="width:200px"> 
    432 <img src="{@docRoot}images/bt_enable_discoverable.png" /> 
    433 <strong>Figure 2:</strong> The enabling discoverability dialog.
    434 </div> 
    435  
    436 <p>A dialog will be displayed, requesting user permission to make the device
    437 discoverable, as shown in Figure 2. If the user responds "Yes," then the device
    438 will become discoverable for the specified amount of time. Your activity will
    439 then receive a call to the {@link android.app.Activity#onActivityResult(int,int,Intent)
    440 onActivityResult())} callback, with the result code equal to the duration that the device
    441 is discoverable. If the user responded "No" or if an error occurred, the result code will
    442 be {@link android.app.Activity#RESULT_CANCELED}.</p> 
    443  
    444 <p class="note"><strong>Note:</strong> If Bluetooth has not been enabled on the device,
    445 then enabling device discoverability will automatically enable Bluetooth.</p> 
    446  
    447 <p>The device will silently remain in discoverable mode for the allotted time.
    448 If you would like to be notified when the discoverable mode has changed, you can
    449 register a BroadcastReceiver for the {@link
    450 android.bluetooth.BluetoothAdapter#ACTION_SCAN_MODE_CHANGED}
    451 Intent. This will contain the extra fields {@link
    452 android.bluetooth.BluetoothAdapter#EXTRA_SCAN_MODE} and
    453 {@link android.bluetooth.BluetoothAdapter#EXTRA_PREVIOUS_SCAN_MODE}, which tell you the
    454 new and old scan mode, respectively. Possible values for each are
    455 {@link android.bluetooth.BluetoothAdapter#SCAN_MODE_CONNECTABLE_DISCOVERABLE},
    456 {@link android.bluetooth.BluetoothAdapter#SCAN_MODE_CONNECTABLE}, or {@link
    457 android.bluetooth.BluetoothAdapter#SCAN_MODE_NONE},
    458 which indicate that the device is either in discoverable mode, not in
    459 discoverable mode but still able to receive connections, or not in discoverable
    460 mode and unable to receive connections, respectively.</p> 
    461  
    462 <p>You do not need to enable device discoverability if you will be initiating
    463 the connection to a remote device. Enabling discoverability is only necessary when
    464 you want your application to host a server socket that will accept incoming
    465 connections, because the remote devices must be able to discover the device
    466 before it can initiate the connection.</p> 
    467  
    468  
    469  
    470 <h2 id="ConnectingDevices">Connecting Devices</h2> 
    471  
    472 <p>In order to create a connection between your application on two devices, you
    473 must implement both the server-side and client-side mechanisms, because one
    474 device must open a server socket and the other one must initiate the connection
    475 (using the server device's MAC address to initiate a connection). The server and
    476 client are considered connected to each other when they each have a connected
    477 {@link android.bluetooth.BluetoothSocket} on the same RFCOMM channel. At this
    478 point, each device can obtain input and output streams and data transfer can
    479 begin, which is discussed in the section about <a
    480 href="#ManagingAConnection">Managing a Connection</a>. This section describes how
    481 to initiate the connection between two devices.</p> 
    482  
    483 <p>The server device and the client device each obtain the required {@link
    484 android.bluetooth.BluetoothSocket} in different ways. The server will receive it
    485 when an incoming connection is accepted. The client will receive it when it
    486 opens an RFCOMM channel to the server.</p> 
    487  
    488 <div class="figure" style="width:200px"> 
    489 <img src="{@docRoot}images/bt_pairing_request.png" /> 
    490 <strong>Figure 3:</strong> The Bluetooth pairing dialog.
    491 </div> 
    492  
    493 <p>One implementation technique is to automatically prepare each device as a
    494 server, so that each one has a server socket open and listening for connections.
    495 Then either device can initiate a connection with the other and become the
    496 client. Alternatively, one device can explicitly "host" the connection and open
    497 a server socket on demand and the other device can simply initiate the
    498 connection.</p> 
    499  
    500 <p class="note"><strong>Note:</strong> If the two devices have not been previously paired,
    501 then the Android framework will automatically show a pairing request notification or
    502 dialog to the user during the connection procedure, as shown in Figure 3. So
    503 when attempting to connect devices,
    504 your application does not need to be concerned about whether or not the devices are
    505 paired. Your RFCOMM connection attempt will block until the user has successfully paired,
    506 or will fail if the user rejects pairing, or if pairing fails or times out. </p> 
    507  
    508  
    509 <h3 id="ConnectingAsAServer">Connecting as a server</h3> 
    510  
    511 <p>When you want to connect two devices, one must act as a server by holding an
    512 open {@link android.bluetooth.BluetoothServerSocket}. The purpose of the server
    513 socket is to listen for incoming connection requests and when one is accepted,
    514 provide a connected {@link android.bluetooth.BluetoothSocket}. When the {@link
    515 android.bluetooth.BluetoothSocket} is acquired from the {@link
    516 android.bluetooth.BluetoothServerSocket},
    517 the {@link android.bluetooth.BluetoothServerSocket} can (and should) be
    518 discarded, unless you want to accept more connections.</p> 
    519  
    520 <div class="sidebox-wrapper"> 
    521 <div class="sidebox"> 
    522 <h2>About UUID</h2> 
    523  
    524 <p>A Universally Unique Identifier (UUID) is a standardized 128-bit format for a string
    525 ID used to uniquely identify information. The point of a UUID is that it's big
    526 enough that you can select any random and it won't clash. In this case, it's
    527 used to uniquely identify your application's Bluetooth service. To get a UUID to
    528 use with your application, you can use one of the many random UUID generators on
    529 the web, then initialize a {@link java.util.UUID} with {@link
    530 java.util.UUID#fromString(String)}.</p> 
    531 </div> 
    532 </div> 
    533  
    534 <p>Here's the basic procedure to set up a server socket and accept a
    535 connection:</p> 
    536  
    537 <ol> 
    538 <li>Get a {@link android.bluetooth.BluetoothServerSocket} by calling the
    539 {@link
    540 android.bluetooth.BluetoothAdapter#listenUsingRfcommWithServiceRecord(String,
    541 UUID)}.
    542 <p>The string is an identifiable name of your service, which the system will
    543 automatically write to a new Service Discovery Protocol (SDP) database entry on
    544 the device (the name is arbitrary and can simply be your application name). The
    545 UUID is also included in the SDP entry and will be the basis for the connection
    546 agreement with the client device. That is, when the client attempts to connect
    547 with this device, it will carry a UUID that uniquely identifies the service with
    548 which it wants to connect. These UUIDs must match in order for the connection to
    549 be accepted (in the next step).</p> 
    550 </li> 
    551  
    552 <li>Start listening for connection requests by calling
    553 {@link android.bluetooth.BluetoothServerSocket#accept()}.
    554 <p>This is a blocking call. It will return when either a connection has been
    555 accepted or an exception has occurred. A connection is accepted only when a
    556 remote device has sent a connection request with a UUID matching the one
    557 registered with this listening server socket. When successful, {@link
    558 android.bluetooth.BluetoothServerSocket#accept()} will
    559 return a connected {@link android.bluetooth.BluetoothSocket}.</p> 
    560 </li> 
    561  
    562 <li>Unless you want to accept additional connections, call
    563 {@link android.bluetooth.BluetoothServerSocket#close()}.
    564 <p>This releases the server socket and all its resources, but does <em>not</em> close the
    565 connected {@link android.bluetooth.BluetoothSocket} that's been returned by {@link
    566 android.bluetooth.BluetoothServerSocket#accept()}. Unlike TCP/IP, RFCOMM only allows one
    567 connected client per channel at a time, so in most cases it makes sense to call {@link
    568 android.bluetooth.BluetoothServerSocket#close()} on the {@link
    569 android.bluetooth.BluetoothServerSocket} immediately after accepting a connected
    570 socket.</p> 
    571 </li> 
    572 </ol> 
    573  
    574 <p>The {@link android.bluetooth.BluetoothServerSocket#accept()} call should not
    575 be executed in the main activity UI thread because it is a blocking call and
    576 will prevent any other interaction with the application. It usually makes
    577 sense to do all work with a {@link android.bluetooth.BluetoothServerSocket} or {@link
    578 android.bluetooth.BluetoothSocket} in a new
    579 thread managed by your application. To abort a blocked call such as {@link
    580 android.bluetooth.BluetoothServerSocket#accept()}, call {@link
    581 android.bluetooth.BluetoothServerSocket#close()} on the {@link
    582 android.bluetooth.BluetoothServerSocket} (or {@link
    583 android.bluetooth.BluetoothSocket}) from another thread and the blocked call will
    584 immediately return. Note that all methods on a {@link
    585 android.bluetooth.BluetoothServerSocket} or {@link android.bluetooth.BluetoothSocket}
    586 are thread-safe.</p> 
    587  
    588 <h4>Example</h4> 
    589  
    590 <p>Here's a simplified thread for the server component that accepts incoming
    591 connections:</p> 
    592 <pre> 
    593 private class AcceptThread extends Thread {
    594     private final BluetoothServerSocket mmServerSocket;
    595  
    596     public AcceptThread() {
    597         // Use a temporary object that is later assigned to mmServerSocket,
    598         // because mmServerSocket is final
    599         BluetoothServerSocket tmp = null;
    600         try {
    601             // MY_UUID is the app's UUID string, also used by the client code
    602             tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
    603         } catch (IOException e) { }
    604         mmServerSocket = tmp;
    605     }
    606  
    607     public void run() {
    608         BluetoothSocket socket = null;
    609         // Keep listening until exception occurs or a socket is returned
    610         while (true) {
    611             try {
    612                 socket = mmServerSocket.accept();
    613             } catch (IOException e) {
    614                 break;
    615             }
    616             // If a connection was accepted
    617             if (socket != null) {
    618                 // Do work to manage the connection (in a separate thread)
    619                 manageConnectedSocket(socket);
    620                 mmServerSocket.close();
    621                 break;
    622             }
    623         }
    624     }
    625  
    626     /** Will cancel the listening socket, and cause the thread to finish */
    627     public void cancel() {
    628         try {
    629             mmServerSocket.close();
    630         } catch (IOException e) { }
    631     }
    632 }
    633 </pre> 
    634  
    635 <p>In this example, only one incoming connection is desired, so as soon as a
    636 connection is accepted and the {@link android.bluetooth.BluetoothSocket} is
    637 acquired, the application
    638 sends the acquired {@link android.bluetooth.BluetoothSocket} to a separate
    639 thread, closes the
    640 {@link android.bluetooth.BluetoothServerSocket} and breaks the loop.</p> 
    641  
    642 <p>Note that when {@link android.bluetooth.BluetoothServerSocket#accept()}
    643 returns the {@link android.bluetooth.BluetoothSocket}, the socket is already
    644 connected, so you should <em>not</em> call {@link
    645 android.bluetooth.BluetoothSocket#connect()} (as you do from the
    646 client-side).</p> 
    647  
    648 <p><code>manageConnectedSocket()</code> is a fictional method in the application
    649 that will
    650 initiate the thread for transferring data, which is discussed in the section
    651 about <a href="#ManagingAConnection">Managing a Connection</a>.</p> 
    652  
    653 <p>You should usually close your {@link android.bluetooth.BluetoothServerSocket}
    654 as soon as you are done listening for incoming connections. In this example, {@link
    655 android.bluetooth.BluetoothServerSocket#close()} is called as soon
    656 as the {@link android.bluetooth.BluetoothSocket} is acquired. You may also want
    657 to provide a public method in your thread that can close the private {@link
    658 android.bluetooth.BluetoothSocket} in the event that you need to stop listening on the
    659 server socket.</p> 
    660  
    661  
    662 <h3 id="ConnectingAsAClient">Connecting as a client</h3> 
    663  
    664 <p>In order to initiate a connection with a remote device (a device holding an
    665 open
    666 server socket), you must first obtain a {@link
    667 android.bluetooth.BluetoothDevice} object that represents the remote device.
    668 (Getting a {@link android.bluetooth.BluetoothDevice} is covered in the above
    669 section about <a
    670 href="#FindingDevices">Finding Devices</a>.) You must then use the
    671 {@link android.bluetooth.BluetoothDevice} to acquire a {@link
    672 android.bluetooth.BluetoothSocket} and initiate the connection.</p> 
    673  
    674 <p>Here's the basic procedure:</p> 
    675  
    676 <ol> 
    677 <li>Using the {@link android.bluetooth.BluetoothDevice}, get a {@link
    678 android.bluetooth.BluetoothSocket} by calling {@link
    679 android.bluetooth.BluetoothDevice#createRfcommSocketToServiceRecord(UUID)}.
    680 <p>This initializes a {@link android.bluetooth.BluetoothSocket} that will
    681 connect to the {@link android.bluetooth.BluetoothDevice}. The UUID passed here
    682 must match the UUID used by the server device when it opened its
    683 {@link android.bluetooth.BluetoothServerSocket} (with {@link
    684 android.bluetooth.BluetoothAdapter#listenUsingRfcommWithServiceRecord(String,
    685 UUID)}). Using the same UUID is simply a matter of hard-coding the UUID string
    686 into your application and then referencing it from both the server and client
    687 code.</p> 
    688 </li> 
    689  
    690 <li>Initiate the connection by calling {@link
    691 android.bluetooth.BluetoothSocket#connect()}.
    692 <p>Upon this call, the system will perform an SDP lookup on the remote device in
    693 order to match the UUID. If the lookup is successful and the remote device
    694 accepts the connection, it will share the RFCOMM channel to use during the
    695 connection and {@link
    696 android.bluetooth.BluetoothSocket#connect()} will return. This method is a
    697 blocking call. If, for
    698 any reason, the connection fails or the {@link
    699 android.bluetooth.BluetoothSocket#connect()} method times out (after about
    700 12 seconds), then it will throw an exception.</p> 
    701 <p>Because {@link
    702 android.bluetooth.BluetoothSocket#connect()} is a blocking call, this connection
    703 procedure should always be performed in a thread separate from the main activity
    704 thread.</p> 
    705 <p class="note">Note: You should always ensure that the device is not performing
    706 device discovery when you call {@link
    707 android.bluetooth.BluetoothSocket#connect()}. If discovery is in progress, then
    708 the
    709 connection attempt will be significantly slowed and is more likely to fail.</p> 
    710 </li> 
    711 </ol> 
    712  
    713 <h4>Example</h4> 
    714  
    715 <p>Here is a basic example of a thread that initiates a Bluetooth
    716 connection:</p> 
    717 <pre> 
    718 private class ConnectThread extends Thread {
    719     private final BluetoothSocket mmSocket;
    720     private final BluetoothDevice mmDevice;
    721  
    722     public ConnectThread(BluetoothDevice device) {
    723         // Use a temporary object that is later assigned to mmSocket,
    724         // because mmSocket is final
    725         BluetoothSocket tmp = null;
    726         mmDevice = device;
    727  
    728         // Get a BluetoothSocket to connect with the given BluetoothDevice
    729         try {
    730             // MY_UUID is the app's UUID string, also used by the server code
    731             tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
    732         } catch (IOException e) { }
    733         mmSocket = tmp;
    734     }
    735  
    736     public void run() {
    737         // Cancel discovery because it will slow down the connection
    738         mBluetoothAdapter.cancelDiscovery();
    739  
    740         try {
    741             // Connect the device through the socket. This will block
    742             // until it succeeds or throws an exception
    743             mmSocket.connect();
    744         } catch (IOException connectException) {
    745             // Unable to connect; close the socket and get out
    746             try {
    747                 mmSocket.close();
    748             } catch (IOException closeException) { }
    749             return;
    750         }
    751  
    752         // Do work to manage the connection (in a separate thread)
    753         manageConnectedSocket(mmSocket);
    754     }
    755  
    756     /** Will cancel an in-progress connection, and close the socket */
    757     public void cancel() {
    758         try {
    759             mmSocket.close();
    760         } catch (IOException e) { }
    761     }
    762 }
    763 </pre> 
    764  
    765 <p>Notice that {@link android.bluetooth.BluetoothAdapter#cancelDiscovery()} is called
    766 before the connection is made. You should always do this before connecting and it is safe
    767 to call without actually checking whether it is running or not (but if you do want to
    768 check, call {@link android.bluetooth.BluetoothAdapter#isDiscovering()}).</p> 
    769  
    770 <p><code>manageConnectedSocket()</code> is a fictional method in the application
    771 that will initiate the thread for transferring data, which is discussed in the section
    772 about <a href="#ManagingAConnection">Managing a Connection</a>.</p> 
    773  
    774 <p>When you're done with your {@link android.bluetooth.BluetoothSocket}, always
    775 call {@link android.bluetooth.BluetoothSocket#close()} to clean up.
    776 Doing so will immediately close the connected socket and clean up all internal
    777 resources.</p> 
    778  
    779  
    780 <h2 id="ManagingAConnection">Managing a Connection</h2> 
    781  
    782 <p>When you have successfully connected two (or more) devices, each one will
    783 have a connected {@link android.bluetooth.BluetoothSocket}. This is where the fun
    784 begins because you can share data between devices. Using the {@link
    785 android.bluetooth.BluetoothSocket}, the general procedure to transfer arbitrary data is
    786 simple:</p> 
    787 <ol> 
    788 <li>Get the {@link java.io.InputStream} and {@link java.io.OutputStream} that
    789 handle transmissions through the socket, via {@link
    790 android.bluetooth.BluetoothSocket#getInputStream()} and
    791 {@link android.bluetooth.BluetoothSocket#getOutputStream}, respectively.</li> 
    792  
    793 <li>Read and write data to the streams with {@link
    794 java.io.InputStream#read(byte[])} and {@link java.io.OutputStream#write(byte[])}.</li> 
    795 </ol> 
    796  
    797 <p>That's it.</p> 
    798  
    799 <p>There are, of course, implementation details to consider. First and foremost,
    800 you should use a dedicated thread for all stream reading and writing. This is
    801 important because both {@link java.io.InputStream#read(byte[])} and {@link
    802 java.io.OutputStream#write(byte[])} methods are blocking calls. {@link
    803 java.io.InputStream#read(byte[])} will block until there is something to read
    804 from the stream. {@link java.io.OutputStream#write(byte[])} does not usually
    805 block, but can block for flow control if the remote device is not calling {@link
    806 java.io.InputStream#read(byte[])} quickly enough and the intermediate buffers are full.
    807 So, your main loop in the thread should be dedicated to reading from the {@link
    808 java.io.InputStream}. A separate public method in the thread can be used to initiate
    809 writes to the {@link java.io.OutputStream}.</p> 
    810  
    811 <h4>Example</h4> 
    812  
    813 <p>Here's an example of how this might look:</p> 
    814 <pre> 
    815 private class ConnectedThread extends Thread {
    816     private final BluetoothSocket mmSocket;
    817     private final InputStream mmInStream;
    818     private final OutputStream mmOutStream;
    819  
    820     public ConnectedThread(BluetoothSocket socket) {
    821         mmSocket = socket;
    822         InputStream tmpIn = null;
    823         OutputStream tmpOut = null;
    824  
    825         // Get the input and output streams, using temp objects because
    826         // member streams are final
    827         try {
    828             tmpIn = socket.getInputStream();
    829             tmpOut = socket.getOutputStream();
    830         } catch (IOException e) { }
    831  
    832         mmInStream = tmpIn;
    833         mmOutStream = tmpOut;
    834     }
    835  
    836     public void run() {
    837         byte[] buffer = new byte[1024];  // buffer store for the stream
    838         int bytes; // bytes returned from read()
    839  
    840         // Keep listening to the InputStream until an exception occurs
    841         while (true) {
    842             try {
    843                 // Read from the InputStream
    844                 bytes = mmInStream.read(buffer);
    845                 // Send the obtained bytes to the UI activity
    846                 mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
    847                         .sendToTarget();
    848             } catch (IOException e) {
    849                 break;
    850             }
    851         }
    852     }
    853  
    854     /* Call this from the main activity to send data to the remote device */
    855     public void write(byte[] bytes) {
    856         try {
    857             mmOutStream.write(bytes);
    858         } catch (IOException e) { }
    859     }
    860  
    861     /* Call this from the main activity to shutdown the connection */
    862     public void cancel() {
    863         try {
    864             mmSocket.close();
    865         } catch (IOException e) { }
    866     }
    867 }
    868 </pre> 
    869  
    870 <p>The constructor acquires the necessary streams and once executed, the thread
    871 will wait for data to come through the InputStream. When {@link
    872 java.io.InputStream#read(byte[])} returns with
    873 bytes from the stream, the data is sent to the main activity using a member
    874 Handler from the parent class. Then it goes back and waits for more bytes from
    875 the stream.</p> 
    876  
    877 <p>Sending outgoing data is as simple as calling the thread's
    878 <code>write()</code> method from the main activity and passing in the bytes to
    879 be sent. This method then simply calls {@link
    880 java.io.OutputStream#write(byte[])} to send the data to the remote device.</p> 
    881  
    882 <p>The thread's <code>cancel()</code> method is important so that the connection
    883 can be
    884 terminated at any time by closing the {@link android.bluetooth.BluetoothSocket}.
    885 This should always be called when you're done using the Bluetooth
    886 connection.</p> 
    887  
    888 <div class="special"> 
    889 <p>For a  demonstration of using the Bluetooth APIs, see the <a
    890 href="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat sample app</a>.</p> 
    891 </div> 
    892 
    893 <h2 id="Profiles">Working with Profiles</h2> 
    894 
    895 <p>Starting in Android 3.0, the Bluetooth API includes support for working with
    896 Bluetooth profiles. A <em>Bluetooth profile</em> is a wireless interface
    897 specification for Bluetooth-based communication between devices. An example
    898 is the Hands-Free profile. For a mobile phone to connect to a wireless headset,
    899 both devices must support the Hands-Free profile. </p> 
    900 
    901 <p>You can implement the interface {@link android.bluetooth.BluetoothProfile} to write
    902 your own classes to support a particular Bluetooth profile. The Android
    903 Bluetooth API provides implementations for the following Bluetooth
    904 profiles:</p> 
    905 <ul> 
    906 
    907   <li><strong>Headset</strong>. The Headset profile provides support for
    908 Bluetooth headsets to be used with mobile phones. Android provides the {@link
    909 android.bluetooth.BluetoothHeadset} class, which is a proxy for controlling the
    910 Bluetooth Headset Service via interprocess communication (<a
    911 href="{@docRoot}guide/components/processes-and-threads.html#IPC">IPC</a
    912 >). This includes both  Bluetooth Headset and Hands-Free (v1.5) profiles. The
    913 {@link android.bluetooth.BluetoothHeadset} class includes support for AT commands.
    914 For more discussion of this topic, see <a href="#AT-Commands">Vendor-specific AT commands</a></li>
    915 
    916   <li><strong>A2DP</strong>. The Advanced Audio Distribution Profile (A2DP)
    917 profile defines how high quality audio can be streamed from one device to
    918 another over a Bluetooth connection. Android provides the {@link
    919 android.bluetooth.BluetoothA2dp} class, which is a proxy for controlling
    920 the Bluetooth A2DP  Service via IPC.</li> 
    921 
    922  <li><strong>Health Device</strong>. Android 4.0 (API level 14) introduces
    923 support for the Bluetooth Health Device Profile (HDP). This lets you create
    924 applications that use Bluetooth to communicate with health devices that support
    925 Bluetooth, such as heart-rate monitors, blood meters, thermometers, scales, and
    926 so on. For a list of supported devices and their corresponding device data
    927 specialization codes, refer to <strong>Bluetooth Assigned Numbers</strong> at <a
    928 href="http://www.bluetooth.org">www.bluetooth.org</a>. Note that these values
    929 are also referenced in the ISO/IEEE 11073-20601 [7] specification as
    930 MDC_DEV_SPEC_PROFILE_* in the Nomenclature Codes Annex. For more discussion of
    931 HDP, see <a href="#HDP">Health Device Profile</a>.</li> 
    932 
    933 </ul> 
    934 
    935 <p>Here are the basic steps for working with a profile:</p> 
    936 <ol> 
    937 
    938   <li>Get the default adapter, as described in
    939     <a href="{@docRoot}guide/topics/connectivity/bluetooth.html#SettingUp">Setting Up
    940       Bluetooth</a>.</li> 
    941 
    942   <li>Use {@link
    943 android.bluetooth.BluetoothAdapter#getProfileProxy(android.content.Context,
    944 android.bluetooth.BluetoothProfile.ServiceListener, int) getProfileProxy()} to
    945 establish a connection to the profile proxy object associated with the profile.
    946 In the example below, the profile proxy object is an instance of {@link
    947 android.bluetooth.BluetoothHeadset}. </li> 
    948 
    949   <li>Set up a  {@link android.bluetooth.BluetoothProfile.ServiceListener}. This
    950 listener notifies {@link android.bluetooth.BluetoothProfile} IPC clients when
    951 they have been connected to or disconnected from the service.</li> 
    952 
    953   <li>In {@link
    954 android.bluetooth.BluetoothProfile.ServiceListener#onServiceConnected(int,
    955 android.bluetooth.BluetoothProfile) onServiceConnected()}, get a handle
    956 to the profile proxy object.</li> 
    957 
    958   <li>Once you have the profile proxy object, you can use it to monitor the
    959 state of the connection and perform other operations that are relevant to that
    960 profile.</li> 
    961 </ol> 
    962 
    963 <p> For example, this code snippet shows how to connect to a {@link
    964 android.bluetooth.BluetoothHeadset} proxy object so that you can control the
    965 Headset profile:</p> 
    966 
    967 <pre>BluetoothHeadset mBluetoothHeadset;
    968  
    969 // Get the default adapter
    970 BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    971  
    972 // Establish connection to the proxy.
    973 mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
    974  
    975 private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
    976     public void onServiceConnected(int profile, BluetoothProfile proxy) {
    977         if (profile == BluetoothProfile.HEADSET) {
    978             mBluetoothHeadset = (BluetoothHeadset) proxy;
    979         }
    980     }
    981     public void onServiceDisconnected(int profile) {
    982         if (profile == BluetoothProfile.HEADSET) {
    983             mBluetoothHeadset = null;
    984         }
    985     }
    986 };
    987  
    988 // ... call functions on mBluetoothHeadset
    989  
    990 // Close proxy connection after use.
    991 mBluetoothAdapter.closeProfileProxy(mBluetoothHeadset);
    992 </pre> 
    993 
    994 
    995 
    996 <h3 id="AT-Commands">Vendor-specific AT commands</h3> 
    997 
    998 <p>Starting in Android 3.0, applications can register to receive system
    999 broadcasts of pre-defined vendor-specific AT commands sent by headsets (such as
   1000 a Plantronics +XEVENT command). For example, an application could receive
   1001 broadcasts that indicate a connected device's battery level and could notify the
   1002 user or take other action as needed. Create a broadcast receiver for the {@link
   1003 android.bluetooth.BluetoothHeadset#ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intent
   1004 to handle vendor-specific AT commands for the headset.</p>
   1005 
   1006 <h3 id="HDP">Health Device Profile</h3>
   1007 
   1008 <p>Android 4.0 (API level 14) introduces support for the Bluetooth Health Device
   1009 Profile (HDP). This lets you create applications that use Bluetooth to
   1010 communicate with health devices that support Bluetooth, such as heart-rate
   1011 monitors, blood meters, thermometers, and scales. The Bluetooth Health API
   1012 includes the classes {@link android.bluetooth.BluetoothHealth}, {@link
   1013 android.bluetooth.BluetoothHealthCallback}, and {@link
   1014 android.bluetooth.BluetoothHealthAppConfiguration}, which are described in <a
   1015 href="#TheBasics">The Basics</a>. </p>
   1016 
   1017 <p>In using the Bluetooth Health API, it's helpful to understand these key HDP concepts:</p>
   1018 <table>
   1019   <tr>
   1020     <th>Concept</th>
   1021     <th>Description</th>
   1022   </tr>
   1023   <tr>
   1024     <td><strong>Source</strong></td>
   1025 
   1026     <td>A role defined in HDP. A <em>source</em> is a  health device that
   1027 transmits medical data (weight scale, glucose meter, thermometer, etc.) to a
   1028 smart device such as an Android phone or tablet. </td>
   1029   </tr>
   1030   <tr>
   1031     <td><strong>Sink</strong></td>
   1032 
   1033     <td>A role defined in HDP. In HDP, a <em>sink</em> is the smart device that
   1034 receives the medical data. In an Android HDP application, the sink is
   1035 represented by a {@link android.bluetooth.BluetoothHealthAppConfiguration}
   1036 object.</td>
   1037   </tr>
   1038   <tr>
   1039     <td><strong>Registration</strong></td>
   1040     <td>Refers to registering a sink for a particular health device.</td>
   1041   </tr>
   1042   <tr>
   1043     <td><strong>Connection</strong></td>
   1044 
   1045     <td>Refers to opening a channel between a health device and a smart device
   1046 such as an Android phone or tablet.</td>
   1047   </tr>
   1048 </table>
   1049 
   1050 <h4>Creating an HDP Application</h4>
   1051 
   1052 <p>Here are the basic steps involved in creating an Android HDP application:</p>
   1053 <ol>
   1054 
   1055   <li>Get a reference to the {@link android.bluetooth.BluetoothHealth} proxy
   1056 object. <p>Similar to regular headset and A2DP profile devices, you must call
   1057 {@link android.bluetooth.BluetoothAdapter#getProfileProxy getProfileProxy()}
   1058 with a {@link android.bluetooth.BluetoothProfile.ServiceListener} and the {@link
   1059 android.bluetooth.BluetoothProfile.ServiceListener#HEALTH} profile type to
   1060 establish a connection with the profile proxy object.</p> </li>
   1061 
   1062   <li>Create a {@link android.bluetooth.BluetoothHealthCallback} and register an
   1063 application configuration 
   1064 ({@link android.bluetooth.BluetoothHealthAppConfiguration})
   1065 that acts as a health
   1066 sink.</li>
   1067 
   1068   <li>Establish a connection to a health device.  Some devices will initiate the
   1069 connection.  It is unnecessary to carry out this step for those devices.</li>
   1070 
   1071   <li>When connected successfully to a health device, read/write to the health
   1072 device using the file descriptor. <p>The received data needs to be interpreted
   1073 using a health manager which implements the IEEE 11073-xxxxx
   1074 specifications.</p></li>
   1075 
   1076   <li>When done, close the health channel and unregister the application.  The
   1077 channel also closes when there is extended inactivity.</li>
   1078 </ol>
   1079 
   1080 <p>For a complete code sample that illustrates these steps, see <a
   1081 href="{@docRoot}resources/samples/BluetoothHDP/index.html">Bluetooth HDP (Health
   1082 Device Profile)</a>. </p>
   1083