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