1page.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 10other 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, 55which allows a device to wirelessly exchange data with other Bluetooth devices. 56The application framework provides access to the Bluetooth functionality through 57the Android Bluetooth APIs. These APIs let applications wirelessly 58connect to other Bluetooth devices, enabling point-to-point and multipoint 59wireless features.</p> 60 61<p>Using the Bluetooth APIs, an Android application can perform the 62following:</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 76the four major tasks necessary to communicate using Bluetooth: setting up 77Bluetooth, finding devices that are either paired or available in the local 78area, connecting devices, and transferring data between devices.</p> 79 80<p>All of the Bluetooth APIs are available in the {@link android.bluetooth} 81package. Here's a summary of the classes and interfaces you will need to create Bluetooth 82connections:</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 88interaction. Using this, 89you can discover other Bluetooth devices, query a list of bonded (paired) 90devices, instantiate a {@link android.bluetooth.BluetoothDevice} using a known 91MAC address, and create a {@link android.bluetooth.BluetoothServerSocket} to 92listen for communications 93from other devices.</dd> 94 95<dt>{@link android.bluetooth.BluetoothDevice}</dt> 96<dd>Represents a remote Bluetooth device. Use this to request a connection 97with a remote device through a {@link android.bluetooth.BluetoothSocket} or 98query information about the 99device 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 104an application to exchange data with another Bluetooth device via InputStream 105and 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 110Android devices, one device must open a server socket with this class. When a 111remote Bluetooth device makes a connection request to the this device, the 112{@link android.bluetooth.BluetoothServerSocket} will return a connected {@link 113android.bluetooth.BluetoothSocket} when the 114connection is accepted.</dd> 115 116<dt>{@link android.bluetooth.BluetoothClass}</dt> 117<dd>Describes the general characteristics and capabilities of a Bluetooth 118device. This is a read-only set of properties that define the device's major and 119minor device classes and its services. However, this does not reliably describe 120all Bluetooth profiles and services supported by the device, but is useful as a 121hint to the device type.</dd> 122 123<dt>{@link android.bluetooth.BluetoothProfile}</dt> <dd>An interface that 124represents a Bluetooth profile. A <em>Bluetooth profile</em> is a wireless 125interface specification for Bluetooth-based communication between devices. An 126example is the Hands-Free profile. For more discussion of profiles, see <a 127href="#Profiles">Working with Profiles</a></dd> 128 129<dt>{@link android.bluetooth.BluetoothHeadset}</dt> <dd>Provides support for 130Bluetooth headsets to be used with mobile phones. This includes both Bluetooth 131Headset and Hands-Free (v1.5) profiles.</dd> 132 133<dt>{@link android.bluetooth.BluetoothA2dp}</dt> <dd> Defines how high quality 134audio 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 143android.bluetooth.BluetoothHealth} callbacks. You must extend this class and 144implement the callback methods to receive updates about changes in the 145application’s 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 150application registers to communicate with a remote Bluetooth health 151device.</dd> 152 153<dt>{@link android.bluetooth.BluetoothProfile.ServiceListener}</dt> 154 155<dd>An interface that notifies {@link android.bluetooth.BluetoothProfile} IPC 156clients when they have been connected to or disconnected from the service (that 157is, 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 167at least one of two Bluetooth permissions: {@link 168android.Manifest.permission#BLUETOOTH} and {@link 169android.Manifest.permission#BLUETOOTH_ADMIN}.</p> 170 171<p>You must request the {@link android.Manifest.permission#BLUETOOTH} permission 172in order to perform any Bluetooth communication, such as requesting a 173connection, accepting a connection, and transferring data.</p> 174 175<p>You must request the {@link android.Manifest.permission#BLUETOOTH_ADMIN} 176permission in order to initiate device discovery or manipulate Bluetooth 177settings. Most applications need this permission solely for the 178ability to discover local Bluetooth devices. The other abilities granted by this 179permission should not be used, unless the application is a "power manager" that 180will modify Bluetooth settings upon user request. <strong>Note:</strong> If you 181use {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission, then must 182also have the {@link android.Manifest.permission#BLUETOOTH} permission.</p> 183 184<p>Declare the Bluetooth permission(s) in your application manifest file. For 185example:</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 195href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a> 196reference 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 207that 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 210Bluetooth features. If Bluetooth is supported, but disabled, then you can request that the 211user enable Bluetooth without leaving your application. This setup is 212accomplished 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 218activity. To get the {@link android.bluetooth.BluetoothAdapter}, call the static {@link 219android.bluetooth.BluetoothAdapter#getDefaultAdapter()} method. This returns a 220{@link android.bluetooth.BluetoothAdapter} that represents the device's own 221Bluetooth adapter (the Bluetooth radio). There's one Bluetooth adapter for the 222entire system, and your application can interact with it using this object. If 223{@link android.bluetooth.BluetoothAdapter#getDefaultAdapter()} returns null, 224then the device does not support Bluetooth and your story ends here. For example:</p> 225<pre> 226BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 227if (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 235android.bluetooth.BluetoothAdapter#isEnabled()} to check whether Bluetooth is 236currently enable. If this method returns false, then Bluetooth is disabled. To 237request that Bluetooth be enabled, call {@link 238android.app.Activity#startActivityForResult(Intent,int) startActivityForResult()} 239with the {@link android.bluetooth.BluetoothAdapter#ACTION_REQUEST_ENABLE} action Intent. 240This will issue a request to enable Bluetooth through the system settings (without 241stopping your application). For example:</p> 242<pre> 243if (!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 250in Figure 1. If the user responds "Yes," the system will begin to enable Bluetooth 251and 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 254android.app.Activity#startActivityForResult(Intent,int) startActivityForResult()} is a locally 255defined integer (which must be greater than 0), that the system passes back to you in your 256{@link 257android.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 261android.app.Activity#RESULT_OK} result code in the {@link 262android.app.Activity#onActivityResult(int,int,Intent) onActivityResult()} 263callback. If Bluetooth was not enabled 264due to an error (or the user responded "No") then the result code is {@link 265android.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 271the system will broadcast whenever the Bluetooth state has changed. This broadcast contains 272the extra fields {@link android.bluetooth.BluetoothAdapter#EXTRA_STATE} and {@link 273android.bluetooth.BluetoothAdapter#EXTRA_PREVIOUS_STATE}, containing the new and old 274Bluetooth states, respectively. Possible values for these extra fields are 275{@link android.bluetooth.BluetoothAdapter#STATE_TURNING_ON}, {@link 276android.bluetooth.BluetoothAdapter#STATE_ON}, {@link 277android.bluetooth.BluetoothAdapter#STATE_TURNING_OFF}, and {@link 278android.bluetooth.BluetoothAdapter#STATE_OFF}. Listening for this 279broadcast can be useful to detect changes made to the Bluetooth state while your 280app is running.</p> 281 282<p class="note"><strong>Tip:</strong> Enabling discoverability will automatically 283enable Bluetooth. If you plan to consistently enable device discoverability before 284performing Bluetooth activity, you can skip 285step 2 above. Read about <a href="#EnablingDiscoverability">enabling discoverability</a>, 286below.</p> 287 288 289<h2 id="FindingDevices">Finding Devices</h2> 290 291<p>Using the {@link android.bluetooth.BluetoothAdapter}, you can find remote Bluetooth 292devices either through device discovery or by querying the list of paired (bonded) 293devices.</p> 294 295<p>Device discovery is a scanning procedure that searches the local area for 296Bluetooth enabled devices and then requesting some information about each one 297(this is sometimes referred to as "discovering," "inquiring" or "scanning"). 298However, a Bluetooth device within the local area will respond to a discovery 299request only if it is currently enabled to be discoverable. If a device is 300discoverable, it will respond to the discovery request by sharing some 301information, such as the device name, class, and its unique MAC address. Using 302this information, the device performing discovery can then choose to initiate a 303connection to the discovered device.</p> 304 305<p>Once a connection is made with a remote device for the first time, a pairing 306request is automatically presented to the user. When a device is 307paired, the basic information about that device (such as the device name, class, 308and MAC address) is saved and can be read using the Bluetooth APIs. Using the 309known MAC address for a remote device, a connection can be initiated with it at 310any 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 313be paired means that two devices are aware of each other's existence, have a 314shared link-key that can be used for authentication, and are capable of 315establishing an encrypted connection with each other. To be connected means that 316the devices currently share an RFCOMM channel and are able to transmit data with 317each other. The current Android Bluetooth API's require devices to be paired 318before an RFCOMM connection can be established. (Pairing is automatically performed 319when 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 322discover new devices using device discovery.</p> 323 324<p class="note"><strong>Note:</strong> Android-powered devices are not 325discoverable by default. A user can make 326the device discoverable for a limited time through the system settings, or an 327application can request that the user enable discoverability without leaving the 328application. How to <a href="#EnablingDiscoverability">enable discoverability</a> 329is 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 335of paired devices to see if the desired device is already known. To do so, 336call {@link android.bluetooth.BluetoothAdapter#getBondedDevices()}. This 337will return a Set of {@link android.bluetooth.BluetoothDevice}s representing 338paired devices. For example, you can query all paired devices and then 339show the name of each device to the user, using an ArrayAdapter:</p> 340<pre> 341Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); 342// If there are paired devices 343if (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 353in order to initiate a connection is the MAC address. In this example, it's saved 354as a part of an ArrayAdapter that's shown to the user. The MAC address can later 355be extracted in order to initiate the connection. You can learn more about creating 356a 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 362android.bluetooth.BluetoothAdapter#startDiscovery()}. The 363process is asynchronous and the method will immediately return with a boolean 364indicating whether discovery has successfully started. The discovery process 365usually involves an inquiry scan of about 12 seconds, followed by a page scan of 366each 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 370order to receive information about each 371device discovered. For each device, the system will broadcast the 372{@link android.bluetooth.BluetoothDevice#ACTION_FOUND} Intent. This 373Intent 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 377android.bluetooth.BluetoothClass}, respectively. For example, here's how you can 378register to handle the broadcast when devices are discovered:</p> 379<pre> 380// Create a BroadcastReceiver for ACTION_FOUND 381private 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 394IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 395registerReceiver(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 399in order to initiate a 400connection is the MAC address. In this example, it's saved as a part of an 401ArrayAdapter that's shown to the user. The MAC address can later be extracted in 402order to initiate the connection. You can learn more about creating a connection 403in the section about <a href="#ConnectingDevices">Connecting Devices</a>.</p> 404 405<p class="caution"><strong>Caution:</strong> Performing device discovery is 406a heavy procedure for the Bluetooth 407adapter and will consume a lot of its resources. Once you have found a device to 408connect, be certain that you always stop discovery with 409{@link android.bluetooth.BluetoothAdapter#cancelDiscovery()} before 410attempting a connection. Also, if you 411already hold a connection with a device, then performing discovery can 412significantly reduce the bandwidth available for the connection, so you should 413not 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, 418call {@link android.app.Activity#startActivityForResult(Intent,int)} with the 419{@link android.bluetooth.BluetoothAdapter#ACTION_REQUEST_DISCOVERABLE} action 420Intent. This will issue a request to enable discoverable mode through the system 421settings (without stopping your application). By default, the device will become 422discoverable for 120 seconds. You can define a different duration by adding the 423{@link android.bluetooth.BluetoothAdapter#EXTRA_DISCOVERABLE_DURATION} Intent 424extra. The maximum duration an app can set is 3600 seconds, and a value of 0 425means the device is always discoverable. Any value below 0 or above 3600 is 426automatically set to 120 secs). For example, this snippet sets the duration to 427300:</p> 428 429<pre>Intent discoverableIntent = new 430Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); 431discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); 432startActivity(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 441discoverable, as shown in Figure 2. If the user responds "Yes," then the device 442will become discoverable for the specified amount of time. Your activity will 443then receive a call to the {@link android.app.Activity#onActivityResult(int,int,Intent) 444onActivityResult())} callback, with the result code equal to the duration that the device 445is discoverable. If the user responded "No" or if an error occurred, the result code will 446be {@link android.app.Activity#RESULT_CANCELED}.</p> 447 448<p class="note"><strong>Note:</strong> If Bluetooth has not been enabled on the device, 449then enabling device discoverability will automatically enable Bluetooth.</p> 450 451<p>The device will silently remain in discoverable mode for the allotted time. 452If you would like to be notified when the discoverable mode has changed, you can 453register a BroadcastReceiver for the {@link 454android.bluetooth.BluetoothAdapter#ACTION_SCAN_MODE_CHANGED} 455Intent. This will contain the extra fields {@link 456android.bluetooth.BluetoothAdapter#EXTRA_SCAN_MODE} and 457{@link android.bluetooth.BluetoothAdapter#EXTRA_PREVIOUS_SCAN_MODE}, which tell you the 458new 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 461android.bluetooth.BluetoothAdapter#SCAN_MODE_NONE}, 462which indicate that the device is either in discoverable mode, not in 463discoverable mode but still able to receive connections, or not in discoverable 464mode and unable to receive connections, respectively.</p> 465 466<p>You do not need to enable device discoverability if you will be initiating 467the connection to a remote device. Enabling discoverability is only necessary when 468you want your application to host a server socket that will accept incoming 469connections, because the remote devices must be able to discover the device 470before 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 477must implement both the server-side and client-side mechanisms, because one 478device 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 480client are considered connected to each other when they each have a connected 481{@link android.bluetooth.BluetoothSocket} on the same RFCOMM channel. At this 482point, each device can obtain input and output streams and data transfer can 483begin, which is discussed in the section about <a 484href="#ManagingAConnection">Managing a Connection</a>. This section describes how 485to initiate the connection between two devices.</p> 486 487<p>The server device and the client device each obtain the required {@link 488android.bluetooth.BluetoothSocket} in different ways. The server will receive it 489when an incoming connection is accepted. The client will receive it when it 490opens 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 498server, so that each one has a server socket open and listening for connections. 499Then either device can initiate a connection with the other and become the 500client. Alternatively, one device can explicitly "host" the connection and open 501a server socket on demand and the other device can simply initiate the 502connection.</p> 503 504<p class="note"><strong>Note:</strong> If the two devices have not been previously paired, 505then the Android framework will automatically show a pairing request notification or 506dialog to the user during the connection procedure, as shown in Figure 3. So 507when attempting to connect devices, 508your application does not need to be concerned about whether or not the devices are 509paired. Your RFCOMM connection attempt will block until the user has successfully paired, 510or 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 516open {@link android.bluetooth.BluetoothServerSocket}. The purpose of the server 517socket is to listen for incoming connection requests and when one is accepted, 518provide a connected {@link android.bluetooth.BluetoothSocket}. When the {@link 519android.bluetooth.BluetoothSocket} is acquired from the {@link 520android.bluetooth.BluetoothServerSocket}, 521the {@link android.bluetooth.BluetoothServerSocket} can (and should) be 522discarded, 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 529ID used to uniquely identify information. The point of a UUID is that it's big 530enough that you can select any random and it won't clash. In this case, it's 531used to uniquely identify your application's Bluetooth service. To get a UUID to 532use with your application, you can use one of the many random UUID generators on 533the web, then initialize a {@link java.util.UUID} with {@link 534java.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 539connection:</p> 540 541<ol> 542<li>Get a {@link android.bluetooth.BluetoothServerSocket} by calling the 543{@link 544android.bluetooth.BluetoothAdapter#listenUsingRfcommWithServiceRecord(String, 545UUID)}. 546<p>The string is an identifiable name of your service, which the system will 547automatically write to a new Service Discovery Protocol (SDP) database entry on 548the device (the name is arbitrary and can simply be your application name). The 549UUID is also included in the SDP entry and will be the basis for the connection 550agreement with the client device. That is, when the client attempts to connect 551with this device, it will carry a UUID that uniquely identifies the service with 552which it wants to connect. These UUIDs must match in order for the connection to 553be 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 559accepted or an exception has occurred. A connection is accepted only when a 560remote device has sent a connection request with a UUID matching the one 561registered with this listening server socket. When successful, {@link 562android.bluetooth.BluetoothServerSocket#accept()} will 563return 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 569connected {@link android.bluetooth.BluetoothSocket} that's been returned by {@link 570android.bluetooth.BluetoothServerSocket#accept()}. Unlike TCP/IP, RFCOMM only allows one 571connected client per channel at a time, so in most cases it makes sense to call {@link 572android.bluetooth.BluetoothServerSocket#close()} on the {@link 573android.bluetooth.BluetoothServerSocket} immediately after accepting a connected 574socket.</p> 575</li> 576</ol> 577 578<p>The {@link android.bluetooth.BluetoothServerSocket#accept()} call should not 579be executed in the main activity UI thread because it is a blocking call and 580will prevent any other interaction with the application. It usually makes 581sense to do all work with a {@link android.bluetooth.BluetoothServerSocket} or {@link 582android.bluetooth.BluetoothSocket} in a new 583thread managed by your application. To abort a blocked call such as {@link 584android.bluetooth.BluetoothServerSocket#accept()}, call {@link 585android.bluetooth.BluetoothServerSocket#close()} on the {@link 586android.bluetooth.BluetoothServerSocket} (or {@link 587android.bluetooth.BluetoothSocket}) from another thread and the blocked call will 588immediately return. Note that all methods on a {@link 589android.bluetooth.BluetoothServerSocket} or {@link android.bluetooth.BluetoothSocket} 590are thread-safe.</p> 591 592<h4>Example</h4> 593 594<p>Here's a simplified thread for the server component that accepts incoming 595connections:</p> 596<pre> 597private 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 640connection is accepted and the {@link android.bluetooth.BluetoothSocket} is 641acquired, the application 642sends the acquired {@link android.bluetooth.BluetoothSocket} to a separate 643thread, closes the 644{@link android.bluetooth.BluetoothServerSocket} and breaks the loop.</p> 645 646<p>Note that when {@link android.bluetooth.BluetoothServerSocket#accept()} 647returns the {@link android.bluetooth.BluetoothSocket}, the socket is already 648connected, so you should <em>not</em> call {@link 649android.bluetooth.BluetoothSocket#connect()} (as you do from the 650client-side).</p> 651 652<p><code>manageConnectedSocket()</code> is a fictional method in the application 653that will 654initiate the thread for transferring data, which is discussed in the section 655about <a href="#ManagingAConnection">Managing a Connection</a>.</p> 656 657<p>You should usually close your {@link android.bluetooth.BluetoothServerSocket} 658as soon as you are done listening for incoming connections. In this example, {@link 659android.bluetooth.BluetoothServerSocket#close()} is called as soon 660as the {@link android.bluetooth.BluetoothSocket} is acquired. You may also want 661to provide a public method in your thread that can close the private {@link 662android.bluetooth.BluetoothSocket} in the event that you need to stop listening on the 663server 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 669open 670server socket), you must first obtain a {@link 671android.bluetooth.BluetoothDevice} object that represents the remote device. 672(Getting a {@link android.bluetooth.BluetoothDevice} is covered in the above 673section about <a 674href="#FindingDevices">Finding Devices</a>.) You must then use the 675{@link android.bluetooth.BluetoothDevice} to acquire a {@link 676android.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 682android.bluetooth.BluetoothSocket} by calling {@link 683android.bluetooth.BluetoothDevice#createRfcommSocketToServiceRecord(UUID)}. 684<p>This initializes a {@link android.bluetooth.BluetoothSocket} that will 685connect to the {@link android.bluetooth.BluetoothDevice}. The UUID passed here 686must match the UUID used by the server device when it opened its 687{@link android.bluetooth.BluetoothServerSocket} (with {@link 688android.bluetooth.BluetoothAdapter#listenUsingRfcommWithServiceRecord(String, 689UUID)}). Using the same UUID is simply a matter of hard-coding the UUID string 690into your application and then referencing it from both the server and client 691code.</p> 692</li> 693 694<li>Initiate the connection by calling {@link 695android.bluetooth.BluetoothSocket#connect()}. 696<p>Upon this call, the system will perform an SDP lookup on the remote device in 697order to match the UUID. If the lookup is successful and the remote device 698accepts the connection, it will share the RFCOMM channel to use during the 699connection and {@link 700android.bluetooth.BluetoothSocket#connect()} will return. This method is a 701blocking call. If, for 702any reason, the connection fails or the {@link 703android.bluetooth.BluetoothSocket#connect()} method times out (after about 70412 seconds), then it will throw an exception.</p> 705<p>Because {@link 706android.bluetooth.BluetoothSocket#connect()} is a blocking call, this connection 707procedure should always be performed in a thread separate from the main activity 708thread.</p> 709<p class="note">Note: You should always ensure that the device is not performing 710device discovery when you call {@link 711android.bluetooth.BluetoothSocket#connect()}. If discovery is in progress, then 712the 713connection 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 720connection:</p> 721<pre> 722private 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 770before the connection is made. You should always do this before connecting and it is safe 771to call without actually checking whether it is running or not (but if you do want to 772check, call {@link android.bluetooth.BluetoothAdapter#isDiscovering()}).</p> 773 774<p><code>manageConnectedSocket()</code> is a fictional method in the application 775that will initiate the thread for transferring data, which is discussed in the section 776about <a href="#ManagingAConnection">Managing a Connection</a>.</p> 777 778<p>When you're done with your {@link android.bluetooth.BluetoothSocket}, always 779call {@link android.bluetooth.BluetoothSocket#close()} to clean up. 780Doing so will immediately close the connected socket and clean up all internal 781resources.</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 787have a connected {@link android.bluetooth.BluetoothSocket}. This is where the fun 788begins because you can share data between devices. Using the {@link 789android.bluetooth.BluetoothSocket}, the general procedure to transfer arbitrary data is 790simple:</p> 791<ol> 792<li>Get the {@link java.io.InputStream} and {@link java.io.OutputStream} that 793handle transmissions through the socket, via {@link 794android.bluetooth.BluetoothSocket#getInputStream()} and 795{@link android.bluetooth.BluetoothSocket#getOutputStream}, respectively.</li> 796 797<li>Read and write data to the streams with {@link 798java.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, 804you should use a dedicated thread for all stream reading and writing. This is 805important because both {@link java.io.InputStream#read(byte[])} and {@link 806java.io.OutputStream#write(byte[])} methods are blocking calls. {@link 807java.io.InputStream#read(byte[])} will block until there is something to read 808from the stream. {@link java.io.OutputStream#write(byte[])} does not usually 809block, but can block for flow control if the remote device is not calling {@link 810java.io.InputStream#read(byte[])} quickly enough and the intermediate buffers are full. 811So, your main loop in the thread should be dedicated to reading from the {@link 812java.io.InputStream}. A separate public method in the thread can be used to initiate 813writes 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> 819private 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 875will wait for data to come through the InputStream. When {@link 876java.io.InputStream#read(byte[])} returns with 877bytes from the stream, the data is sent to the main activity using a member 878Handler from the parent class. Then it goes back and waits for more bytes from 879the 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 883be sent. This method then simply calls {@link 884java.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 887can be 888terminated at any time by closing the {@link android.bluetooth.BluetoothSocket}. 889This should always be called when you're done using the Bluetooth 890connection.</p> 891 892<div class="special"> 893<p>For a demonstration of using the Bluetooth APIs, see the <a 894href="{@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 900Bluetooth profiles. A <em>Bluetooth profile</em> is a wireless interface 901specification for Bluetooth-based communication between devices. An example 902is the Hands-Free profile. For a mobile phone to connect to a wireless headset, 903both devices must support the Hands-Free profile. </p> 904 905<p>You can implement the interface {@link android.bluetooth.BluetoothProfile} to write 906your own classes to support a particular Bluetooth profile. The Android 907Bluetooth API provides implementations for the following Bluetooth 908profiles:</p> 909<ul> 910 911 <li><strong>Headset</strong>. The Headset profile provides support for 912Bluetooth headsets to be used with mobile phones. Android provides the {@link 913android.bluetooth.BluetoothHeadset} class, which is a proxy for controlling the 914Bluetooth Headset Service via interprocess communication (<a 915href="{@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. 918For 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) 921profile defines how high quality audio can be streamed from one device to 922another over a Bluetooth connection. Android provides the {@link 923android.bluetooth.BluetoothA2dp} class, which is a proxy for controlling 924the Bluetooth A2DP Service via IPC.</li> 925 926 <li><strong>Health Device</strong>. Android 4.0 (API level 14) introduces 927support for the Bluetooth Health Device Profile (HDP). This lets you create 928applications that use Bluetooth to communicate with health devices that support 929Bluetooth, such as heart-rate monitors, blood meters, thermometers, scales, and 930so on. For a list of supported devices and their corresponding device data 931specialization codes, refer to <strong>Bluetooth Assigned Numbers</strong> at <a 932href="http://www.bluetooth.org">www.bluetooth.org</a>. Note that these values 933are also referenced in the ISO/IEEE 11073-20601 [7] specification as 934MDC_DEV_SPEC_PROFILE_* in the Nomenclature Codes Annex. For more discussion of 935HDP, 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 947android.bluetooth.BluetoothAdapter#getProfileProxy(android.content.Context, 948android.bluetooth.BluetoothProfile.ServiceListener, int) getProfileProxy()} to 949establish a connection to the profile proxy object associated with the profile. 950In the example below, the profile proxy object is an instance of {@link 951android.bluetooth.BluetoothHeadset}. </li> 952 953 <li>Set up a {@link android.bluetooth.BluetoothProfile.ServiceListener}. This 954listener notifies {@link android.bluetooth.BluetoothProfile} IPC clients when 955they have been connected to or disconnected from the service.</li> 956 957 <li>In {@link 958android.bluetooth.BluetoothProfile.ServiceListener#onServiceConnected(int, 959android.bluetooth.BluetoothProfile) onServiceConnected()}, get a handle 960to the profile proxy object.</li> 961 962 <li>Once you have the profile proxy object, you can use it to monitor the 963state of the connection and perform other operations that are relevant to that 964profile.</li> 965</ol> 966 967<p> For example, this code snippet shows how to connect to a {@link 968android.bluetooth.BluetoothHeadset} proxy object so that you can control the 969Headset profile:</p> 970 971<pre>BluetoothHeadset mBluetoothHeadset; 972 973// Get the default adapter 974BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 975 976// Establish connection to the proxy. 977mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET); 978 979private 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. 995mBluetoothAdapter.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 1003broadcasts of pre-defined vendor-specific AT commands sent by headsets (such as 1004a Plantronics +XEVENT command). For example, an application could receive 1005broadcasts that indicate a connected device's battery level and could notify the 1006user or take other action as needed. Create a broadcast receiver for the {@link 1007android.bluetooth.BluetoothHeadset#ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intent 1008to 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 1013Profile (HDP). This lets you create applications that use Bluetooth to 1014communicate with health devices that support Bluetooth, such as heart-rate 1015monitors, blood meters, thermometers, and scales. The Bluetooth Health API 1016includes the classes {@link android.bluetooth.BluetoothHealth}, {@link 1017android.bluetooth.BluetoothHealthCallback}, and {@link 1018android.bluetooth.BluetoothHealthAppConfiguration}, which are described in <a 1019href="#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 1031transmits medical data (weight scale, glucose meter, thermometer, etc.) to a 1032smart 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 1038receives the medical data. In an Android HDP application, the sink is 1039represented by a {@link android.bluetooth.BluetoothHealthAppConfiguration} 1040object.</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 1050such 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 1060object. <p>Similar to regular headset and A2DP profile devices, you must call 1061{@link android.bluetooth.BluetoothAdapter#getProfileProxy getProfileProxy()} 1062with a {@link android.bluetooth.BluetoothProfile.ServiceListener} and the {@link 1063android.bluetooth.BluetoothProfile.ServiceListener#HEALTH} profile type to 1064establish a connection with the profile proxy object.</p> </li> 1065 1066 <li>Create a {@link android.bluetooth.BluetoothHealthCallback} and register an 1067application configuration 1068({@link android.bluetooth.BluetoothHealthAppConfiguration}) 1069that acts as a health 1070sink.</li> 1071 1072 <li>Establish a connection to a health device. Some devices will initiate the 1073connection. 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 1076device using the file descriptor. <p>The received data needs to be interpreted 1077using a health manager which implements the IEEE 11073-xxxxx 1078specifications.</p></li> 1079 1080 <li>When done, close the health channel and unregister the application. The 1081channel also closes when there is extended inactivity.</li> 1082</ol> 1083 1084<p>For a complete code sample that illustrates these steps, see <a 1085href="{@docRoot}resources/samples/BluetoothHDP/index.html">Bluetooth HDP (Health 1086Device Profile)</a>. </p> 1087