• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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&lt;manifest ... >
151  &lt;uses-permission android:name="android.permission.BLUETOOTH" />
152  ...
153&lt;/manifest>
154</pre>
155
156<p>See the <a
157href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;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&lt;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