BluetoothAdapter.java revision bd022f423a33f0794bb53e5b0720da2d67e4631c
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.bluetooth; 18 19import android.os.RemoteException; 20import android.util.Log; 21 22import java.io.IOException; 23import java.util.Collections; 24import java.util.Set; 25import java.util.HashSet; 26 27/** 28 * Represents the local Bluetooth adapter. 29 * 30 * @hide 31 */ 32public final class BluetoothAdapter { 33 private static final String TAG = "BluetoothAdapter"; 34 35 public static final int BLUETOOTH_STATE_OFF = 0; 36 public static final int BLUETOOTH_STATE_TURNING_ON = 1; 37 public static final int BLUETOOTH_STATE_ON = 2; 38 public static final int BLUETOOTH_STATE_TURNING_OFF = 3; 39 40 /** Inquiry scan and page scan are both off. 41 * Device is neither discoverable nor connectable */ 42 public static final int SCAN_MODE_NONE = 0; 43 /** Page scan is on, inquiry scan is off. 44 * Device is connectable, but not discoverable */ 45 public static final int SCAN_MODE_CONNECTABLE = 1; 46 /** Page scan and inquiry scan are on. 47 * Device is connectable and discoverable */ 48 public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 3; 49 50 public static final int RESULT_FAILURE = -1; 51 public static final int RESULT_SUCCESS = 0; 52 53 /* The user will be prompted to enter a pin */ 54 public static final int PAIRING_VARIANT_PIN = 0; 55 /* The user will be prompted to enter a passkey */ 56 public static final int PAIRING_VARIANT_PASSKEY = 1; 57 /* The user will be prompted to confirm the passkey displayed on the screen */ 58 public static final int PAIRING_VARIANT_CONFIRMATION = 2; 59 60 private final IBluetooth mService; 61 62 /** 63 * Do not use this constructor. Use Context.getSystemService() instead. 64 * @hide 65 */ 66 public BluetoothAdapter(IBluetooth service) { 67 if (service == null) { 68 throw new IllegalArgumentException("service is null"); 69 } 70 mService = service; 71 } 72 73 /** 74 * Get the remote BluetoothDevice associated with the given MAC address. 75 * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB". 76 * @param address valid Bluetooth MAC address 77 */ 78 public BluetoothDevice getRemoteDevice(String address) { 79 return new BluetoothDevice(address); 80 } 81 82 /** 83 * Is Bluetooth currently turned on. 84 * 85 * @return true if Bluetooth enabled, false otherwise. 86 */ 87 public boolean isEnabled() { 88 try { 89 return mService.isEnabled(); 90 } catch (RemoteException e) {Log.e(TAG, "", e);} 91 return false; 92 } 93 94 /** 95 * Get the current state of Bluetooth. 96 * 97 * @return One of BLUETOOTH_STATE_ or BluetoothError.ERROR. 98 */ 99 public int getBluetoothState() { 100 try { 101 return mService.getBluetoothState(); 102 } catch (RemoteException e) {Log.e(TAG, "", e);} 103 return BluetoothError.ERROR; 104 } 105 106 /** 107 * Enable the Bluetooth device. 108 * Turn on the underlying hardware. 109 * This is an asynchronous call, 110 * BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION can be used to check if 111 * and when the device is sucessfully enabled. 112 * @return false if we cannot enable the Bluetooth device. True does not 113 * imply the device was enabled, it only implies that so far there were no 114 * problems. 115 */ 116 public boolean enable() { 117 try { 118 return mService.enable(); 119 } catch (RemoteException e) {Log.e(TAG, "", e);} 120 return false; 121 } 122 123 /** 124 * Disable the Bluetooth device. 125 * This turns off the underlying hardware. 126 * 127 * @return true if successful, false otherwise. 128 */ 129 public boolean disable() { 130 try { 131 return mService.disable(true); 132 } catch (RemoteException e) {Log.e(TAG, "", e);} 133 return false; 134 } 135 136 public String getAddress() { 137 try { 138 return mService.getAddress(); 139 } catch (RemoteException e) {Log.e(TAG, "", e);} 140 return null; 141 } 142 143 /** 144 * Get the friendly Bluetooth name of this device. 145 * 146 * This name is visible to remote Bluetooth devices. Currently it is only 147 * possible to retrieve the Bluetooth name when Bluetooth is enabled. 148 * 149 * @return the Bluetooth name, or null if there was a problem. 150 */ 151 public String getName() { 152 try { 153 return mService.getName(); 154 } catch (RemoteException e) {Log.e(TAG, "", e);} 155 return null; 156 } 157 158 /** 159 * Set the friendly Bluetooth name of this device. 160 * 161 * This name is visible to remote Bluetooth devices. The Bluetooth Service 162 * is responsible for persisting this name. 163 * 164 * @param name the name to set 165 * @return true, if the name was successfully set. False otherwise. 166 */ 167 public boolean setName(String name) { 168 try { 169 return mService.setName(name); 170 } catch (RemoteException e) {Log.e(TAG, "", e);} 171 return false; 172 } 173 174 /** 175 * Get the current scan mode. 176 * Used to determine if the local device is connectable and/or discoverable 177 * @return Scan mode, one of SCAN_MODE_* or an error code 178 */ 179 public int getScanMode() { 180 try { 181 return mService.getScanMode(); 182 } catch (RemoteException e) {Log.e(TAG, "", e);} 183 return BluetoothError.ERROR_IPC; 184 } 185 186 /** 187 * Set the current scan mode. 188 * Used to make the local device connectable and/or discoverable 189 * @param scanMode One of SCAN_MODE_* 190 */ 191 public void setScanMode(int scanMode) { 192 try { 193 mService.setScanMode(scanMode); 194 } catch (RemoteException e) {Log.e(TAG, "", e);} 195 } 196 197 public int getDiscoverableTimeout() { 198 try { 199 return mService.getDiscoverableTimeout(); 200 } catch (RemoteException e) {Log.e(TAG, "", e);} 201 return -1; 202 } 203 204 public void setDiscoverableTimeout(int timeout) { 205 try { 206 mService.setDiscoverableTimeout(timeout); 207 } catch (RemoteException e) {Log.e(TAG, "", e);} 208 } 209 210 public boolean startDiscovery() { 211 try { 212 return mService.startDiscovery(); 213 } catch (RemoteException e) {Log.e(TAG, "", e);} 214 return false; 215 } 216 217 public void cancelDiscovery() { 218 try { 219 mService.cancelDiscovery(); 220 } catch (RemoteException e) {Log.e(TAG, "", e);} 221 } 222 223 public boolean isDiscovering() { 224 try { 225 return mService.isDiscovering(); 226 } catch (RemoteException e) {Log.e(TAG, "", e);} 227 return false; 228 } 229 230 /** 231 * List remote devices that are bonded (paired) to the local adapter. 232 * 233 * Bonding (pairing) is the process by which the user enters a pin code for 234 * the device, which generates a shared link key, allowing for 235 * authentication and encryption of future connections. In Android we 236 * require bonding before RFCOMM or SCO connections can be made to a remote 237 * device. 238 * 239 * This function lists which remote devices we have a link key for. It does 240 * not cause any RF transmission, and does not check if the remote device 241 * still has it's link key with us. If the other side no longer has its 242 * link key then the RFCOMM or SCO connection attempt will result in an 243 * error. 244 * 245 * This function does not check if the remote device is in range. 246 * 247 * Remote devices that have an in-progress bonding attempt are not 248 * returned. 249 * 250 * @return unmodifiable set of bonded devices, or null on error 251 */ 252 public Set<BluetoothDevice> getBondedDevices() { 253 try { 254 return toDeviceSet(mService.listBonds()); 255 } catch (RemoteException e) {Log.e(TAG, "", e);} 256 return null; 257 } 258 259 /** 260 * Construct a listening, secure RFCOMM server socket. 261 * The remote device connecting to this socket will be authenticated and 262 * communication on this socket will be encrypted. 263 * Call #accept to retrieve connections to this socket. 264 * @return An RFCOMM BluetoothServerSocket 265 * @throws IOException On error, for example Bluetooth not available, or 266 * insufficient permissions. 267 */ 268 public BluetoothServerSocket listenUsingRfcommOn(int port) throws IOException { 269 BluetoothServerSocket socket = new BluetoothServerSocket( 270 BluetoothSocket.TYPE_RFCOMM, true, true, port); 271 try { 272 socket.mSocket.bindListenNative(); 273 } catch (IOException e) { 274 try { 275 socket.close(); 276 } catch (IOException e2) { } 277 throw e; 278 } 279 return socket; 280 } 281 282 /** 283 * Construct an unencrypted, unauthenticated, RFCOMM server socket. 284 * Call #accept to retrieve connections to this socket. 285 * @return An RFCOMM BluetoothServerSocket 286 * @throws IOException On error, for example Bluetooth not available, or 287 * insufficient permissions. 288 */ 289 public BluetoothServerSocket listenUsingInsecureRfcommOn(int port) throws IOException { 290 BluetoothServerSocket socket = new BluetoothServerSocket( 291 BluetoothSocket.TYPE_RFCOMM, false, false, port); 292 try { 293 socket.mSocket.bindListenNative(); 294 } catch (IOException e) { 295 try { 296 socket.close(); 297 } catch (IOException e2) { } 298 throw e; 299 } 300 return socket; 301 } 302 303 /** 304 * Construct a SCO server socket. 305 * Call #accept to retrieve connections to this socket. 306 * @return A SCO BluetoothServerSocket 307 * @throws IOException On error, for example Bluetooth not available, or 308 * insufficient permissions. 309 */ 310 public static BluetoothServerSocket listenUsingScoOn() throws IOException { 311 BluetoothServerSocket socket = new BluetoothServerSocket( 312 BluetoothSocket.TYPE_SCO, false, false, -1); 313 try { 314 socket.mSocket.bindListenNative(); 315 } catch (IOException e) { 316 try { 317 socket.close(); 318 } catch (IOException e2) { } 319 throw e; 320 } 321 return socket; 322 } 323 324 private Set<BluetoothDevice> toDeviceSet(String[] addresses) { 325 Set<BluetoothDevice> devices = new HashSet<BluetoothDevice>(addresses.length); 326 for (int i = 0; i < addresses.length; i++) { 327 devices.add(getRemoteDevice(addresses[i])); 328 } 329 return Collections.unmodifiableSet(devices); 330 } 331} 332