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