19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpage.title=Bluetooth 233baa5ad7d8cdcc89ce4fbc3bc8cd537d5f5d639Joe Fernandezpage.tags=wireless,bluetoothadapter,bluetoothdevice 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project@jd:body 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormick<div id="qv-wrapper"> 6f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormick<div id="qv"> 7d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 8f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormick <h2>In this document</h2> 9d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <ol> 10f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormick <li><a href="#TheBasics">The Basics</a></li> 11f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormick <li><a href="#Permissions">Bluetooth Permissions</a></li> 12d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="#SettingUp">Setting Up Bluetooth</a></li> 13d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="#FindingDevices">Finding Devices</a> 14d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <ol> 15d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="#QueryingPairedDevices">Querying paired devices</a></li> 16d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="#DiscoveringDevices">Discovering devices</a></li> 17d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick </ol></li> 18d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="#ConnectingDevices">Connecting Devices</a> 19d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <ol> 20d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="#ConnectingAsAServer">Connecting as a server</a></li> 21d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="#ConnectingAsAClient">Connecting as a client</a></li> 22d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick </ol></li> 23d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="#ManagingAConnection">Managing a Connection</a></li> 24d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="#Profiles">Working with Profiles</a> 25ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main <ol> 26d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="#AT-Commands">Vendor-specific AT commands</a> 272e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <li><a href="#HDP">Health Device Profile</a> 28a90eb8fec1c67177b614b945bcc4a4b14aaabaffScott Main </ol></li> 29d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick </ol> 30d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 31d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <h2>Key classes</h2> 32d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <ol> 33d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li>{@link android.bluetooth.BluetoothAdapter}</li> 34d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li>{@link android.bluetooth.BluetoothDevice}</li> 35d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li>{@link android.bluetooth.BluetoothSocket}</li> 36d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li>{@link android.bluetooth.BluetoothServerSocket}</li> 37d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick </ol> 38d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 39d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <h2>Related samples</h2> 40d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <ol> 41d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><a href="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat</a></li> 422e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <li><a href="{@docRoot}resources/samples/BluetoothHDP/index.html">Bluetooth HDP (Health Device Profile)</a></li> 43d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick </ol> 44d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 45d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</div> 46d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</div> 47d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 48d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 49ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>The Android platform includes support for the Bluetooth network stack, 50ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwhich allows a device to wirelessly exchange data with other Bluetooth devices. 51ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainThe application framework provides access to the Bluetooth functionality through 52ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe Android Bluetooth APIs. These APIs let applications wirelessly 53ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainconnect to other Bluetooth devices, enabling point-to-point and multipoint 54d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickwireless features.</p> 55d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 56ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Using the Bluetooth APIs, an Android application can perform the 57ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainfollowing:</p> 58ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<ul> 59ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main <li>Scan for other Bluetooth devices</li> 60ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main <li>Query the local Bluetooth adapter for paired Bluetooth devices</li> 61ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main <li>Establish RFCOMM channels</li> 62ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main <li>Connect to other devices through service discovery</li> 63ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main <li>Transfer data to and from other devices</li> 64ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main <li>Manage multiple connections</li> 65ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main</ul> 66ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main 67f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormick<p>This document describes how to use <em>Classic Bluetooth</em>. Classic 68f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormickBluetooth is the right choice for more battery-intensive operations such as streaming 69f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormickand communicating between Android devices. For Bluetooth devices with low power requirements, 70f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormickAndroid 4.3 (API Level 18) introduces API support for Bluetooth Low Energy. To learn more, 71f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormicksee <a href="{@docRoot}guide/topics/connectivity/bluetooth-le.html">Bluetooth Low Energy</a>.</p> 72ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main 73ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<h2 id="TheBasics">The Basics</h2> 74ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main 75bb64fa1e3dde8910397d159eaa300c4444b0073cScott Main<p>This document describes how to use the Android Bluetooth APIs to accomplish 76ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe four major tasks necessary to communicate using Bluetooth: setting up 77ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainBluetooth, finding devices that are either paired or available in the local 78d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickarea, connecting devices, and transferring data between devices.</p> 79d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 80ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>All of the Bluetooth APIs are available in the {@link android.bluetooth} 81d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickpackage. Here's a summary of the classes and interfaces you will need to create Bluetooth 82d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickconnections:</p> 83d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 84d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<dl> 85d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<dt>{@link android.bluetooth.BluetoothAdapter}</dt> 86ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<dd>Represents the local Bluetooth adapter (Bluetooth radio). The 87ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothAdapter} is the entry-point for all Bluetooth 88ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maininteraction. Using this, 89ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainyou can discover other Bluetooth devices, query a list of bonded (paired) 90ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maindevices, instantiate a {@link android.bluetooth.BluetoothDevice} using a known 91ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainMAC address, and create a {@link android.bluetooth.BluetoothServerSocket} to 92ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainlisten for communications 93d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickfrom other devices.</dd> 94d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 95d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<dt>{@link android.bluetooth.BluetoothDevice}</dt> 96ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<dd>Represents a remote Bluetooth device. Use this to request a connection 97ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwith a remote device through a {@link android.bluetooth.BluetoothSocket} or 98ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainquery information about the 99d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickdevice such as its name, address, class, and bonding state.</dd> 100d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 101d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<dt>{@link android.bluetooth.BluetoothSocket}</dt> 102ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<dd>Represents the interface for a Bluetooth socket (similar to a TCP 103ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link java.net.Socket}). This is the connection point that allows 104ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainan application to exchange data with another Bluetooth device via InputStream 105d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickand OutputStream.</dd> 106d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 107d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<dt>{@link android.bluetooth.BluetoothServerSocket}</dt> 108ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<dd>Represents an open server socket that listens for incoming requests 109ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main(similar to a TCP {@link java.net.ServerSocket}). In order to connect two 110ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainAndroid devices, one device must open a server socket with this class. When a 111ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainremote Bluetooth device makes a connection request to the this device, the 112ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothServerSocket} will return a connected {@link 113ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket} when the 114d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickconnection is accepted.</dd> 115d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 116d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<dt>{@link android.bluetooth.BluetoothClass}</dt> 117ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<dd>Describes the general characteristics and capabilities of a Bluetooth 118ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maindevice. This is a read-only set of properties that define the device's major and 119ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainminor device classes and its services. However, this does not reliably describe 120ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainall Bluetooth profiles and services supported by the device, but is useful as a 121d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickhint to the device type.</dd> 122d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 123d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<dt>{@link android.bluetooth.BluetoothProfile}</dt> <dd>An interface that 124d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickrepresents a Bluetooth profile. A <em>Bluetooth profile</em> is a wireless 125d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickinterface specification for Bluetooth-based communication between devices. An 126d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickexample is the Hands-Free profile. For more discussion of profiles, see <a 127d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickhref="#Profiles">Working with Profiles</a></dd> 128d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 129d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<dt>{@link android.bluetooth.BluetoothHeadset}</dt> <dd>Provides support for 130d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickBluetooth headsets to be used with mobile phones. This includes both Bluetooth 131d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickHeadset and Hands-Free (v1.5) profiles.</dd> 132d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 133d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<dt>{@link android.bluetooth.BluetoothA2dp}</dt> <dd> Defines how high quality 134d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickaudio can be streamed from one device to another over a Bluetooth connection. 135d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick"A2DP" stands for Advanced Audio Distribution Profile.</dd> 136d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 1372e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<dt>{@link android.bluetooth.BluetoothHealth}</dt> 1382e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<dd> Represents a Health Device Profile proxy that controls the Bluetooth service.</dd> 1392e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 1402e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<dt>{@link android.bluetooth.BluetoothHealthCallback}</dt> 1412e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 1422e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<dd>An abstract class that you use to implement {@link 1432e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickandroid.bluetooth.BluetoothHealth} callbacks. You must extend this class and 1442e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickimplement the callback methods to receive updates about changes in the 1452e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickapplication’s registration state and Bluetooth channel state.</dd> 1462e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 1472e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<dt>{@link android.bluetooth.BluetoothHealthAppConfiguration}</dt> 1482e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 1492e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<dd>Represents an application configuration that the Bluetooth Health third-party 1502e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickapplication registers to communicate with a remote Bluetooth health 1512e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickdevice.</dd> 1522e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 1532e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<dt>{@link android.bluetooth.BluetoothProfile.ServiceListener}</dt> 154d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 155d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<dd>An interface that notifies {@link android.bluetooth.BluetoothProfile} IPC 156d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickclients when they have been connected to or disconnected from the service (that 1572e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickis, the internal service that runs a particular profile). </dd> 158d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 159d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</dl> 160d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 161d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 162d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 163d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 164d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h2 id="Permissions">Bluetooth Permissions</h2> 165d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 166f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormick<p>In order to use Bluetooth features in your application, you must declare 167f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormickthe Bluetooth permission {@link android.Manifest.permission#BLUETOOTH}. 168f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormickYou need this permission to perform any Bluetooth communication, 169f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormicksuch as requesting a connection, accepting a connection, and transferring data.</p> 170f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormick 171f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormick<p>If you want your app to initiate device discovery or manipulate Bluetooth 172f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormicksettings, you must also declare the {@link android.Manifest.permission#BLUETOOTH_ADMIN} 173f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormickpermission. Most applications need this permission solely for the 174ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainability to discover local Bluetooth devices. The other abilities granted by this 175ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainpermission should not be used, unless the application is a "power manager" that 176ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwill modify Bluetooth settings upon user request. <strong>Note:</strong> If you 177f14ff1c9ce37299c2fcef258a854acf79c026ccfkmccormickuse {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission, then you must 178d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickalso have the {@link android.Manifest.permission#BLUETOOTH} permission.</p> 179d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 180ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Declare the Bluetooth permission(s) in your application manifest file. For 181d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickexample:</p> 182d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 183d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<pre> 184ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<manifest ... > 185ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main <uses-permission android:name="android.permission.BLUETOOTH" /> 186ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main ... 187ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main</manifest> 188d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</pre> 189d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 190ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>See the <a 191d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickhref="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a> 192d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickreference for more information about declaring application permissions.</p> 193d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 194d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 195d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h2 id="SettingUp">Setting Up Bluetooth</h2> 196d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 197d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<div class="figure" style="width:200px"> 198d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<img src="{@docRoot}images/bt_enable_request.png" /> 199ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<strong>Figure 1:</strong> The enabling Bluetooth dialog. 200d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</div> 201d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 202ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Before your application can communicate over Bluetooth, you need to verify 203d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickthat Bluetooth is supported on the device, and if so, ensure that it is enabled.</p> 204d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 205ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>If Bluetooth is not supported, then you should gracefully disable any 206ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainBluetooth features. If Bluetooth is supported, but disabled, then you can request that the 207ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainuser enable Bluetooth without leaving your application. This setup is 208d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickaccomplished in two steps, using the {@link android.bluetooth.BluetoothAdapter}.</p> 209d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 210d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 211d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<ol> 212ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<li>Get the {@link android.bluetooth.BluetoothAdapter} 213ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>The {@link android.bluetooth.BluetoothAdapter} is required for any and all Bluetooth 214ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainactivity. To get the {@link android.bluetooth.BluetoothAdapter}, call the static {@link 215ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#getDefaultAdapter()} method. This returns a 216ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothAdapter} that represents the device's own 217ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainBluetooth adapter (the Bluetooth radio). There's one Bluetooth adapter for the 218ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainentire system, and your application can interact with it using this object. If 219ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothAdapter#getDefaultAdapter()} returns null, 220d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickthen the device does not support Bluetooth and your story ends here. For example:</p> 221d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<pre> 222ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainBluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 223ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainif (mBluetoothAdapter == null) { 224ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Device does not support Bluetooth 225ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main} 226d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</pre> 227d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</li> 228d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 229ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<li>Enable Bluetooth 230ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Next, you need to ensure that Bluetooth is enabled. Call {@link 231ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#isEnabled()} to check whether Bluetooth is 232ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maincurrently enable. If this method returns false, then Bluetooth is disabled. To 233ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainrequest that Bluetooth be enabled, call {@link 234ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.app.Activity#startActivityForResult(Intent,int) startActivityForResult()} 235ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwith the {@link android.bluetooth.BluetoothAdapter#ACTION_REQUEST_ENABLE} action Intent. 236ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainThis will issue a request to enable Bluetooth through the system settings (without 237d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickstopping your application). For example:</p> 238d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<pre> 239ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainif (!mBluetoothAdapter.isEnabled()) { 240ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 241ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 242ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main} 243d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</pre> 244d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 245ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>A dialog will appear requesting user permission to enable Bluetooth, as shown 246ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainin Figure 1. If the user responds "Yes," the system will begin to enable Bluetooth 247d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickand focus will return to your application once the process completes (or fails).</p> 24893dc642eaf48e3db58c4929df26283fbc5fd663fScott Main 24993dc642eaf48e3db58c4929df26283fbc5fd663fScott Main<p>The {@code REQUEST_ENABLE_BT} constant passed to {@link 25093dc642eaf48e3db58c4929df26283fbc5fd663fScott Mainandroid.app.Activity#startActivityForResult(Intent,int) startActivityForResult()} is a locally 25193dc642eaf48e3db58c4929df26283fbc5fd663fScott Maindefined integer (which must be greater than 0), that the system passes back to you in your 25293dc642eaf48e3db58c4929df26283fbc5fd663fScott Main{@link 25393dc642eaf48e3db58c4929df26283fbc5fd663fScott Mainandroid.app.Activity#onActivityResult(int,int,Intent) onActivityResult()} implementation as the 25493dc642eaf48e3db58c4929df26283fbc5fd663fScott Main<code>requestCode</code> parameter.</p> 25593dc642eaf48e3db58c4929df26283fbc5fd663fScott Main 25693dc642eaf48e3db58c4929df26283fbc5fd663fScott Main<p>If enabling Bluetooth succeeds, your activity receives the {@link 257ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.app.Activity#RESULT_OK} result code in the {@link 258ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.app.Activity#onActivityResult(int,int,Intent) onActivityResult()} 259ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maincallback. If Bluetooth was not enabled 26093dc642eaf48e3db58c4929df26283fbc5fd663fScott Maindue to an error (or the user responded "No") then the result code is {@link 26193dc642eaf48e3db58c4929df26283fbc5fd663fScott Mainandroid.app.Activity#RESULT_CANCELED}.</p> 262d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</li> 263d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</ol> 264d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 265ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Optionally, your application can also listen for the 266ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothAdapter#ACTION_STATE_CHANGED} broadcast Intent, which 267ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe system will broadcast whenever the Bluetooth state has changed. This broadcast contains 268ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe extra fields {@link android.bluetooth.BluetoothAdapter#EXTRA_STATE} and {@link 269ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#EXTRA_PREVIOUS_STATE}, containing the new and old 270ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainBluetooth states, respectively. Possible values for these extra fields are 271ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothAdapter#STATE_TURNING_ON}, {@link 272ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#STATE_ON}, {@link 273ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#STATE_TURNING_OFF}, and {@link 274ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#STATE_OFF}. Listening for this 275ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainbroadcast can be useful to detect changes made to the Bluetooth state while your 276d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickapp is running.</p> 277d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 278ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p class="note"><strong>Tip:</strong> Enabling discoverability will automatically 279ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainenable Bluetooth. If you plan to consistently enable device discoverability before 280ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainperforming Bluetooth activity, you can skip 281ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainstep 2 above. Read about <a href="#EnablingDiscoverability">enabling discoverability</a>, 282d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickbelow.</p> 283d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 284d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 285d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h2 id="FindingDevices">Finding Devices</h2> 286d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 287ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Using the {@link android.bluetooth.BluetoothAdapter}, you can find remote Bluetooth 288ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maindevices either through device discovery or by querying the list of paired (bonded) 289d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickdevices.</p> 290d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 291ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Device discovery is a scanning procedure that searches the local area for 292ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainBluetooth enabled devices and then requesting some information about each one 293ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main(this is sometimes referred to as "discovering," "inquiring" or "scanning"). 294ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainHowever, a Bluetooth device within the local area will respond to a discovery 295ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainrequest only if it is currently enabled to be discoverable. If a device is 296ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maindiscoverable, it will respond to the discovery request by sharing some 297ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maininformation, such as the device name, class, and its unique MAC address. Using 298ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthis information, the device performing discovery can then choose to initiate a 299d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickconnection to the discovered device.</p> 300d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 301ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Once a connection is made with a remote device for the first time, a pairing 302ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainrequest is automatically presented to the user. When a device is 303ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainpaired, the basic information about that device (such as the device name, class, 304ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainand MAC address) is saved and can be read using the Bluetooth APIs. Using the 305ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainknown MAC address for a remote device, a connection can be initiated with it at 306d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickany time without performing discovery (assuming the device is within range).</p> 307d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 308ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Remember there is a difference between being paired and being connected. To 309ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainbe paired means that two devices are aware of each other's existence, have a 310ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainshared link-key that can be used for authentication, and are capable of 311ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainestablishing an encrypted connection with each other. To be connected means that 312ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe devices currently share an RFCOMM channel and are able to transmit data with 313ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maineach other. The current Android Bluetooth API's require devices to be paired 314ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainbefore an RFCOMM connection can be established. (Pairing is automatically performed 315d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickwhen you initiate an encrypted connection with the Bluetooth APIs.)</p> 316d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 317ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>The following sections describe how to find devices that have been paired, or 318d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickdiscover new devices using device discovery.</p> 319d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 320ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p class="note"><strong>Note:</strong> Android-powered devices are not 321ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maindiscoverable by default. A user can make 322ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe device discoverable for a limited time through the system settings, or an 323ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainapplication can request that the user enable discoverability without leaving the 324d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickapplication. How to <a href="#EnablingDiscoverability">enable discoverability</a> 325d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickis discussed below.</p> 326d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 327d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 328d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h3 id="QueryingPairedDevices">Querying paired devices</h3> 329d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 330ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Before performing device discovery, its worth querying the set 331ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainof paired devices to see if the desired device is already known. To do so, 332ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maincall {@link android.bluetooth.BluetoothAdapter#getBondedDevices()}. This 333ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwill return a Set of {@link android.bluetooth.BluetoothDevice}s representing 33436cdecd89dbc3eb503197414f525e30ee241ba66Scott Mainpaired devices. For example, you can query all paired devices and then 335d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickshow the name of each device to the user, using an ArrayAdapter:</p> 336d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<pre> 337ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainSet<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); 338ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main// If there are paired devices 339ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainif (pairedDevices.size() > 0) { 340ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Loop through paired devices 341ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main for (BluetoothDevice device : pairedDevices) { 342ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Add the name and address to an array adapter to show in a ListView 343ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); 344ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 345ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main} 346d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</pre> 347d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 348ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>All that's needed from the {@link android.bluetooth.BluetoothDevice} object 349ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainin order to initiate a connection is the MAC address. In this example, it's saved 350ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainas a part of an ArrayAdapter that's shown to the user. The MAC address can later 351ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainbe extracted in order to initiate the connection. You can learn more about creating 352d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormicka connection in the section about <a href="#ConnectingDevices">Connecting Devices</a>.</p> 353d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 354d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 355d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h3 id="DiscoveringDevices">Discovering devices</h3> 356d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 357ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>To start discovering devices, simply call {@link 358ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#startDiscovery()}. The 359ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainprocess is asynchronous and the method will immediately return with a boolean 360ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainindicating whether discovery has successfully started. The discovery process 361ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainusually involves an inquiry scan of about 12 seconds, followed by a page scan of 362d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickeach found device to retrieve its Bluetooth name.</p> 363d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 364ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Your application must register a BroadcastReceiver for the 365ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothDevice#ACTION_FOUND} Intent in 366ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainorder to receive information about each 367ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maindevice discovered. For each device, the system will broadcast the 368ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothDevice#ACTION_FOUND} Intent. This 369ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainIntent carries the extra fields 370ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothDevice#EXTRA_DEVICE} and 371ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothDevice#EXTRA_CLASS}, containing a 372ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothDevice} and a {@link 373ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothClass}, respectively. For example, here's how you can 374d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickregister to handle the broadcast when devices are discovered:</p> 375d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<pre> 376ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main// Create a BroadcastReceiver for ACTION_FOUND 377ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainprivate final BroadcastReceiver mReceiver = new BroadcastReceiver() { 378ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public void onReceive(Context context, Intent intent) { 379ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main String action = intent.getAction(); 380ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // When discovery finds a device 381ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main if (BluetoothDevice.ACTION_FOUND.equals(action)) { 382ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Get the BluetoothDevice object from the Intent 383ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 384ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Add the name and address to an array adapter to show in a ListView 385ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); 386ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 387ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 388ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main}; 389ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main// Register the BroadcastReceiver 390ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainIntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 391ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainregisterReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy 392d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</pre> 393d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 394ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>All that's needed from the {@link android.bluetooth.BluetoothDevice} object 395ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainin order to initiate a 396ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainconnection is the MAC address. In this example, it's saved as a part of an 397ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainArrayAdapter that's shown to the user. The MAC address can later be extracted in 398ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainorder to initiate the connection. You can learn more about creating a connection 399d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickin the section about <a href="#ConnectingDevices">Connecting Devices</a>.</p> 400d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 401ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p class="caution"><strong>Caution:</strong> Performing device discovery is 402ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maina heavy procedure for the Bluetooth 403ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainadapter and will consume a lot of its resources. Once you have found a device to 404ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainconnect, be certain that you always stop discovery with 405ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothAdapter#cancelDiscovery()} before 406ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainattempting a connection. Also, if you 407ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainalready hold a connection with a device, then performing discovery can 408ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainsignificantly reduce the bandwidth available for the connection, so you should 409d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormicknot perform discovery while connected.</p> 410d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 411d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h4 id="EnablingDiscoverability">Enabling discoverability</h4> 412d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 413ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>If you would like to make the local device discoverable to other devices, 414ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maincall {@link android.app.Activity#startActivityForResult(Intent,int)} with the 415d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick{@link android.bluetooth.BluetoothAdapter#ACTION_REQUEST_DISCOVERABLE} action 416d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickIntent. This will issue a request to enable discoverable mode through the system 417d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormicksettings (without stopping your application). By default, the device will become 418d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickdiscoverable for 120 seconds. You can define a different duration by adding the 419d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick{@link android.bluetooth.BluetoothAdapter#EXTRA_DISCOVERABLE_DURATION} Intent 420d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickextra. The maximum duration an app can set is 3600 seconds, and a value of 0 421d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickmeans the device is always discoverable. Any value below 0 or above 3600 is 422d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickautomatically set to 120 secs). For example, this snippet sets the duration to 423d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick300:</p> 424d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 425d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<pre>Intent discoverableIntent = new 426ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); 427ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MaindiscoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); 428ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainstartActivity(discoverableIntent); 429d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</pre> 430d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 431d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<div class="figure" style="width:200px"> 432d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<img src="{@docRoot}images/bt_enable_discoverable.png" /> 433ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<strong>Figure 2:</strong> The enabling discoverability dialog. 434d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</div> 435d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 436ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>A dialog will be displayed, requesting user permission to make the device 437ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maindiscoverable, as shown in Figure 2. If the user responds "Yes," then the device 43893dc642eaf48e3db58c4929df26283fbc5fd663fScott Mainwill become discoverable for the specified amount of time. Your activity will 439ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthen receive a call to the {@link android.app.Activity#onActivityResult(int,int,Intent) 440ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainonActivityResult())} callback, with the result code equal to the duration that the device 441ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainis discoverable. If the user responded "No" or if an error occurred, the result code will 44293dc642eaf48e3db58c4929df26283fbc5fd663fScott Mainbe {@link android.app.Activity#RESULT_CANCELED}.</p> 443d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 444ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p class="note"><strong>Note:</strong> If Bluetooth has not been enabled on the device, 445d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickthen enabling device discoverability will automatically enable Bluetooth.</p> 446d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 447ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>The device will silently remain in discoverable mode for the allotted time. 448ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainIf you would like to be notified when the discoverable mode has changed, you can 449ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainregister a BroadcastReceiver for the {@link 450ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#ACTION_SCAN_MODE_CHANGED} 451ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainIntent. This will contain the extra fields {@link 452ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#EXTRA_SCAN_MODE} and 453ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothAdapter#EXTRA_PREVIOUS_SCAN_MODE}, which tell you the 454ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainnew and old scan mode, respectively. Possible values for each are 455ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothAdapter#SCAN_MODE_CONNECTABLE_DISCOVERABLE}, 456ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothAdapter#SCAN_MODE_CONNECTABLE}, or {@link 457ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#SCAN_MODE_NONE}, 458ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwhich indicate that the device is either in discoverable mode, not in 459ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maindiscoverable mode but still able to receive connections, or not in discoverable 460d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickmode and unable to receive connections, respectively.</p> 461d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 462ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>You do not need to enable device discoverability if you will be initiating 463ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe connection to a remote device. Enabling discoverability is only necessary when 464ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainyou want your application to host a server socket that will accept incoming 465ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainconnections, because the remote devices must be able to discover the device 466d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickbefore it can initiate the connection.</p> 467d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 468d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 469d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 470d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h2 id="ConnectingDevices">Connecting Devices</h2> 471d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 472ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>In order to create a connection between your application on two devices, you 473ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainmust implement both the server-side and client-side mechanisms, because one 474ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maindevice must open a server socket and the other one must initiate the connection 475ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main(using the server device's MAC address to initiate a connection). The server and 476ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainclient are considered connected to each other when they each have a connected 477ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothSocket} on the same RFCOMM channel. At this 478ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainpoint, each device can obtain input and output streams and data transfer can 479ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainbegin, which is discussed in the section about <a 480369c1c1fa22802b6504c5cde533d797841700a66Scott Mainhref="#ManagingAConnection">Managing a Connection</a>. This section describes how 481d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickto initiate the connection between two devices.</p> 482d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 483ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>The server device and the client device each obtain the required {@link 484ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket} in different ways. The server will receive it 485ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwhen an incoming connection is accepted. The client will receive it when it 486d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickopens an RFCOMM channel to the server.</p> 487d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 488d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<div class="figure" style="width:200px"> 489d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<img src="{@docRoot}images/bt_pairing_request.png" /> 490fe7f27aabfb339b86eeb3a40ce894b91eafd26f0Scott Main<strong>Figure 3:</strong> The Bluetooth pairing dialog. 491d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</div> 492d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 493ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>One implementation technique is to automatically prepare each device as a 494ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainserver, so that each one has a server socket open and listening for connections. 495ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainThen either device can initiate a connection with the other and become the 496ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainclient. Alternatively, one device can explicitly "host" the connection and open 497ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maina server socket on demand and the other device can simply initiate the 498d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickconnection.</p> 499d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 500ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p class="note"><strong>Note:</strong> If the two devices have not been previously paired, 501ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthen the Android framework will automatically show a pairing request notification or 502fe7f27aabfb339b86eeb3a40ce894b91eafd26f0Scott Maindialog to the user during the connection procedure, as shown in Figure 3. So 503fe7f27aabfb339b86eeb3a40ce894b91eafd26f0Scott Mainwhen attempting to connect devices, 504ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainyour application does not need to be concerned about whether or not the devices are 505ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainpaired. Your RFCOMM connection attempt will block until the user has successfully paired, 506d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickor will fail if the user rejects pairing, or if pairing fails or times out. </p> 507d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 508d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 509d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h3 id="ConnectingAsAServer">Connecting as a server</h3> 510d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 511ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>When you want to connect two devices, one must act as a server by holding an 512ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainopen {@link android.bluetooth.BluetoothServerSocket}. The purpose of the server 513ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainsocket is to listen for incoming connection requests and when one is accepted, 514ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainprovide a connected {@link android.bluetooth.BluetoothSocket}. When the {@link 515ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket} is acquired from the {@link 516ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothServerSocket}, 517ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe {@link android.bluetooth.BluetoothServerSocket} can (and should) be 518d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickdiscarded, unless you want to accept more connections.</p> 519d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 520d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<div class="sidebox-wrapper"> 521d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<div class="sidebox"> 522d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h2>About UUID</h2> 523d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 524ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>A Universally Unique Identifier (UUID) is a standardized 128-bit format for a string 525ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainID used to uniquely identify information. The point of a UUID is that it's big 526ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainenough that you can select any random and it won't clash. In this case, it's 527ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainused to uniquely identify your application's Bluetooth service. To get a UUID to 528ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainuse with your application, you can use one of the many random UUID generators on 529ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe web, then initialize a {@link java.util.UUID} with {@link 530d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickjava.util.UUID#fromString(String)}.</p> 531d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</div> 532d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</div> 533d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 534ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Here's the basic procedure to set up a server socket and accept a 535d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickconnection:</p> 536d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 537d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<ol> 538ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<li>Get a {@link android.bluetooth.BluetoothServerSocket} by calling the 539ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link 540ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#listenUsingRfcommWithServiceRecord(String, 541ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainUUID)}. 542ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>The string is an identifiable name of your service, which the system will 543ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainautomatically write to a new Service Discovery Protocol (SDP) database entry on 544ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe device (the name is arbitrary and can simply be your application name). The 545ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainUUID is also included in the SDP entry and will be the basis for the connection 546ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainagreement with the client device. That is, when the client attempts to connect 547ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwith this device, it will carry a UUID that uniquely identifies the service with 548ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwhich it wants to connect. These UUIDs must match in order for the connection to 549d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickbe accepted (in the next step).</p> 550d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</li> 551d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 552ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<li>Start listening for connection requests by calling 553ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothServerSocket#accept()}. 554ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>This is a blocking call. It will return when either a connection has been 555ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainaccepted or an exception has occurred. A connection is accepted only when a 556ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainremote device has sent a connection request with a UUID matching the one 557ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainregistered with this listening server socket. When successful, {@link 558ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothServerSocket#accept()} will 559d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickreturn a connected {@link android.bluetooth.BluetoothSocket}.</p> 560d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</li> 561d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 562ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<li>Unless you want to accept additional connections, call 563ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothServerSocket#close()}. 564ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>This releases the server socket and all its resources, but does <em>not</em> close the 565ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainconnected {@link android.bluetooth.BluetoothSocket} that's been returned by {@link 566ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothServerSocket#accept()}. Unlike TCP/IP, RFCOMM only allows one 567ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainconnected client per channel at a time, so in most cases it makes sense to call {@link 568ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothServerSocket#close()} on the {@link 569ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothServerSocket} immediately after accepting a connected 570d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormicksocket.</p> 571d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</li> 572d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</ol> 573d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 574ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>The {@link android.bluetooth.BluetoothServerSocket#accept()} call should not 57593dc642eaf48e3db58c4929df26283fbc5fd663fScott Mainbe executed in the main activity UI thread because it is a blocking call and 576ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwill prevent any other interaction with the application. It usually makes 577ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainsense to do all work with a {@link android.bluetooth.BluetoothServerSocket} or {@link 578ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket} in a new 579ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthread managed by your application. To abort a blocked call such as {@link 580ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothServerSocket#accept()}, call {@link 581ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothServerSocket#close()} on the {@link 582ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothServerSocket} (or {@link 583ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket}) from another thread and the blocked call will 584ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainimmediately return. Note that all methods on a {@link 585ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothServerSocket} or {@link android.bluetooth.BluetoothSocket} 586d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickare thread-safe.</p> 587d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 588d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h4>Example</h4> 589d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 590ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Here's a simplified thread for the server component that accepts incoming 591d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickconnections:</p> 592d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<pre> 593ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainprivate class AcceptThread extends Thread { 594ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main private final BluetoothServerSocket mmServerSocket; 595d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 596ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public AcceptThread() { 597ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Use a temporary object that is later assigned to mmServerSocket, 598ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // because mmServerSocket is final 599ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main BluetoothServerSocket tmp = null; 600ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 601ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // MY_UUID is the app's UUID string, also used by the client code 6022785443c6e93c05a4885f4eeb76b12dd8c0e59b5Scott Main tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID); 603ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException e) { } 604ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmServerSocket = tmp; 605ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 606d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 607ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public void run() { 608ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main BluetoothSocket socket = null; 609ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Keep listening until exception occurs or a socket is returned 610ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main while (true) { 611ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 612ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main socket = mmServerSocket.accept(); 613ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException e) { 614ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main break; 615ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 616ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // If a connection was accepted 617ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main if (socket != null) { 618ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Do work to manage the connection (in a separate thread) 619ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main manageConnectedSocket(socket); 620ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmServerSocket.close(); 621ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main break; 622ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 623ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 624ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 625d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 626ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main /** Will cancel the listening socket, and cause the thread to finish */ 627ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public void cancel() { 628ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 629ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmServerSocket.close(); 630ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException e) { } 631ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 632ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main} 633d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</pre> 634d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 635ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>In this example, only one incoming connection is desired, so as soon as a 636ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainconnection is accepted and the {@link android.bluetooth.BluetoothSocket} is 637ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainacquired, the application 638ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainsends the acquired {@link android.bluetooth.BluetoothSocket} to a separate 639ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthread, closes the 640d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick{@link android.bluetooth.BluetoothServerSocket} and breaks the loop.</p> 641d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 642ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Note that when {@link android.bluetooth.BluetoothServerSocket#accept()} 643ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainreturns the {@link android.bluetooth.BluetoothSocket}, the socket is already 644ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainconnected, so you should <em>not</em> call {@link 645ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket#connect()} (as you do from the 646d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickclient-side).</p> 647d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 648ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p><code>manageConnectedSocket()</code> is a fictional method in the application 649ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthat will 650ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maininitiate the thread for transferring data, which is discussed in the section 651d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickabout <a href="#ManagingAConnection">Managing a Connection</a>.</p> 652d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 653ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>You should usually close your {@link android.bluetooth.BluetoothServerSocket} 654ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainas soon as you are done listening for incoming connections. In this example, {@link 655ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothServerSocket#close()} is called as soon 656ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainas the {@link android.bluetooth.BluetoothSocket} is acquired. You may also want 657ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainto provide a public method in your thread that can close the private {@link 658ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket} in the event that you need to stop listening on the 659d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickserver socket.</p> 660d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 661d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 662d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h3 id="ConnectingAsAClient">Connecting as a client</h3> 663d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 664ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>In order to initiate a connection with a remote device (a device holding an 665ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainopen 666ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainserver socket), you must first obtain a {@link 667ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothDevice} object that represents the remote device. 668ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main(Getting a {@link android.bluetooth.BluetoothDevice} is covered in the above 669ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainsection about <a 670ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainhref="#FindingDevices">Finding Devices</a>.) You must then use the 671ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothDevice} to acquire a {@link 672d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickandroid.bluetooth.BluetoothSocket} and initiate the connection.</p> 673d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 674d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<p>Here's the basic procedure:</p> 675d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 676d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<ol> 677ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<li>Using the {@link android.bluetooth.BluetoothDevice}, get a {@link 678ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket} by calling {@link 679ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothDevice#createRfcommSocketToServiceRecord(UUID)}. 680ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>This initializes a {@link android.bluetooth.BluetoothSocket} that will 681ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainconnect to the {@link android.bluetooth.BluetoothDevice}. The UUID passed here 682ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainmust match the UUID used by the server device when it opened its 683ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main{@link android.bluetooth.BluetoothServerSocket} (with {@link 684ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothAdapter#listenUsingRfcommWithServiceRecord(String, 685ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainUUID)}). Using the same UUID is simply a matter of hard-coding the UUID string 686ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maininto your application and then referencing it from both the server and client 687d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickcode.</p> 688d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</li> 689d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 690ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<li>Initiate the connection by calling {@link 691ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket#connect()}. 692ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Upon this call, the system will perform an SDP lookup on the remote device in 693ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainorder to match the UUID. If the lookup is successful and the remote device 694ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainaccepts the connection, it will share the RFCOMM channel to use during the 695ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainconnection and {@link 696ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket#connect()} will return. This method is a 697ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainblocking call. If, for 698ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainany reason, the connection fails or the {@link 699ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket#connect()} method times out (after about 700d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick12 seconds), then it will throw an exception.</p> 701ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Because {@link 702ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket#connect()} is a blocking call, this connection 70393dc642eaf48e3db58c4929df26283fbc5fd663fScott Mainprocedure should always be performed in a thread separate from the main activity 704d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickthread.</p> 705ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p class="note">Note: You should always ensure that the device is not performing 706ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maindevice discovery when you call {@link 707ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket#connect()}. If discovery is in progress, then 708ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthe 709d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickconnection attempt will be significantly slowed and is more likely to fail.</p> 710d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</li> 711d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</ol> 712d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 713d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h4>Example</h4> 714d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 715ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Here is a basic example of a thread that initiates a Bluetooth 716d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickconnection:</p> 717d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<pre> 718ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainprivate class ConnectThread extends Thread { 719ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main private final BluetoothSocket mmSocket; 720ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main private final BluetoothDevice mmDevice; 721d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 722ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public ConnectThread(BluetoothDevice device) { 723ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Use a temporary object that is later assigned to mmSocket, 724ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // because mmSocket is final 725ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main BluetoothSocket tmp = null; 726ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmDevice = device; 727d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 728ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Get a BluetoothSocket to connect with the given BluetoothDevice 729ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 730ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // MY_UUID is the app's UUID string, also used by the server code 731ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main tmp = device.createRfcommSocketToServiceRecord(MY_UUID); 732ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException e) { } 733ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmSocket = tmp; 734ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 735d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 736ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public void run() { 737ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Cancel discovery because it will slow down the connection 7382785443c6e93c05a4885f4eeb76b12dd8c0e59b5Scott Main mBluetoothAdapter.cancelDiscovery(); 739d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 740ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 741ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Connect the device through the socket. This will block 742ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // until it succeeds or throws an exception 743ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmSocket.connect(); 744ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException connectException) { 745ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Unable to connect; close the socket and get out 746ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 747ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmSocket.close(); 748ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException closeException) { } 749ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main return; 750ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 751d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 752ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Do work to manage the connection (in a separate thread) 753ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main manageConnectedSocket(mmSocket); 754ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 755d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 756ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main /** Will cancel an in-progress connection, and close the socket */ 757ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public void cancel() { 758ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 759ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmSocket.close(); 760ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException e) { } 761ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 762ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main} 763d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</pre> 764d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 765ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Notice that {@link android.bluetooth.BluetoothAdapter#cancelDiscovery()} is called 766ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainbefore the connection is made. You should always do this before connecting and it is safe 767ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainto call without actually checking whether it is running or not (but if you do want to 768d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickcheck, call {@link android.bluetooth.BluetoothAdapter#isDiscovering()}).</p> 769d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 770ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p><code>manageConnectedSocket()</code> is a fictional method in the application 771ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainthat will initiate the thread for transferring data, which is discussed in the section 772d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickabout <a href="#ManagingAConnection">Managing a Connection</a>.</p> 773d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 774ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>When you're done with your {@link android.bluetooth.BluetoothSocket}, always 775ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maincall {@link android.bluetooth.BluetoothSocket#close()} to clean up. 776ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainDoing so will immediately close the connected socket and clean up all internal 777d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickresources.</p> 778d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 779d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 780d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h2 id="ManagingAConnection">Managing a Connection</h2> 781d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 782ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>When you have successfully connected two (or more) devices, each one will 783ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainhave a connected {@link android.bluetooth.BluetoothSocket}. This is where the fun 784ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainbegins because you can share data between devices. Using the {@link 785ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket}, the general procedure to transfer arbitrary data is 786d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormicksimple:</p> 787d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<ol> 788ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<li>Get the {@link java.io.InputStream} and {@link java.io.OutputStream} that 789ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainhandle transmissions through the socket, via {@link 790ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainandroid.bluetooth.BluetoothSocket#getInputStream()} and 791d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick{@link android.bluetooth.BluetoothSocket#getOutputStream}, respectively.</li> 792d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 793ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<li>Read and write data to the streams with {@link 794d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickjava.io.InputStream#read(byte[])} and {@link java.io.OutputStream#write(byte[])}.</li> 795d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</ol> 796d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 797d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<p>That's it.</p> 798d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 799ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>There are, of course, implementation details to consider. First and foremost, 800ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainyou should use a dedicated thread for all stream reading and writing. This is 801ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainimportant because both {@link java.io.InputStream#read(byte[])} and {@link 802ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainjava.io.OutputStream#write(byte[])} methods are blocking calls. {@link 803ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainjava.io.InputStream#read(byte[])} will block until there is something to read 804ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainfrom the stream. {@link java.io.OutputStream#write(byte[])} does not usually 805ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainblock, but can block for flow control if the remote device is not calling {@link 806ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainjava.io.InputStream#read(byte[])} quickly enough and the intermediate buffers are full. 807ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainSo, your main loop in the thread should be dedicated to reading from the {@link 808ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainjava.io.InputStream}. A separate public method in the thread can be used to initiate 809d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickwrites to the {@link java.io.OutputStream}.</p> 810d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 811d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h4>Example</h4> 812d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 813d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<p>Here's an example of how this might look:</p> 814d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<pre> 815ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainprivate class ConnectedThread extends Thread { 816ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main private final BluetoothSocket mmSocket; 817ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main private final InputStream mmInStream; 818ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main private final OutputStream mmOutStream; 819d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 820ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public ConnectedThread(BluetoothSocket socket) { 821ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmSocket = socket; 822ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main InputStream tmpIn = null; 823ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main OutputStream tmpOut = null; 824d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 825ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Get the input and output streams, using temp objects because 826ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // member streams are final 827ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 828ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main tmpIn = socket.getInputStream(); 829ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main tmpOut = socket.getOutputStream(); 830ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException e) { } 831d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 832ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmInStream = tmpIn; 833ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmOutStream = tmpOut; 834ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 835d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 836ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public void run() { 837ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main byte[] buffer = new byte[1024]; // buffer store for the stream 838ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main int bytes; // bytes returned from read() 839d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 840ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Keep listening to the InputStream until an exception occurs 841ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main while (true) { 842ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 843ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main // Read from the InputStream 844ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main bytes = mmInStream.read(buffer); 84593dc642eaf48e3db58c4929df26283fbc5fd663fScott Main // Send the obtained bytes to the UI activity 846ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer) 847ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main .sendToTarget(); 848ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException e) { 849ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main break; 850ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 851ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 852ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 853d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 85493dc642eaf48e3db58c4929df26283fbc5fd663fScott Main /* Call this from the main activity to send data to the remote device */ 855ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public void write(byte[] bytes) { 856ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 857ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmOutStream.write(bytes); 858ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException e) { } 859ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 860d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 86193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main /* Call this from the main activity to shutdown the connection */ 862ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main public void cancel() { 863ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main try { 864ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main mmSocket.close(); 865ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } catch (IOException e) { } 866ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main } 867ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main} 868d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</pre> 869d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 870ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>The constructor acquires the necessary streams and once executed, the thread 871ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainwill wait for data to come through the InputStream. When {@link 872ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainjava.io.InputStream#read(byte[])} returns with 87393dc642eaf48e3db58c4929df26283fbc5fd663fScott Mainbytes from the stream, the data is sent to the main activity using a member 874ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainHandler from the parent class. Then it goes back and waits for more bytes from 875d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickthe stream.</p> 876d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 877ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>Sending outgoing data is as simple as calling the thread's 87893dc642eaf48e3db58c4929df26283fbc5fd663fScott Main<code>write()</code> method from the main activity and passing in the bytes to 879ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainbe sent. This method then simply calls {@link 880d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickjava.io.OutputStream#write(byte[])} to send the data to the remote device.</p> 881d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 882ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Main<p>The thread's <code>cancel()</code> method is important so that the connection 883ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Maincan be 884ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott Mainterminated at any time by closing the {@link android.bluetooth.BluetoothSocket}. 885ed2a70d6495b3f1928e36ad2b00ee4d33b2c0379Scott MainThis should always be called when you're done using the Bluetooth 886d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickconnection.</p> 887d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 888d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<div class="special"> 889d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<p>For a demonstration of using the Bluetooth APIs, see the <a 890d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickhref="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat sample app</a>.</p> 891d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</div> 892d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 893d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h2 id="Profiles">Working with Profiles</h2> 894d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 895d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<p>Starting in Android 3.0, the Bluetooth API includes support for working with 896d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickBluetooth profiles. A <em>Bluetooth profile</em> is a wireless interface 897d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickspecification for Bluetooth-based communication between devices. An example 898d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickis the Hands-Free profile. For a mobile phone to connect to a wireless headset, 899d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickboth devices must support the Hands-Free profile. </p> 900d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 901d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<p>You can implement the interface {@link android.bluetooth.BluetoothProfile} to write 902d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickyour own classes to support a particular Bluetooth profile. The Android 903d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickBluetooth API provides implementations for the following Bluetooth 904d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickprofiles:</p> 905d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<ul> 906d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 907d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><strong>Headset</strong>. The Headset profile provides support for 908d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickBluetooth headsets to be used with mobile phones. Android provides the {@link 909d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickandroid.bluetooth.BluetoothHeadset} class, which is a proxy for controlling the 910d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickBluetooth Headset Service via interprocess communication (<a 91150e990c64fa23ce94efa76b9e72df7f8ec3cee6aScott Mainhref="{@docRoot}guide/components/processes-and-threads.html#IPC">IPC</a 912d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick>). This includes both Bluetooth Headset and Hands-Free (v1.5) profiles. The 913d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick{@link android.bluetooth.BluetoothHeadset} class includes support for AT commands. 9142e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickFor more discussion of this topic, see <a href="#AT-Commands">Vendor-specific AT commands</a></li> 915d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 916d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li><strong>A2DP</strong>. The Advanced Audio Distribution Profile (A2DP) 917d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickprofile defines how high quality audio can be streamed from one device to 918d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickanother over a Bluetooth connection. Android provides the {@link 919d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickandroid.bluetooth.BluetoothA2dp} class, which is a proxy for controlling 920d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickthe Bluetooth A2DP Service via IPC.</li> 921d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 9222e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <li><strong>Health Device</strong>. Android 4.0 (API level 14) introduces 9232e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormicksupport for the Bluetooth Health Device Profile (HDP). This lets you create 9242e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickapplications that use Bluetooth to communicate with health devices that support 9252e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickBluetooth, such as heart-rate monitors, blood meters, thermometers, scales, and 9262e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickso on. For a list of supported devices and their corresponding device data 9272e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickspecialization codes, refer to <strong>Bluetooth Assigned Numbers</strong> at <a 9282e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickhref="http://www.bluetooth.org">www.bluetooth.org</a>. Note that these values 9292e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickare also referenced in the ISO/IEEE 11073-20601 [7] specification as 9302e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickMDC_DEV_SPEC_PROFILE_* in the Nomenclature Codes Annex. For more discussion of 9312e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickHDP, see <a href="#HDP">Health Device Profile</a>.</li> 9322e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 933d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</ul> 934d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 935d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<p>Here are the basic steps for working with a profile:</p> 936d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<ol> 937d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 938cd1b08e1e239269f7d0d48119505313f52d3dd5aScott Main <li>Get the default adapter, as described in 93950e990c64fa23ce94efa76b9e72df7f8ec3cee6aScott Main <a href="{@docRoot}guide/topics/connectivity/bluetooth.html#SettingUp">Setting Up 940cd1b08e1e239269f7d0d48119505313f52d3dd5aScott Main Bluetooth</a>.</li> 941d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 942d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li>Use {@link 943d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickandroid.bluetooth.BluetoothAdapter#getProfileProxy(android.content.Context, 944d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickandroid.bluetooth.BluetoothProfile.ServiceListener, int) getProfileProxy()} to 945d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickestablish a connection to the profile proxy object associated with the profile. 946d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickIn the example below, the profile proxy object is an instance of {@link 947d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickandroid.bluetooth.BluetoothHeadset}. </li> 948d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 949d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li>Set up a {@link android.bluetooth.BluetoothProfile.ServiceListener}. This 950d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormicklistener notifies {@link android.bluetooth.BluetoothProfile} IPC clients when 951d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickthey have been connected to or disconnected from the service.</li> 952d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 953d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li>In {@link 954d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickandroid.bluetooth.BluetoothProfile.ServiceListener#onServiceConnected(int, 955d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickandroid.bluetooth.BluetoothProfile) onServiceConnected()}, get a handle 956d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickto the profile proxy object.</li> 957d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 958d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick <li>Once you have the profile proxy object, you can use it to monitor the 959d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickstate of the connection and perform other operations that are relevant to that 960d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickprofile.</li> 961d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</ol> 9622e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 9632e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<p> For example, this code snippet shows how to connect to a {@link 9642e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickandroid.bluetooth.BluetoothHeadset} proxy object so that you can control the 965d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickHeadset profile:</p> 966d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 967d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<pre>BluetoothHeadset mBluetoothHeadset; 968d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 969d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick// Get the default adapter 970d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickBluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 971d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 972d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick// Establish connection to the proxy. 973d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickmBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET); 974d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 975d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickprivate BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() { 976d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick public void onServiceConnected(int profile, BluetoothProfile proxy) { 977d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick if (profile == BluetoothProfile.HEADSET) { 978d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick mBluetoothHeadset = (BluetoothHeadset) proxy; 979d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick } 980d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick } 981d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick public void onServiceDisconnected(int profile) { 982d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick if (profile == BluetoothProfile.HEADSET) { 983d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick mBluetoothHeadset = null; 984d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick } 985d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick } 986d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick}; 987d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 988d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick// ... call functions on mBluetoothHeadset 989d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 990d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick// Close proxy connection after use. 991d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickmBluetoothAdapter.closeProfileProxy(mBluetoothHeadset); 992d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick</pre> 993d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 9942e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 9952e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 996d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<h3 id="AT-Commands">Vendor-specific AT commands</h3> 997d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick 998d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormick<p>Starting in Android 3.0, applications can register to receive system 999d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickbroadcasts of pre-defined vendor-specific AT commands sent by headsets (such as 1000d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormicka Plantronics +XEVENT command). For example, an application could receive 1001d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickbroadcasts that indicate a connected device's battery level and could notify the 1002d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickuser or take other action as needed. Create a broadcast receiver for the {@link 1003d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickandroid.bluetooth.BluetoothHeadset#ACTION_VENDOR_SPECIFIC_HEADSET_EVENT} intent 1004d4fac2c0263fda4b20f253edd594cf909e61eb4eKatie McCormickto handle vendor-specific AT commands for the headset.</p> 10052e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10062e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<h3 id="HDP">Health Device Profile</h3> 10072e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10082e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<p>Android 4.0 (API level 14) introduces support for the Bluetooth Health Device 10092e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickProfile (HDP). This lets you create applications that use Bluetooth to 10102e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickcommunicate with health devices that support Bluetooth, such as heart-rate 10112e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickmonitors, blood meters, thermometers, and scales. The Bluetooth Health API 10122e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickincludes the classes {@link android.bluetooth.BluetoothHealth}, {@link 10132e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickandroid.bluetooth.BluetoothHealthCallback}, and {@link 10142e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickandroid.bluetooth.BluetoothHealthAppConfiguration}, which are described in <a 10152e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickhref="#TheBasics">The Basics</a>. </p> 10162e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10172e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<p>In using the Bluetooth Health API, it's helpful to understand these key HDP concepts:</p> 10182e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<table> 10192e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <tr> 10202e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <th>Concept</th> 10212e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <th>Description</th> 10222e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick </tr> 10232e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <tr> 10242e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <td><strong>Source</strong></td> 10252e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10262e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <td>A role defined in HDP. A <em>source</em> is a health device that 10272e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormicktransmits medical data (weight scale, glucose meter, thermometer, etc.) to a 10282e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormicksmart device such as an Android phone or tablet. </td> 10292e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick </tr> 10302e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <tr> 10312e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <td><strong>Sink</strong></td> 10322e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10332e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <td>A role defined in HDP. In HDP, a <em>sink</em> is the smart device that 10342e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickreceives the medical data. In an Android HDP application, the sink is 10352e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickrepresented by a {@link android.bluetooth.BluetoothHealthAppConfiguration} 10362e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickobject.</td> 10372e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick </tr> 10382e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <tr> 10392e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <td><strong>Registration</strong></td> 10402e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <td>Refers to registering a sink for a particular health device.</td> 10412e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick </tr> 10422e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <tr> 10432e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <td><strong>Connection</strong></td> 10442e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10452e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <td>Refers to opening a channel between a health device and a smart device 10462e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormicksuch as an Android phone or tablet.</td> 10472e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick </tr> 10482e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick</table> 10492e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10502e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<h4>Creating an HDP Application</h4> 10512e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10522e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<p>Here are the basic steps involved in creating an Android HDP application:</p> 10532e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<ol> 10542e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10552e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <li>Get a reference to the {@link android.bluetooth.BluetoothHealth} proxy 10562e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickobject. <p>Similar to regular headset and A2DP profile devices, you must call 10572e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick{@link android.bluetooth.BluetoothAdapter#getProfileProxy getProfileProxy()} 10582e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickwith a {@link android.bluetooth.BluetoothProfile.ServiceListener} and the {@link 10592e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickandroid.bluetooth.BluetoothProfile.ServiceListener#HEALTH} profile type to 10602e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickestablish a connection with the profile proxy object.</p> </li> 10612e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10622e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <li>Create a {@link android.bluetooth.BluetoothHealthCallback} and register an 10632e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickapplication configuration 10642e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick({@link android.bluetooth.BluetoothHealthAppConfiguration}) 10652e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickthat acts as a health 10662e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormicksink.</li> 10672e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10682e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <li>Establish a connection to a health device. Some devices will initiate the 10692e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickconnection. It is unnecessary to carry out this step for those devices.</li> 10702e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10712e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <li>When connected successfully to a health device, read/write to the health 10722e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickdevice using the file descriptor. <p>The received data needs to be interpreted 10732e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickusing a health manager which implements the IEEE 11073-xxxxx 10742e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickspecifications.</p></li> 10752e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10762e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick <li>When done, close the health channel and unregister the application. The 10772e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickchannel also closes when there is extended inactivity.</li> 10782e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick</ol> 10792e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick 10802e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormick<p>For a complete code sample that illustrates these steps, see <a 10812e32a78eadfe8b98d89a376b8ccbea52e32a749cKatie McCormickhref="{@docRoot}resources/samples/BluetoothHDP/index.html">Bluetooth HDP (Health 10826a52c632530fa39de570c9a6630264178c20e58eKatie McCormickDevice Profile)</a>. </p> 1083