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 <manifest ... > 189 <uses-permission android:name="android.permission.BLUETOOTH" /> 190 ... 191 </manifest> 192 </pre> 193 194 <p>See the <a 195 href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><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<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