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