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