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> 22 <ol><li><a href="#EnablingDiscoverability">Enabling 23 discoverability</a></li></ol> 24 </li> 25 </ol> 26 </li> 27 <li><a href="#ConnectingDevices">Connecting Devices</a> 28 <ol> 29 <li><a href="#ConnectingAsAServer">Connecting as a server</a></li> 30 <li><a href="#ConnectingAsAClient">Connecting as a client</a></li> 31 </ol> 32 </li> 33 <li><a href="#ManagingAConnection">Managing a Connection</a></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 </ol> 48 49</div> 50</div> 51 52 53<p>The Android platform includes support for the Bluetooth network stack, 54which allows a device to wirelessly exchange data with other Bluetooth devices. 55The application framework provides access to the Bluetooth functionality through 56the Android Bluetooth APIs. These APIs let applications wirelessly 57connect to other Bluetooth devices, enabling point-to-point and multipoint 58wireless features.</p> 59 60<p>Using the Bluetooth APIs, an Android application can perform the 61following:</p> 62<ul> 63 <li>Scan for other Bluetooth devices</li> 64 <li>Query the local Bluetooth adapter for paired Bluetooth devices</li> 65 <li>Establish RFCOMM channels</li> 66 <li>Connect to other devices through service discovery</li> 67 <li>Transfer data to and from other devices</li> 68 <li>Manage multiple connections</li> 69</ul> 70 71 72<h2 id="TheBasics">The Basics</h2> 73 74<p>This document describes how to us the Android Bluetooth APIs to accomplish 75the four major tasks necessary to communicate using Bluetooth: setting up 76Bluetooth, finding devices that are either paired or available in the local 77area, connecting devices, and transferring data between devices.</p> 78 79<p>All of the Bluetooth APIs are available in the {@link android.bluetooth} 80package. Here's a summary of the classes you will need to create Bluetooth 81connections:</p> 82 83<dl> 84<dt>{@link android.bluetooth.BluetoothAdapter}</dt> 85<dd>Represents the local Bluetooth adapter (Bluetooth radio). The 86{@link android.bluetooth.BluetoothAdapter} is the entry-point for all Bluetooth 87interaction. Using this, 88you can discover other Bluetooth devices, query a list of bonded (paired) 89devices, instantiate a {@link android.bluetooth.BluetoothDevice} using a known 90MAC address, and create a {@link android.bluetooth.BluetoothServerSocket} to 91listen for communications 92from other devices.</dd> 93 94<dt>{@link android.bluetooth.BluetoothDevice}</dt> 95<dd>Represents a remote Bluetooth device. Use this to request a connection 96with a remote device through a {@link android.bluetooth.BluetoothSocket} or 97query information about the 98device such as its name, address, class, and bonding state.</dd> 99 100<dt>{@link android.bluetooth.BluetoothSocket}</dt> 101<dd>Represents the interface for a Bluetooth socket (similar to a TCP 102{@link java.net.Socket}). This is the connection point that allows 103an application to exchange data with another Bluetooth device via InputStream 104and OutputStream.</dd> 105 106<dt>{@link android.bluetooth.BluetoothServerSocket}</dt> 107<dd>Represents an open server socket that listens for incoming requests 108(similar to a TCP {@link java.net.ServerSocket}). In order to connect two 109Android devices, one device must open a server socket with this class. When a 110remote Bluetooth device makes a connection request to the this device, the 111{@link android.bluetooth.BluetoothServerSocket} will return a connected {@link 112android.bluetooth.BluetoothSocket} when the 113connection is accepted.</dd> 114 115<dt>{@link android.bluetooth.BluetoothClass}</dt> 116<dd>Describes the general characteristics and capabilities of a Bluetooth 117device. This is a read-only set of properties that define the device's major and 118minor device classes and its services. However, this does not reliably describe 119all Bluetooth profiles and services supported by the device, but is useful as a 120hint to the device type.</dd> 121</dl> 122 123 124 125 126<h2 id="Permissions">Bluetooth Permissions</h2> 127 128<p>In order to use Bluetooth features in your application, you need to declare 129at least one of two Bluetooth permissions: {@link 130android.Manifest.permission#BLUETOOTH} and {@link 131android.Manifest.permission#BLUETOOTH_ADMIN}.</p> 132 133<p>You must request the {@link android.Manifest.permission#BLUETOOTH} permission 134in order to perform any Bluetooth communication, such as requesting a 135connection, accepting a connection, and transferring data.</p> 136 137<p>You must request the {@link android.Manifest.permission#BLUETOOTH_ADMIN} 138permission in order to initiate device discovery or manipulate Bluetooth 139settings. Most applications need this permission solely for the 140ability to discover local Bluetooth devices. The other abilities granted by this 141permission should not be used, unless the application is a "power manager" that 142will modify Bluetooth settings upon user request. <strong>Note:</strong> If you 143use {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission, then must 144also have the {@link android.Manifest.permission#BLUETOOTH} permission.</p> 145 146<p>Declare the Bluetooth permission(s) in your application manifest file. For 147example:</p> 148 149<pre> 150<manifest ... > 151 <uses-permission android:name="android.permission.BLUETOOTH" /> 152 ... 153</manifest> 154</pre> 155 156<p>See the <a 157href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a> 158reference for more information about declaring application permissions.</p> 159 160 161<h2 id="SettingUp">Setting Up Bluetooth</h2> 162 163<div class="figure" style="width:200px"> 164<img src="{@docRoot}images/bt_enable_request.png" /> 165<strong>Figure 1:</strong> The enabling Bluetooth dialog. 166</div> 167 168<p>Before your application can communicate over Bluetooth, you need to verify 169that Bluetooth is supported on the device, and if so, ensure that it is enabled.</p> 170 171<p>If Bluetooth is not supported, then you should gracefully disable any 172Bluetooth features. If Bluetooth is supported, but disabled, then you can request that the 173user enable Bluetooth without leaving your application. This setup is 174accomplished in two steps, using the {@link android.bluetooth.BluetoothAdapter}.</p> 175 176 177<ol> 178<li>Get the {@link android.bluetooth.BluetoothAdapter} 179<p>The {@link android.bluetooth.BluetoothAdapter} is required for any and all Bluetooth 180activity. To get the {@link android.bluetooth.BluetoothAdapter}, call the static {@link 181android.bluetooth.BluetoothAdapter#getDefaultAdapter()} method. This returns a 182{@link android.bluetooth.BluetoothAdapter} that represents the device's own 183Bluetooth adapter (the Bluetooth radio). There's one Bluetooth adapter for the 184entire system, and your application can interact with it using this object. If 185{@link android.bluetooth.BluetoothAdapter#getDefaultAdapter()} returns null, 186then the device does not support Bluetooth and your story ends here. For example:</p> 187<pre> 188BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 189if (mBluetoothAdapter == null) { 190 // Device does not support Bluetooth 191} 192</pre> 193</li> 194 195<li>Enable Bluetooth 196<p>Next, you need to ensure that Bluetooth is enabled. Call {@link 197android.bluetooth.BluetoothAdapter#isEnabled()} to check whether Bluetooth is 198currently enable. If this method returns false, then Bluetooth is disabled. To 199request that Bluetooth be enabled, call {@link 200android.app.Activity#startActivityForResult(Intent,int) startActivityForResult()} 201with the {@link android.bluetooth.BluetoothAdapter#ACTION_REQUEST_ENABLE} action Intent. 202This will issue a request to enable Bluetooth through the system settings (without 203stopping your application). For example:</p> 204<pre> 205if (!mBluetoothAdapter.isEnabled()) { 206 Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 207 startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 208} 209</pre> 210 211<p>A dialog will appear requesting user permission to enable Bluetooth, as shown 212in Figure 1. If the user responds "Yes," the system will begin to enable Bluetooth 213and focus will return to your application once the process completes (or fails).</p> 214<p>If enabling Bluetooth succeeds, your Activity will receive the {@link 215android.app.Activity#RESULT_OK} result code in the {@link 216android.app.Activity#onActivityResult(int,int,Intent) onActivityResult()} 217callback. If Bluetooth was not enabled 218due to an error (or the user responded "No") then the result code will be {@link 219android.app.Activity#RESULT_CANCELED}.</p> 220</li> 221</ol> 222 223<p>Optionally, your application can also listen for the 224{@link android.bluetooth.BluetoothAdapter#ACTION_STATE_CHANGED} broadcast Intent, which 225the system will broadcast whenever the Bluetooth state has changed. This broadcast contains 226the extra fields {@link android.bluetooth.BluetoothAdapter#EXTRA_STATE} and {@link 227android.bluetooth.BluetoothAdapter#EXTRA_PREVIOUS_STATE}, containing the new and old 228Bluetooth states, respectively. Possible values for these extra fields are 229{@link android.bluetooth.BluetoothAdapter#STATE_TURNING_ON}, {@link 230android.bluetooth.BluetoothAdapter#STATE_ON}, {@link 231android.bluetooth.BluetoothAdapter#STATE_TURNING_OFF}, and {@link 232android.bluetooth.BluetoothAdapter#STATE_OFF}. Listening for this 233broadcast can be useful to detect changes made to the Bluetooth state while your 234app is running.</p> 235 236<p class="note"><strong>Tip:</strong> Enabling discoverability will automatically 237enable Bluetooth. If you plan to consistently enable device discoverability before 238performing Bluetooth activity, you can skip 239step 2 above. Read about <a href="#EnablingDiscoverability">enabling discoverability</a>, 240below.</p> 241 242 243<h2 id="FindingDevices">Finding Devices</h2> 244 245<p>Using the {@link android.bluetooth.BluetoothAdapter}, you can find remote Bluetooth 246devices either through device discovery or by querying the list of paired (bonded) 247devices.</p> 248 249<p>Device discovery is a scanning procedure that searches the local area for 250Bluetooth enabled devices and then requesting some information about each one 251(this is sometimes referred to as "discovering," "inquiring" or "scanning"). 252However, a Bluetooth device within the local area will respond to a discovery 253request only if it is currently enabled to be discoverable. If a device is 254discoverable, it will respond to the discovery request by sharing some 255information, such as the device name, class, and its unique MAC address. Using 256this information, the device performing discovery can then choose to initiate a 257connection to the discovered device.</p> 258 259<p>Once a connection is made with a remote device for the first time, a pairing 260request is automatically presented to the user. When a device is 261paired, the basic information about that device (such as the device name, class, 262and MAC address) is saved and can be read using the Bluetooth APIs. Using the 263known MAC address for a remote device, a connection can be initiated with it at 264any time without performing discovery (assuming the device is within range).</p> 265 266<p>Remember there is a difference between being paired and being connected. To 267be paired means that two devices are aware of each other's existence, have a 268shared link-key that can be used for authentication, and are capable of 269establishing an encrypted connection with each other. To be connected means that 270the devices currently share an RFCOMM channel and are able to transmit data with 271each other. The current Android Bluetooth API's require devices to be paired 272before an RFCOMM connection can be established. (Pairing is automatically performed 273when you initiate an encrypted connection with the Bluetooth APIs.)</p> 274 275<p>The following sections describe how to find devices that have been paired, or 276discover new devices using device discovery.</p> 277 278<p class="note"><strong>Note:</strong> Android-powered devices are not 279discoverable by default. A user can make 280the device discoverable for a limited time through the system settings, or an 281application can request that the user enable discoverability without leaving the 282application. How to <a href="#EnablingDiscoverability">enable discoverability</a> 283is discussed below.</p> 284 285 286<h3 id="QueryingPairedDevices">Querying paired devices</h3> 287 288<p>Before performing device discovery, its worth querying the set 289of paired devices to see if the desired device is already known. To do so, 290call {@link android.bluetooth.BluetoothAdapter#getBondedDevices()}. This 291will return a Set of {@link android.bluetooth.BluetoothDevice}s representing 292paired devices. For example, you can query all paired devices and then 293show the name of each device to the user, using an ArrayAdapter:</p> 294<pre> 295Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); 296// If there are paired devices 297if (pairedDevices.size() > 0) { 298 // Loop through paired devices 299 for (BluetoothDevice device : pairedDevices) { 300 // Add the name and address to an array adapter to show in a ListView 301 mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); 302 } 303} 304</pre> 305 306<p>All that's needed from the {@link android.bluetooth.BluetoothDevice} object 307in order to initiate a connection is the MAC address. In this example, it's saved 308as a part of an ArrayAdapter that's shown to the user. The MAC address can later 309be extracted in order to initiate the connection. You can learn more about creating 310a connection in the section about <a href="#ConnectingDevices">Connecting Devices</a>.</p> 311 312 313<h3 id="DiscoveringDevices">Discovering devices</h3> 314 315<p>To start discovering devices, simply call {@link 316android.bluetooth.BluetoothAdapter#startDiscovery()}. The 317process is asynchronous and the method will immediately return with a boolean 318indicating whether discovery has successfully started. The discovery process 319usually involves an inquiry scan of about 12 seconds, followed by a page scan of 320each found device to retrieve its Bluetooth name.</p> 321 322<p>Your application must register a BroadcastReceiver for the 323{@link android.bluetooth.BluetoothDevice#ACTION_FOUND} Intent in 324order to receive information about each 325device discovered. For each device, the system will broadcast the 326{@link android.bluetooth.BluetoothDevice#ACTION_FOUND} Intent. This 327Intent carries the extra fields 328{@link android.bluetooth.BluetoothDevice#EXTRA_DEVICE} and 329{@link android.bluetooth.BluetoothDevice#EXTRA_CLASS}, containing a 330{@link android.bluetooth.BluetoothDevice} and a {@link 331android.bluetooth.BluetoothClass}, respectively. For example, here's how you can 332register to handle the broadcast when devices are discovered:</p> 333<pre> 334// Create a BroadcastReceiver for ACTION_FOUND 335private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 336 public void onReceive(Context context, Intent intent) { 337 String action = intent.getAction(); 338 // When discovery finds a device 339 if (BluetoothDevice.ACTION_FOUND.equals(action)) { 340 // Get the BluetoothDevice object from the Intent 341 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 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}; 347// Register the BroadcastReceiver 348IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 349registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy 350</pre> 351 352<p>All that's needed from the {@link android.bluetooth.BluetoothDevice} object 353in order to initiate a 354connection is the MAC address. In this example, it's saved as a part of an 355ArrayAdapter that's shown to the user. The MAC address can later be extracted in 356order to initiate the connection. You can learn more about creating a connection 357in the section about <a href="#ConnectingDevices">Connecting Devices</a>.</p> 358 359<p class="caution"><strong>Caution:</strong> Performing device discovery is 360a heavy procedure for the Bluetooth 361adapter and will consume a lot of its resources. Once you have found a device to 362connect, be certain that you always stop discovery with 363{@link android.bluetooth.BluetoothAdapter#cancelDiscovery()} before 364attempting a connection. Also, if you 365already hold a connection with a device, then performing discovery can 366significantly reduce the bandwidth available for the connection, so you should 367not perform discovery while connected.</p> 368 369<h4 id="EnablingDiscoverability">Enabling discoverability</h4> 370 371<p>If you would like to make the local device discoverable to other devices, 372call {@link android.app.Activity#startActivityForResult(Intent,int)} with the 373{@link android.bluetooth.BluetoothAdapter#ACTION_REQUEST_DISCOVERABLE} action Intent. 374This will issue a request to enable discoverable mode through the system settings (without 375stopping your application). By default, the device will become discoverable for 376120 seconds. You can define a different duration by adding the 377{@link android.bluetooth.BluetoothAdapter#EXTRA_DISCOVERABLE_DURATION} Intent extra 378(maximum duration is 300 seconds). For example:</p> 379<pre> 380Intent discoverableIntent = new 381Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); 382discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); 383startActivity(discoverableIntent); 384</pre> 385 386<div class="figure" style="width:200px"> 387<img src="{@docRoot}images/bt_enable_discoverable.png" /> 388<strong>Figure 2:</strong> The enabling discoverability dialog. 389</div> 390 391<p>A dialog will be displayed, requesting user permission to make the device 392discoverable, as shown in Figure 2. If the user responds "Yes," then the device 393will become discoverable for the specified amount of time. Your Activity will 394then receive a call to the {@link android.app.Activity#onActivityResult(int,int,Intent) 395onActivityResult())} callback, with the result code equal to the duration that the device 396is discoverable. If the user responded "No" or if an error occurred, the result code will 397be Activity.RESULT_CANCELLED.</p> 398 399<p class="note"><strong>Note:</strong> If Bluetooth has not been enabled on the device, 400then enabling device discoverability will automatically enable Bluetooth.</p> 401 402<p>The device will silently remain in discoverable mode for the allotted time. 403If you would like to be notified when the discoverable mode has changed, you can 404register a BroadcastReceiver for the {@link 405android.bluetooth.BluetoothAdapter#ACTION_SCAN_MODE_CHANGED} 406Intent. This will contain the extra fields {@link 407android.bluetooth.BluetoothAdapter#EXTRA_SCAN_MODE} and 408{@link android.bluetooth.BluetoothAdapter#EXTRA_PREVIOUS_SCAN_MODE}, which tell you the 409new and old scan mode, respectively. Possible values for each are 410{@link android.bluetooth.BluetoothAdapter#SCAN_MODE_CONNECTABLE_DISCOVERABLE}, 411{@link android.bluetooth.BluetoothAdapter#SCAN_MODE_CONNECTABLE}, or {@link 412android.bluetooth.BluetoothAdapter#SCAN_MODE_NONE}, 413which indicate that the device is either in discoverable mode, not in 414discoverable mode but still able to receive connections, or not in discoverable 415mode and unable to receive connections, respectively.</p> 416 417<p>You do not need to enable device discoverability if you will be initiating 418the connection to a remote device. Enabling discoverability is only necessary when 419you want your application to host a server socket that will accept incoming 420connections, because the remote devices must be able to discover the device 421before it can initiate the connection.</p> 422 423 424 425<h2 id="ConnectingDevices">Connecting Devices</h2> 426 427<p>In order to create a connection between your application on two devices, you 428must implement both the server-side and client-side mechanisms, because one 429device must open a server socket and the other one must initiate the connection 430(using the server device's MAC address to initiate a connection). The server and 431client are considered connected to each other when they each have a connected 432{@link android.bluetooth.BluetoothSocket} on the same RFCOMM channel. At this 433point, each device can obtain input and output streams and data transfer can 434begin, which is discussed in the section about <a 435href="#ManagingAConnection">Managing a Connection</a>. This section describes how 436to initiate the connection between two devices.</p> 437 438<p>The server device and the client device each obtain the required {@link 439android.bluetooth.BluetoothSocket} in different ways. The server will receive it 440when an incoming connection is accepted. The client will receive it when it 441opens an RFCOMM channel to the server.</p> 442 443<div class="figure" style="width:200px"> 444<img src="{@docRoot}images/bt_pairing_request.png" /> 445<strong>Figure 3:</strong> The Bluetooth pairing dialog. 446</div> 447 448<p>One implementation technique is to automatically prepare each device as a 449server, so that each one has a server socket open and listening for connections. 450Then either device can initiate a connection with the other and become the 451client. Alternatively, one device can explicitly "host" the connection and open 452a server socket on demand and the other device can simply initiate the 453connection.</p> 454 455<p class="note"><strong>Note:</strong> If the two devices have not been previously paired, 456then the Android framework will automatically show a pairing request notification or 457dialog to the user during the connection procedure, as shown in Figure 3. So 458when attempting to connect devices, 459your application does not need to be concerned about whether or not the devices are 460paired. Your RFCOMM connection attempt will block until the user has successfully paired, 461or will fail if the user rejects pairing, or if pairing fails or times out. </p> 462 463 464<h3 id="ConnectingAsAServer">Connecting as a server</h3> 465 466<p>When you want to connect two devices, one must act as a server by holding an 467open {@link android.bluetooth.BluetoothServerSocket}. The purpose of the server 468socket is to listen for incoming connection requests and when one is accepted, 469provide a connected {@link android.bluetooth.BluetoothSocket}. When the {@link 470android.bluetooth.BluetoothSocket} is acquired from the {@link 471android.bluetooth.BluetoothServerSocket}, 472the {@link android.bluetooth.BluetoothServerSocket} can (and should) be 473discarded, unless you want to accept more connections.</p> 474 475<div class="sidebox-wrapper"> 476<div class="sidebox"> 477<h2>About UUID</h2> 478 479<p>A Universally Unique Identifier (UUID) is a standardized 128-bit format for a string 480ID used to uniquely identify information. The point of a UUID is that it's big 481enough that you can select any random and it won't clash. In this case, it's 482used to uniquely identify your application's Bluetooth service. To get a UUID to 483use with your application, you can use one of the many random UUID generators on 484the web, then initialize a {@link java.util.UUID} with {@link 485java.util.UUID#fromString(String)}.</p> 486</div> 487</div> 488 489<p>Here's the basic procedure to set up a server socket and accept a 490connection:</p> 491 492<ol> 493<li>Get a {@link android.bluetooth.BluetoothServerSocket} by calling the 494{@link 495android.bluetooth.BluetoothAdapter#listenUsingRfcommWithServiceRecord(String, 496UUID)}. 497<p>The string is an identifiable name of your service, which the system will 498automatically write to a new Service Discovery Protocol (SDP) database entry on 499the device (the name is arbitrary and can simply be your application name). The 500UUID is also included in the SDP entry and will be the basis for the connection 501agreement with the client device. That is, when the client attempts to connect 502with this device, it will carry a UUID that uniquely identifies the service with 503which it wants to connect. These UUIDs must match in order for the connection to 504be accepted (in the next step).</p> 505</li> 506 507<li>Start listening for connection requests by calling 508{@link android.bluetooth.BluetoothServerSocket#accept()}. 509<p>This is a blocking call. It will return when either a connection has been 510accepted or an exception has occurred. A connection is accepted only when a 511remote device has sent a connection request with a UUID matching the one 512registered with this listening server socket. When successful, {@link 513android.bluetooth.BluetoothServerSocket#accept()} will 514return a connected {@link android.bluetooth.BluetoothSocket}.</p> 515</li> 516 517<li>Unless you want to accept additional connections, call 518{@link android.bluetooth.BluetoothServerSocket#close()}. 519<p>This releases the server socket and all its resources, but does <em>not</em> close the 520connected {@link android.bluetooth.BluetoothSocket} that's been returned by {@link 521android.bluetooth.BluetoothServerSocket#accept()}. Unlike TCP/IP, RFCOMM only allows one 522connected client per channel at a time, so in most cases it makes sense to call {@link 523android.bluetooth.BluetoothServerSocket#close()} on the {@link 524android.bluetooth.BluetoothServerSocket} immediately after accepting a connected 525socket.</p> 526</li> 527</ol> 528 529<p>The {@link android.bluetooth.BluetoothServerSocket#accept()} call should not 530be executed in the main Activity UI thread because it is a blocking call and 531will prevent any other interaction with the application. It usually makes 532sense to do all work with a {@link android.bluetooth.BluetoothServerSocket} or {@link 533android.bluetooth.BluetoothSocket} in a new 534thread managed by your application. To abort a blocked call such as {@link 535android.bluetooth.BluetoothServerSocket#accept()}, call {@link 536android.bluetooth.BluetoothServerSocket#close()} on the {@link 537android.bluetooth.BluetoothServerSocket} (or {@link 538android.bluetooth.BluetoothSocket}) from another thread and the blocked call will 539immediately return. Note that all methods on a {@link 540android.bluetooth.BluetoothServerSocket} or {@link android.bluetooth.BluetoothSocket} 541are thread-safe.</p> 542 543<h4>Example</h4> 544 545<p>Here's a simplified thread for the server component that accepts incoming 546connections:</p> 547<pre> 548private class AcceptThread extends Thread { 549 private final BluetoothServerSocket mmServerSocket; 550 551 public AcceptThread() { 552 // Use a temporary object that is later assigned to mmServerSocket, 553 // because mmServerSocket is final 554 BluetoothServerSocket tmp = null; 555 try { 556 // MY_UUID is the app's UUID string, also used by the client code 557 tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID); 558 } catch (IOException e) { } 559 mmServerSocket = tmp; 560 } 561 562 public void run() { 563 BluetoothSocket socket = null; 564 // Keep listening until exception occurs or a socket is returned 565 while (true) { 566 try { 567 socket = mmServerSocket.accept(); 568 } catch (IOException e) { 569 break; 570 } 571 // If a connection was accepted 572 if (socket != null) { 573 // Do work to manage the connection (in a separate thread) 574 manageConnectedSocket(socket); 575 mmServerSocket.close(); 576 break; 577 } 578 } 579 } 580 581 /** Will cancel the listening socket, and cause the thread to finish */ 582 public void cancel() { 583 try { 584 mmServerSocket.close(); 585 } catch (IOException e) { } 586 } 587} 588</pre> 589 590<p>In this example, only one incoming connection is desired, so as soon as a 591connection is accepted and the {@link android.bluetooth.BluetoothSocket} is 592acquired, the application 593sends the acquired {@link android.bluetooth.BluetoothSocket} to a separate 594thread, closes the 595{@link android.bluetooth.BluetoothServerSocket} and breaks the loop.</p> 596 597<p>Note that when {@link android.bluetooth.BluetoothServerSocket#accept()} 598returns the {@link android.bluetooth.BluetoothSocket}, the socket is already 599connected, so you should <em>not</em> call {@link 600android.bluetooth.BluetoothSocket#connect()} (as you do from the 601client-side).</p> 602 603<p><code>manageConnectedSocket()</code> is a fictional method in the application 604that will 605initiate the thread for transferring data, which is discussed in the section 606about <a href="#ManagingAConnection">Managing a Connection</a>.</p> 607 608<p>You should usually close your {@link android.bluetooth.BluetoothServerSocket} 609as soon as you are done listening for incoming connections. In this example, {@link 610android.bluetooth.BluetoothServerSocket#close()} is called as soon 611as the {@link android.bluetooth.BluetoothSocket} is acquired. You may also want 612to provide a public method in your thread that can close the private {@link 613android.bluetooth.BluetoothSocket} in the event that you need to stop listening on the 614server socket.</p> 615 616 617<h3 id="ConnectingAsAClient">Connecting as a client</h3> 618 619<p>In order to initiate a connection with a remote device (a device holding an 620open 621server socket), you must first obtain a {@link 622android.bluetooth.BluetoothDevice} object that represents the remote device. 623(Getting a {@link android.bluetooth.BluetoothDevice} is covered in the above 624section about <a 625href="#FindingDevices">Finding Devices</a>.) You must then use the 626{@link android.bluetooth.BluetoothDevice} to acquire a {@link 627android.bluetooth.BluetoothSocket} and initiate the connection.</p> 628 629<p>Here's the basic procedure:</p> 630 631<ol> 632<li>Using the {@link android.bluetooth.BluetoothDevice}, get a {@link 633android.bluetooth.BluetoothSocket} by calling {@link 634android.bluetooth.BluetoothDevice#createRfcommSocketToServiceRecord(UUID)}. 635<p>This initializes a {@link android.bluetooth.BluetoothSocket} that will 636connect to the {@link android.bluetooth.BluetoothDevice}. The UUID passed here 637must match the UUID used by the server device when it opened its 638{@link android.bluetooth.BluetoothServerSocket} (with {@link 639android.bluetooth.BluetoothAdapter#listenUsingRfcommWithServiceRecord(String, 640UUID)}). Using the same UUID is simply a matter of hard-coding the UUID string 641into your application and then referencing it from both the server and client 642code.</p> 643</li> 644 645<li>Initiate the connection by calling {@link 646android.bluetooth.BluetoothSocket#connect()}. 647<p>Upon this call, the system will perform an SDP lookup on the remote device in 648order to match the UUID. If the lookup is successful and the remote device 649accepts the connection, it will share the RFCOMM channel to use during the 650connection and {@link 651android.bluetooth.BluetoothSocket#connect()} will return. This method is a 652blocking call. If, for 653any reason, the connection fails or the {@link 654android.bluetooth.BluetoothSocket#connect()} method times out (after about 65512 seconds), then it will throw an exception.</p> 656<p>Because {@link 657android.bluetooth.BluetoothSocket#connect()} is a blocking call, this connection 658procedure should always be performed in a thread separate from the main Activity 659thread.</p> 660<p class="note">Note: You should always ensure that the device is not performing 661device discovery when you call {@link 662android.bluetooth.BluetoothSocket#connect()}. If discovery is in progress, then 663the 664connection attempt will be significantly slowed and is more likely to fail.</p> 665</li> 666</ol> 667 668<h4>Example</h4> 669 670<p>Here is a basic example of a thread that initiates a Bluetooth 671connection:</p> 672<pre> 673private class ConnectThread extends Thread { 674 private final BluetoothSocket mmSocket; 675 private final BluetoothDevice mmDevice; 676 677 public ConnectThread(BluetoothDevice device) { 678 // Use a temporary object that is later assigned to mmSocket, 679 // because mmSocket is final 680 BluetoothSocket tmp = null; 681 mmDevice = device; 682 683 // Get a BluetoothSocket to connect with the given BluetoothDevice 684 try { 685 // MY_UUID is the app's UUID string, also used by the server code 686 tmp = device.createRfcommSocketToServiceRecord(MY_UUID); 687 } catch (IOException e) { } 688 mmSocket = tmp; 689 } 690 691 public void run() { 692 // Cancel discovery because it will slow down the connection 693 mAdapter.cancelDiscovery(); 694 695 try { 696 // Connect the device through the socket. This will block 697 // until it succeeds or throws an exception 698 mmSocket.connect(); 699 } catch (IOException connectException) { 700 // Unable to connect; close the socket and get out 701 try { 702 mmSocket.close(); 703 } catch (IOException closeException) { } 704 return; 705 } 706 707 // Do work to manage the connection (in a separate thread) 708 manageConnectedSocket(mmSocket); 709 } 710 711 /** Will cancel an in-progress connection, and close the socket */ 712 public void cancel() { 713 try { 714 mmSocket.close(); 715 } catch (IOException e) { } 716 } 717} 718</pre> 719 720<p>Notice that {@link android.bluetooth.BluetoothAdapter#cancelDiscovery()} is called 721before the connection is made. You should always do this before connecting and it is safe 722to call without actually checking whether it is running or not (but if you do want to 723check, call {@link android.bluetooth.BluetoothAdapter#isDiscovering()}).</p> 724 725<p><code>manageConnectedSocket()</code> is a fictional method in the application 726that will initiate the thread for transferring data, which is discussed in the section 727about <a href="#ManagingAConnection">Managing a Connection</a>.</p> 728 729<p>When you're done with your {@link android.bluetooth.BluetoothSocket}, always 730call {@link android.bluetooth.BluetoothSocket#close()} to clean up. 731Doing so will immediately close the connected socket and clean up all internal 732resources.</p> 733 734 735<h2 id="ManagingAConnection">Managing a Connection</h2> 736 737<p>When you have successfully connected two (or more) devices, each one will 738have a connected {@link android.bluetooth.BluetoothSocket}. This is where the fun 739begins because you can share data between devices. Using the {@link 740android.bluetooth.BluetoothSocket}, the general procedure to transfer arbitrary data is 741simple:</p> 742<ol> 743<li>Get the {@link java.io.InputStream} and {@link java.io.OutputStream} that 744handle transmissions through the socket, via {@link 745android.bluetooth.BluetoothSocket#getInputStream()} and 746{@link android.bluetooth.BluetoothSocket#getOutputStream}, respectively.</li> 747 748<li>Read and write data to the streams with {@link 749java.io.InputStream#read(byte[])} and {@link java.io.OutputStream#write(byte[])}.</li> 750</ol> 751 752<p>That's it.</p> 753 754<p>There are, of course, implementation details to consider. First and foremost, 755you should use a dedicated thread for all stream reading and writing. This is 756important because both {@link java.io.InputStream#read(byte[])} and {@link 757java.io.OutputStream#write(byte[])} methods are blocking calls. {@link 758java.io.InputStream#read(byte[])} will block until there is something to read 759from the stream. {@link java.io.OutputStream#write(byte[])} does not usually 760block, but can block for flow control if the remote device is not calling {@link 761java.io.InputStream#read(byte[])} quickly enough and the intermediate buffers are full. 762So, your main loop in the thread should be dedicated to reading from the {@link 763java.io.InputStream}. A separate public method in the thread can be used to initiate 764writes to the {@link java.io.OutputStream}.</p> 765 766<h4>Example</h4> 767 768<p>Here's an example of how this might look:</p> 769<pre> 770private class ConnectedThread extends Thread { 771 private final BluetoothSocket mmSocket; 772 private final InputStream mmInStream; 773 private final OutputStream mmOutStream; 774 775 public ConnectedThread(BluetoothSocket socket) { 776 mmSocket = socket; 777 InputStream tmpIn = null; 778 OutputStream tmpOut = null; 779 780 // Get the input and output streams, using temp objects because 781 // member streams are final 782 try { 783 tmpIn = socket.getInputStream(); 784 tmpOut = socket.getOutputStream(); 785 } catch (IOException e) { } 786 787 mmInStream = tmpIn; 788 mmOutStream = tmpOut; 789 } 790 791 public void run() { 792 byte[] buffer = new byte[1024]; // buffer store for the stream 793 int bytes; // bytes returned from read() 794 795 // Keep listening to the InputStream until an exception occurs 796 while (true) { 797 try { 798 // Read from the InputStream 799 bytes = mmInStream.read(buffer); 800 // Send the obtained bytes to the UI Activity 801 mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer) 802 .sendToTarget(); 803 } catch (IOException e) { 804 break; 805 } 806 } 807 } 808 809 /* Call this from the main Activity to send data to the remote device */ 810 public void write(byte[] bytes) { 811 try { 812 mmOutStream.write(bytes); 813 } catch (IOException e) { } 814 } 815 816 /* Call this from the main Activity to shutdown the connection */ 817 public void cancel() { 818 try { 819 mmSocket.close(); 820 } catch (IOException e) { } 821 } 822} 823</pre> 824 825<p>The constructor acquires the necessary streams and once executed, the thread 826will wait for data to come through the InputStream. When {@link 827java.io.InputStream#read(byte[])} returns with 828bytes from the stream, the data is sent to the main Activity using a member 829Handler from the parent class. Then it goes back and waits for more bytes from 830the stream.</p> 831 832<p>Sending outgoing data is as simple as calling the thread's 833<code>write()</code> method from the main Activity and passing in the bytes to 834be sent. This method then simply calls {@link 835java.io.OutputStream#write(byte[])} to send the data to the remote device.</p> 836 837<p>The thread's <code>cancel()</code> method is important so that the connection 838can be 839terminated at any time by closing the {@link android.bluetooth.BluetoothSocket}. 840This should always be called when you're done using the Bluetooth 841connection.</p> 842 843<div class="special"> 844<p>For a complete demonstration using the Bluetooth APIs, see the <a 845href="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat sample app</a>.</p> 846</div> 847