BluetoothDevice.java revision 8949bfb90c415629dbd0e30d25003fb3e0375fb5
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.annotation.SdkConstant; 20import android.annotation.SdkConstant.SdkConstantType; 21import android.content.Context; 22import android.os.Parcel; 23import android.os.Parcelable; 24import android.os.ParcelUuid; 25import android.os.RemoteException; 26import android.util.Log; 27 28import java.io.IOException; 29import java.io.UnsupportedEncodingException; 30import java.util.UUID; 31 32/** 33 * Represents a remote Bluetooth device. A {@link BluetoothDevice} lets you 34 * create a connection with the respective device or query information about 35 * it, such as the name, address, class, and bonding state. 36 * 37 * <p>This class is really just a thin wrapper for a Bluetooth hardware 38 * address. Objects of this class are immutable. Operations on this class 39 * are performed on the remote Bluetooth hardware address, using the 40 * {@link BluetoothAdapter} that was used to create this {@link 41 * BluetoothDevice}. 42 * 43 * <p>To get a {@link BluetoothDevice}, use 44 * {@link BluetoothAdapter#getRemoteDevice(String) 45 * BluetoothAdapter.getRemoteDevice(String)} to create one representing a device 46 * of a known MAC address (which you can get through device discovery with 47 * {@link BluetoothAdapter}) or get one from the set of bonded devices 48 * returned by {@link BluetoothAdapter#getBondedDevices() 49 * BluetoothAdapter.getBondedDevices()}. You can then open a 50 * {@link BluetoothSocket} for communication with the remote device, using 51 * {@link #createRfcommSocketToServiceRecord(UUID)}. 52 * 53 * <p class="note"><strong>Note:</strong> 54 * Requires the {@link android.Manifest.permission#BLUETOOTH} permission. 55 * 56 * <div class="special reference"> 57 * <h3>Developer Guides</h3> 58 * <p>For more information about using Bluetooth, read the 59 * <a href="{@docRoot}guide/topics/wireless/bluetooth.html">Bluetooth</a> developer guide.</p> 60 * </div> 61 * 62 * {@see BluetoothAdapter} 63 * {@see BluetoothSocket} 64 */ 65public final class BluetoothDevice implements Parcelable { 66 private static final String TAG = "BluetoothDevice"; 67 private static final boolean DBG = false; 68 69 /** 70 * Sentinel error value for this class. Guaranteed to not equal any other 71 * integer constant in this class. Provided as a convenience for functions 72 * that require a sentinel error value, for example: 73 * <p><code>Intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, 74 * BluetoothDevice.ERROR)</code> 75 */ 76 public static final int ERROR = Integer.MIN_VALUE; 77 78 /** 79 * Broadcast Action: Remote device discovered. 80 * <p>Sent when a remote device is found during discovery. 81 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link 82 * #EXTRA_CLASS}. Can contain the extra fields {@link #EXTRA_NAME} and/or 83 * {@link #EXTRA_RSSI} if they are available. 84 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 85 */ 86 // TODO: Change API to not broadcast RSSI if not available (incoming connection) 87 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 88 public static final String ACTION_FOUND = 89 "android.bluetooth.device.action.FOUND"; 90 91 /** 92 * Broadcast Action: Remote device disappeared. 93 * <p>Sent when a remote device that was found in the last discovery is not 94 * found in the current discovery. 95 * <p>Always contains the extra field {@link #EXTRA_DEVICE}. 96 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 97 * @hide 98 */ 99 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 100 public static final String ACTION_DISAPPEARED = 101 "android.bluetooth.device.action.DISAPPEARED"; 102 103 /** 104 * Broadcast Action: Bluetooth class of a remote device has changed. 105 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link 106 * #EXTRA_CLASS}. 107 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 108 * {@see BluetoothClass} 109 */ 110 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 111 public static final String ACTION_CLASS_CHANGED = 112 "android.bluetooth.device.action.CLASS_CHANGED"; 113 114 /** 115 * Broadcast Action: Indicates a low level (ACL) connection has been 116 * established with a remote device. 117 * <p>Always contains the extra field {@link #EXTRA_DEVICE}. 118 * <p>ACL connections are managed automatically by the Android Bluetooth 119 * stack. 120 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 121 */ 122 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 123 public static final String ACTION_ACL_CONNECTED = 124 "android.bluetooth.device.action.ACL_CONNECTED"; 125 126 /** 127 * Broadcast Action: Indicates that a low level (ACL) disconnection has 128 * been requested for a remote device, and it will soon be disconnected. 129 * <p>This is useful for graceful disconnection. Applications should use 130 * this intent as a hint to immediately terminate higher level connections 131 * (RFCOMM, L2CAP, or profile connections) to the remote device. 132 * <p>Always contains the extra field {@link #EXTRA_DEVICE}. 133 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 134 */ 135 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 136 public static final String ACTION_ACL_DISCONNECT_REQUESTED = 137 "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED"; 138 139 /** 140 * Broadcast Action: Indicates a low level (ACL) disconnection from a 141 * remote device. 142 * <p>Always contains the extra field {@link #EXTRA_DEVICE}. 143 * <p>ACL connections are managed automatically by the Android Bluetooth 144 * stack. 145 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 146 */ 147 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 148 public static final String ACTION_ACL_DISCONNECTED = 149 "android.bluetooth.device.action.ACL_DISCONNECTED"; 150 151 /** 152 * Broadcast Action: Indicates the friendly name of a remote device has 153 * been retrieved for the first time, or changed since the last retrieval. 154 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link 155 * #EXTRA_NAME}. 156 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 157 */ 158 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 159 public static final String ACTION_NAME_CHANGED = 160 "android.bluetooth.device.action.NAME_CHANGED"; 161 162 /** 163 * Broadcast Action: Indicates the alias of a remote device has been 164 * changed. 165 * <p>Always contains the extra field {@link #EXTRA_DEVICE}. 166 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 167 * 168 * @hide 169 */ 170 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 171 public static final String ACTION_ALIAS_CHANGED = 172 "android.bluetooth.device.action.ALIAS_CHANGED"; 173 174 /** 175 * Broadcast Action: Indicates a change in the bond state of a remote 176 * device. For example, if a device is bonded (paired). 177 * <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link 178 * #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}. 179 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 180 */ 181 // Note: When EXTRA_BOND_STATE is BOND_NONE then this will also 182 // contain a hidden extra field EXTRA_REASON with the result code. 183 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 184 public static final String ACTION_BOND_STATE_CHANGED = 185 "android.bluetooth.device.action.BOND_STATE_CHANGED"; 186 187 /** 188 * Used as a Parcelable {@link BluetoothDevice} extra field in every intent 189 * broadcast by this class. It contains the {@link BluetoothDevice} that 190 * the intent applies to. 191 */ 192 public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE"; 193 194 /** 195 * Used as a String extra field in {@link #ACTION_NAME_CHANGED} and {@link 196 * #ACTION_FOUND} intents. It contains the friendly Bluetooth name. 197 */ 198 public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME"; 199 200 /** 201 * Used as an optional short extra field in {@link #ACTION_FOUND} intents. 202 * Contains the RSSI value of the remote device as reported by the 203 * Bluetooth hardware. 204 */ 205 public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI"; 206 207 /** 208 * Used as a Parcelable {@link BluetoothClass} extra field in {@link 209 * #ACTION_FOUND} and {@link #ACTION_CLASS_CHANGED} intents. 210 */ 211 public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS"; 212 213 /** 214 * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents. 215 * Contains the bond state of the remote device. 216 * <p>Possible values are: 217 * {@link #BOND_NONE}, 218 * {@link #BOND_BONDING}, 219 * {@link #BOND_BONDED}. 220 */ 221 public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE"; 222 /** 223 * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents. 224 * Contains the previous bond state of the remote device. 225 * <p>Possible values are: 226 * {@link #BOND_NONE}, 227 * {@link #BOND_BONDING}, 228 * {@link #BOND_BONDED}. 229 */ 230 public static final String EXTRA_PREVIOUS_BOND_STATE = 231 "android.bluetooth.device.extra.PREVIOUS_BOND_STATE"; 232 /** 233 * Indicates the remote device is not bonded (paired). 234 * <p>There is no shared link key with the remote device, so communication 235 * (if it is allowed at all) will be unauthenticated and unencrypted. 236 */ 237 public static final int BOND_NONE = 10; 238 /** 239 * Indicates bonding (pairing) is in progress with the remote device. 240 */ 241 public static final int BOND_BONDING = 11; 242 /** 243 * Indicates the remote device is bonded (paired). 244 * <p>A shared link keys exists locally for the remote device, so 245 * communication can be authenticated and encrypted. 246 * <p><i>Being bonded (paired) with a remote device does not necessarily 247 * mean the device is currently connected. It just means that the pending 248 * procedure was completed at some earlier time, and the link key is still 249 * stored locally, ready to use on the next connection. 250 * </i> 251 */ 252 public static final int BOND_BONDED = 12; 253 254 /** 255 * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST} 256 * intents for unbond reason. 257 * @hide 258 */ 259 public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON"; 260 261 /** 262 * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST} 263 * intents to indicate pairing method used. Possible values are: 264 * {@link #PAIRING_VARIANT_PIN}, 265 * {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION}, 266 */ 267 public static final String EXTRA_PAIRING_VARIANT = 268 "android.bluetooth.device.extra.PAIRING_VARIANT"; 269 270 /** 271 * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST} 272 * intents as the value of passkey. 273 */ 274 public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY"; 275 276 /** 277 * Bluetooth device type, Unknown 278 */ 279 public static final int DEVICE_TYPE_UNKNOWN = 0; 280 281 /** 282 * Bluetooth device type, Classic - BR/EDR devices 283 */ 284 public static final int DEVICE_TYPE_CLASSIC = 1; 285 286 /** 287 * Bluetooth device type, Low Energy - LE-only 288 */ 289 public static final int DEVICE_TYPE_LE = 2; 290 291 /** 292 * Bluetooth device type, Dual Mode - BR/EDR/LE 293 */ 294 public static final int DEVICE_TYPE_DUAL = 3; 295 296 /** 297 * Broadcast Action: This intent is used to broadcast the {@link UUID} 298 * wrapped as a {@link android.os.ParcelUuid} of the remote device after it 299 * has been fetched. This intent is sent only when the UUIDs of the remote 300 * device are requested to be fetched using Service Discovery Protocol 301 * <p> Always contains the extra field {@link #EXTRA_DEVICE} 302 * <p> Always contains the extra field {@link #EXTRA_UUID} 303 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 304 */ 305 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 306 public static final String ACTION_UUID = 307 "android.bluetooth.device.action.UUID"; 308 309 /** @hide */ 310 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 311 public static final String ACTION_MAS_INSTANCE = 312 "android.bluetooth.device.action.MAS_INSTANCE"; 313 314 /** 315 * Broadcast Action: Indicates a failure to retrieve the name of a remote 316 * device. 317 * <p>Always contains the extra field {@link #EXTRA_DEVICE}. 318 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. 319 * @hide 320 */ 321 //TODO: is this actually useful? 322 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 323 public static final String ACTION_NAME_FAILED = 324 "android.bluetooth.device.action.NAME_FAILED"; 325 326 /** 327 * Broadcast Action: This intent is used to broadcast PAIRING REQUEST 328 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} to 329 * receive. 330 */ 331 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 332 public static final String ACTION_PAIRING_REQUEST = 333 "android.bluetooth.device.action.PAIRING_REQUEST"; 334 /** @hide */ 335 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 336 public static final String ACTION_PAIRING_CANCEL = 337 "android.bluetooth.device.action.PAIRING_CANCEL"; 338 339 /** @hide */ 340 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 341 public static final String ACTION_CONNECTION_ACCESS_REQUEST = 342 "android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST"; 343 344 /** @hide */ 345 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 346 public static final String ACTION_CONNECTION_ACCESS_REPLY = 347 "android.bluetooth.device.action.CONNECTION_ACCESS_REPLY"; 348 349 /** @hide */ 350 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 351 public static final String ACTION_CONNECTION_ACCESS_CANCEL = 352 "android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL"; 353 354 /** 355 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intent. 356 * @hide 357 */ 358 public static final String EXTRA_ACCESS_REQUEST_TYPE = 359 "android.bluetooth.device.extra.ACCESS_REQUEST_TYPE"; 360 361 /**@hide*/ 362 public static final int REQUEST_TYPE_PROFILE_CONNECTION = 1; 363 364 /**@hide*/ 365 public static final int REQUEST_TYPE_PHONEBOOK_ACCESS = 2; 366 367 /**@hide*/ 368 public static final int REQUEST_TYPE_MESSAGE_ACCESS = 3; 369 370 /** 371 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents, 372 * Contains package name to return reply intent to. 373 * @hide 374 */ 375 public static final String EXTRA_PACKAGE_NAME = "android.bluetooth.device.extra.PACKAGE_NAME"; 376 377 /** 378 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents, 379 * Contains class name to return reply intent to. 380 * @hide 381 */ 382 public static final String EXTRA_CLASS_NAME = "android.bluetooth.device.extra.CLASS_NAME"; 383 384 /** 385 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intent. 386 * @hide 387 */ 388 public static final String EXTRA_CONNECTION_ACCESS_RESULT = 389 "android.bluetooth.device.extra.CONNECTION_ACCESS_RESULT"; 390 391 /**@hide*/ 392 public static final int CONNECTION_ACCESS_YES = 1; 393 394 /**@hide*/ 395 public static final int CONNECTION_ACCESS_NO = 2; 396 397 /** 398 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intents, 399 * Contains boolean to indicate if the allowed response is once-for-all so that 400 * next request will be granted without asking user again. 401 * @hide 402 */ 403 public static final String EXTRA_ALWAYS_ALLOWED = 404 "android.bluetooth.device.extra.ALWAYS_ALLOWED"; 405 406 /** 407 * A bond attempt succeeded 408 * @hide 409 */ 410 public static final int BOND_SUCCESS = 0; 411 412 /** 413 * A bond attempt failed because pins did not match, or remote device did 414 * not respond to pin request in time 415 * @hide 416 */ 417 public static final int UNBOND_REASON_AUTH_FAILED = 1; 418 419 /** 420 * A bond attempt failed because the other side explicitly rejected 421 * bonding 422 * @hide 423 */ 424 public static final int UNBOND_REASON_AUTH_REJECTED = 2; 425 426 /** 427 * A bond attempt failed because we canceled the bonding process 428 * @hide 429 */ 430 public static final int UNBOND_REASON_AUTH_CANCELED = 3; 431 432 /** 433 * A bond attempt failed because we could not contact the remote device 434 * @hide 435 */ 436 public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4; 437 438 /** 439 * A bond attempt failed because a discovery is in progress 440 * @hide 441 */ 442 public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5; 443 444 /** 445 * A bond attempt failed because of authentication timeout 446 * @hide 447 */ 448 public static final int UNBOND_REASON_AUTH_TIMEOUT = 6; 449 450 /** 451 * A bond attempt failed because of repeated attempts 452 * @hide 453 */ 454 public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7; 455 456 /** 457 * A bond attempt failed because we received an Authentication Cancel 458 * by remote end 459 * @hide 460 */ 461 public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8; 462 463 /** 464 * An existing bond was explicitly revoked 465 * @hide 466 */ 467 public static final int UNBOND_REASON_REMOVED = 9; 468 469 /** 470 * The user will be prompted to enter a pin or 471 * an app will enter a pin for user. 472 */ 473 public static final int PAIRING_VARIANT_PIN = 0; 474 475 /** 476 * The user will be prompted to enter a passkey 477 * @hide 478 */ 479 public static final int PAIRING_VARIANT_PASSKEY = 1; 480 481 /** 482 * The user will be prompted to confirm the passkey displayed on the screen or 483 * an app will confirm the passkey for the user. 484 */ 485 public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2; 486 487 /** 488 * The user will be prompted to accept or deny the incoming pairing request 489 * @hide 490 */ 491 public static final int PAIRING_VARIANT_CONSENT = 3; 492 493 /** 494 * The user will be prompted to enter the passkey displayed on remote device 495 * This is used for Bluetooth 2.1 pairing. 496 * @hide 497 */ 498 public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4; 499 500 /** 501 * The user will be prompted to enter the PIN displayed on remote device. 502 * This is used for Bluetooth 2.0 pairing. 503 * @hide 504 */ 505 public static final int PAIRING_VARIANT_DISPLAY_PIN = 5; 506 507 /** 508 * The user will be prompted to accept or deny the OOB pairing request 509 * @hide 510 */ 511 public static final int PAIRING_VARIANT_OOB_CONSENT = 6; 512 513 /** 514 * Used as an extra field in {@link #ACTION_UUID} intents, 515 * Contains the {@link android.os.ParcelUuid}s of the remote device which 516 * is a parcelable version of {@link UUID}. 517 */ 518 public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID"; 519 520 /** 521 * No preferrence of physical transport for GATT connections to remote dual-mode devices 522 * @hide 523 */ 524 public static final int TRANSPORT_AUTO = 0; 525 526 /** 527 * Prefer BR/EDR transport for GATT connections to remote dual-mode devices 528 * @hide 529 */ 530 public static final int TRANSPORT_BREDR = 1; 531 532 /** 533 * Prefer LE transport for GATT connections to remote dual-mode devices 534 * @hide 535 */ 536 public static final int TRANSPORT_LE = 2; 537 538 /** @hide */ 539 public static final String EXTRA_MAS_INSTANCE = 540 "android.bluetooth.device.extra.MAS_INSTANCE"; 541 542 /** 543 * Lazy initialization. Guaranteed final after first object constructed, or 544 * getService() called. 545 * TODO: Unify implementation of sService amongst BluetoothFoo API's 546 */ 547 private static IBluetooth sService; 548 549 private final String mAddress; 550 551 /*package*/ static IBluetooth getService() { 552 synchronized (BluetoothDevice.class) { 553 if (sService == null) { 554 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 555 sService = adapter.getBluetoothService(mStateChangeCallback); 556 } 557 } 558 return sService; 559 } 560 561 static IBluetoothManagerCallback mStateChangeCallback = new IBluetoothManagerCallback.Stub() { 562 563 public void onBluetoothServiceUp(IBluetooth bluetoothService) 564 throws RemoteException { 565 synchronized (BluetoothDevice.class) { 566 sService = bluetoothService; 567 } 568 } 569 570 public void onBluetoothServiceDown() 571 throws RemoteException { 572 synchronized (BluetoothDevice.class) { 573 sService = null; 574 } 575 } 576 }; 577 /** 578 * Create a new BluetoothDevice 579 * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB", 580 * and is validated in this constructor. 581 * @param address valid Bluetooth MAC address 582 * @throws RuntimeException Bluetooth is not available on this platform 583 * @throws IllegalArgumentException address is invalid 584 * @hide 585 */ 586 /*package*/ BluetoothDevice(String address) { 587 getService(); // ensures sService is initialized 588 if (!BluetoothAdapter.checkBluetoothAddress(address)) { 589 throw new IllegalArgumentException(address + " is not a valid Bluetooth address"); 590 } 591 592 mAddress = address; 593 } 594 595 @Override 596 public boolean equals(Object o) { 597 if (o instanceof BluetoothDevice) { 598 return mAddress.equals(((BluetoothDevice)o).getAddress()); 599 } 600 return false; 601 } 602 603 @Override 604 public int hashCode() { 605 return mAddress.hashCode(); 606 } 607 608 /** 609 * Returns a string representation of this BluetoothDevice. 610 * <p>Currently this is the Bluetooth hardware address, for example 611 * "00:11:22:AA:BB:CC". However, you should always use {@link #getAddress} 612 * if you explicitly require the Bluetooth hardware address in case the 613 * {@link #toString} representation changes in the future. 614 * @return string representation of this BluetoothDevice 615 */ 616 @Override 617 public String toString() { 618 return mAddress; 619 } 620 621 public int describeContents() { 622 return 0; 623 } 624 625 public static final Parcelable.Creator<BluetoothDevice> CREATOR = 626 new Parcelable.Creator<BluetoothDevice>() { 627 public BluetoothDevice createFromParcel(Parcel in) { 628 return new BluetoothDevice(in.readString()); 629 } 630 public BluetoothDevice[] newArray(int size) { 631 return new BluetoothDevice[size]; 632 } 633 }; 634 635 public void writeToParcel(Parcel out, int flags) { 636 out.writeString(mAddress); 637 } 638 639 /** 640 * Returns the hardware address of this BluetoothDevice. 641 * <p> For example, "00:11:22:AA:BB:CC". 642 * @return Bluetooth hardware address as string 643 */ 644 public String getAddress() { 645 if (DBG) Log.d(TAG, "mAddress: " + mAddress); 646 return mAddress; 647 } 648 649 /** 650 * Get the friendly Bluetooth name of the remote device. 651 * 652 * <p>The local adapter will automatically retrieve remote names when 653 * performing a device scan, and will cache them. This method just returns 654 * the name for this device from the cache. 655 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} 656 * 657 * @return the Bluetooth name, or null if there was a problem. 658 */ 659 public String getName() { 660 if (sService == null) { 661 Log.e(TAG, "BT not enabled. Cannot get Remote Device name"); 662 return null; 663 } 664 try { 665 return sService.getRemoteName(this); 666 } catch (RemoteException e) {Log.e(TAG, "", e);} 667 return null; 668 } 669 670 /** 671 * Get the Bluetooth device type of the remote device. 672 * 673 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} 674 * 675 * @return the device type {@link #DEVICE_TYPE_CLASSIC}, {@link #DEVICE_TYPE_LE} 676 * {@link #DEVICE_TYPE_DUAL}. 677 * {@link #DEVICE_TYPE_UNKNOWN} if it's not available 678 */ 679 public int getType() { 680 if (sService == null) { 681 Log.e(TAG, "BT not enabled. Cannot get Remote Device type"); 682 return DEVICE_TYPE_UNKNOWN; 683 } 684 try { 685 return sService.getRemoteType(this); 686 } catch (RemoteException e) {Log.e(TAG, "", e);} 687 return DEVICE_TYPE_UNKNOWN; 688 } 689 690 /** 691 * Get the Bluetooth alias of the remote device. 692 * <p>Alias is the locally modified name of a remote device. 693 * 694 * @return the Bluetooth alias, or null if no alias or there was a problem 695 * @hide 696 */ 697 public String getAlias() { 698 if (sService == null) { 699 Log.e(TAG, "BT not enabled. Cannot get Remote Device Alias"); 700 return null; 701 } 702 try { 703 return sService.getRemoteAlias(this); 704 } catch (RemoteException e) {Log.e(TAG, "", e);} 705 return null; 706 } 707 708 /** 709 * Set the Bluetooth alias of the remote device. 710 * <p>Alias is the locally modified name of a remote device. 711 * <p>This methoid overwrites the alias. The changed 712 * alias is saved in the local storage so that the change 713 * is preserved over power cycle. 714 * 715 * @return true on success, false on error 716 * @hide 717 */ 718 public boolean setAlias(String alias) { 719 if (sService == null) { 720 Log.e(TAG, "BT not enabled. Cannot set Remote Device name"); 721 return false; 722 } 723 try { 724 return sService.setRemoteAlias(this, alias); 725 } catch (RemoteException e) {Log.e(TAG, "", e);} 726 return false; 727 } 728 729 /** 730 * Get the Bluetooth alias of the remote device. 731 * If Alias is null, get the Bluetooth name instead. 732 * @see #getAlias() 733 * @see #getName() 734 * 735 * @return the Bluetooth alias, or null if no alias or there was a problem 736 * @hide 737 */ 738 public String getAliasName() { 739 String name = getAlias(); 740 if (name == null) { 741 name = getName(); 742 } 743 return name; 744 } 745 746 /** 747 * Start the bonding (pairing) process with the remote device. 748 * <p>This is an asynchronous call, it will return immediately. Register 749 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when 750 * the bonding process completes, and its result. 751 * <p>Android system services will handle the necessary user interactions 752 * to confirm and complete the bonding process. 753 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. 754 * 755 * @return false on immediate error, true if bonding will begin 756 */ 757 public boolean createBond() { 758 if (sService == null) { 759 Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device"); 760 return false; 761 } 762 try { 763 return sService.createBond(this); 764 } catch (RemoteException e) {Log.e(TAG, "", e);} 765 return false; 766 } 767 768 /** 769 * Start the bonding (pairing) process with the remote device using the 770 * Out Of Band mechanism. 771 * 772 * <p>This is an asynchronous call, it will return immediately. Register 773 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when 774 * the bonding process completes, and its result. 775 * 776 * <p>Android system services will handle the necessary user interactions 777 * to confirm and complete the bonding process. 778 * 779 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. 780 * 781 * @param hash - Simple Secure pairing hash 782 * @param randomizer - The random key obtained using OOB 783 * @return false on immediate error, true if bonding will begin 784 * 785 * @hide 786 */ 787 public boolean createBondOutOfBand(byte[] hash, byte[] randomizer) { 788 //TODO(BT) 789 /* 790 try { 791 return sService.createBondOutOfBand(this, hash, randomizer); 792 } catch (RemoteException e) {Log.e(TAG, "", e);}*/ 793 return false; 794 } 795 796 /** 797 * Set the Out Of Band data for a remote device to be used later 798 * in the pairing mechanism. Users can obtain this data through other 799 * trusted channels 800 * 801 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. 802 * 803 * @param hash Simple Secure pairing hash 804 * @param randomizer The random key obtained using OOB 805 * @return false on error; true otherwise 806 * 807 * @hide 808 */ 809 public boolean setDeviceOutOfBandData(byte[] hash, byte[] randomizer) { 810 //TODO(BT) 811 /* 812 try { 813 return sService.setDeviceOutOfBandData(this, hash, randomizer); 814 } catch (RemoteException e) {Log.e(TAG, "", e);} */ 815 return false; 816 } 817 818 /** 819 * Cancel an in-progress bonding request started with {@link #createBond}. 820 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. 821 * 822 * @return true on success, false on error 823 * @hide 824 */ 825 public boolean cancelBondProcess() { 826 if (sService == null) { 827 Log.e(TAG, "BT not enabled. Cannot cancel Remote Device bond"); 828 return false; 829 } 830 try { 831 return sService.cancelBondProcess(this); 832 } catch (RemoteException e) {Log.e(TAG, "", e);} 833 return false; 834 } 835 836 /** 837 * Remove bond (pairing) with the remote device. 838 * <p>Delete the link key associated with the remote device, and 839 * immediately terminate connections to that device that require 840 * authentication and encryption. 841 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. 842 * 843 * @return true on success, false on error 844 * @hide 845 */ 846 public boolean removeBond() { 847 if (sService == null) { 848 Log.e(TAG, "BT not enabled. Cannot remove Remote Device bond"); 849 return false; 850 } 851 try { 852 return sService.removeBond(this); 853 } catch (RemoteException e) {Log.e(TAG, "", e);} 854 return false; 855 } 856 857 /** 858 * Get the bond state of the remote device. 859 * <p>Possible values for the bond state are: 860 * {@link #BOND_NONE}, 861 * {@link #BOND_BONDING}, 862 * {@link #BOND_BONDED}. 863 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}. 864 * 865 * @return the bond state 866 */ 867 public int getBondState() { 868 if (sService == null) { 869 Log.e(TAG, "BT not enabled. Cannot get bond state"); 870 return BOND_NONE; 871 } 872 try { 873 return sService.getBondState(this); 874 } catch (RemoteException e) {Log.e(TAG, "", e);} 875 catch (NullPointerException npe) { 876 // Handle case where bluetooth service proxy 877 // is already null. 878 Log.e(TAG, "NullPointerException for getBondState() of device ("+ 879 getAddress()+")", npe); 880 } 881 return BOND_NONE; 882 } 883 884 /** 885 * Returns whether there is an open connection to this device. 886 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}. 887 * 888 * @return True if there is at least one open connection to this device. 889 * @hide 890 */ 891 public boolean isConnected() { 892 if (sService == null) { 893 // BT is not enabled, we cannot be connected. 894 return false; 895 } 896 try { 897 return sService.isConnected(this); 898 } catch (RemoteException e) { 899 Log.e(TAG, "", e); 900 return false; 901 } 902 } 903 904 /** 905 * Get the Bluetooth class of the remote device. 906 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}. 907 * 908 * @return Bluetooth class object, or null on error 909 */ 910 public BluetoothClass getBluetoothClass() { 911 if (sService == null) { 912 Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class"); 913 return null; 914 } 915 try { 916 int classInt = sService.getRemoteClass(this); 917 if (classInt == BluetoothClass.ERROR) return null; 918 return new BluetoothClass(classInt); 919 } catch (RemoteException e) {Log.e(TAG, "", e);} 920 return null; 921 } 922 923 /** 924 * Get trust state of a remote device. 925 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}. 926 * @hide 927 */ 928 public boolean getTrustState() { 929 //TODO(BT) 930 /* 931 try { 932 return sService.getTrustState(this); 933 } catch (RemoteException e) { 934 Log.e(TAG, "", e); 935 }*/ 936 return false; 937 } 938 939 /** 940 * Set trust state for a remote device. 941 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. 942 * @param value the trust state value (true or false) 943 * @hide 944 */ 945 public boolean setTrust(boolean value) { 946 //TODO(BT) 947 /* 948 try { 949 return sService.setTrust(this, value); 950 } catch (RemoteException e) { 951 Log.e(TAG, "", e); 952 }*/ 953 return false; 954 } 955 956 /** 957 * Returns the supported features (UUIDs) of the remote device. 958 * 959 * <p>This method does not start a service discovery procedure to retrieve the UUIDs 960 * from the remote device. Instead, the local cached copy of the service 961 * UUIDs are returned. 962 * <p>Use {@link #fetchUuidsWithSdp} if fresh UUIDs are desired. 963 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}. 964 * 965 * @return the supported features (UUIDs) of the remote device, 966 * or null on error 967 */ 968 public ParcelUuid[] getUuids() { 969 if (sService == null) { 970 Log.e(TAG, "BT not enabled. Cannot get remote device Uuids"); 971 return null; 972 } 973 try { 974 return sService.getRemoteUuids(this); 975 } catch (RemoteException e) {Log.e(TAG, "", e);} 976 return null; 977 } 978 979 /** 980 * Perform a service discovery on the remote device to get the UUIDs supported. 981 * 982 * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent, 983 * with the UUIDs supported by the remote end. If there is an error 984 * in getting the SDP records or if the process takes a long time, 985 * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently 986 * present in the cache. Clients should use the {@link #getUuids} to get UUIDs 987 * if service discovery is not to be performed. 988 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}. 989 * 990 * @return False if the sanity check fails, True if the process 991 * of initiating an ACL connection to the remote device 992 * was started. 993 */ 994 public boolean fetchUuidsWithSdp() { 995 IBluetooth service = sService; 996 if (service == null) { 997 Log.e(TAG, "BT not enabled. Cannot fetchUuidsWithSdp"); 998 return false; 999 } 1000 try { 1001 return service.fetchRemoteUuids(this); 1002 } catch (RemoteException e) {Log.e(TAG, "", e);} 1003 return false; 1004 } 1005 1006 /** @hide */ 1007 public boolean fetchMasInstances() { 1008 if (sService == null) { 1009 Log.e(TAG, "BT not enabled. Cannot query remote device for MAS instances"); 1010 return false; 1011 } 1012 try { 1013 return sService.fetchRemoteMasInstances(this); 1014 } catch (RemoteException e) {Log.e(TAG, "", e);} 1015 return false; 1016 } 1017 1018 /** @hide */ 1019 public int getServiceChannel(ParcelUuid uuid) { 1020 //TODO(BT) 1021 /* 1022 try { 1023 return sService.getRemoteServiceChannel(this, uuid); 1024 } catch (RemoteException e) {Log.e(TAG, "", e);}*/ 1025 return BluetoothDevice.ERROR; 1026 } 1027 1028 /** 1029 * Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN} 1030 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. 1031 * 1032 * @return true pin has been set 1033 * false for error 1034 */ 1035 public boolean setPin(byte[] pin) { 1036 if (sService == null) { 1037 Log.e(TAG, "BT not enabled. Cannot set Remote Device pin"); 1038 return false; 1039 } 1040 try { 1041 return sService.setPin(this, true, pin.length, pin); 1042 } catch (RemoteException e) {Log.e(TAG, "", e);} 1043 return false; 1044 } 1045 1046 /** @hide */ 1047 public boolean setPasskey(int passkey) { 1048 //TODO(BT) 1049 /* 1050 try { 1051 return sService.setPasskey(this, true, 4, passkey); 1052 } catch (RemoteException e) {Log.e(TAG, "", e);}*/ 1053 return false; 1054 } 1055 1056 /** 1057 * Confirm passkey for {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION} pairing. 1058 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}. 1059 * 1060 * @return true confirmation has been sent out 1061 * false for error 1062 */ 1063 public boolean setPairingConfirmation(boolean confirm) { 1064 if (sService == null) { 1065 Log.e(TAG, "BT not enabled. Cannot set pairing confirmation"); 1066 return false; 1067 } 1068 try { 1069 return sService.setPairingConfirmation(this, confirm); 1070 } catch (RemoteException e) {Log.e(TAG, "", e);} 1071 return false; 1072 } 1073 1074 /** @hide */ 1075 public boolean setRemoteOutOfBandData() { 1076 // TODO(BT) 1077 /* 1078 try { 1079 return sService.setRemoteOutOfBandData(this); 1080 } catch (RemoteException e) {Log.e(TAG, "", e);}*/ 1081 return false; 1082 } 1083 1084 /** @hide */ 1085 public boolean cancelPairingUserInput() { 1086 if (sService == null) { 1087 Log.e(TAG, "BT not enabled. Cannot create pairing user input"); 1088 return false; 1089 } 1090 try { 1091 return sService.cancelBondProcess(this); 1092 } catch (RemoteException e) {Log.e(TAG, "", e);} 1093 return false; 1094 } 1095 1096 /** @hide */ 1097 public boolean isBluetoothDock() { 1098 // TODO(BT) 1099 /* 1100 try { 1101 return sService.isBluetoothDock(this); 1102 } catch (RemoteException e) {Log.e(TAG, "", e);}*/ 1103 return false; 1104 } 1105 1106 /** 1107 * Create an RFCOMM {@link BluetoothSocket} ready to start a secure 1108 * outgoing connection to this remote device on given channel. 1109 * <p>The remote device will be authenticated and communication on this 1110 * socket will be encrypted. 1111 * <p> Use this socket only if an authenticated socket link is possible. 1112 * Authentication refers to the authentication of the link key to 1113 * prevent man-in-the-middle type of attacks. 1114 * For example, for Bluetooth 2.1 devices, if any of the devices does not 1115 * have an input and output capability or just has the ability to 1116 * display a numeric key, a secure socket connection is not possible. 1117 * In such a case, use {#link createInsecureRfcommSocket}. 1118 * For more details, refer to the Security Model section 5.2 (vol 3) of 1119 * Bluetooth Core Specification version 2.1 + EDR. 1120 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing 1121 * connection. 1122 * <p>Valid RFCOMM channels are in range 1 to 30. 1123 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} 1124 * 1125 * @param channel RFCOMM channel to connect to 1126 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection 1127 * @throws IOException on error, for example Bluetooth not available, or 1128 * insufficient permissions 1129 * @hide 1130 */ 1131 public BluetoothSocket createRfcommSocket(int channel) throws IOException { 1132 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel, 1133 null); 1134 } 1135 1136 /** 1137 * Create an RFCOMM {@link BluetoothSocket} ready to start a secure 1138 * outgoing connection to this remote device using SDP lookup of uuid. 1139 * <p>This is designed to be used with {@link 1140 * BluetoothAdapter#listenUsingRfcommWithServiceRecord} for peer-peer 1141 * Bluetooth applications. 1142 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing 1143 * connection. This will also perform an SDP lookup of the given uuid to 1144 * determine which channel to connect to. 1145 * <p>The remote device will be authenticated and communication on this 1146 * socket will be encrypted. 1147 * <p> Use this socket only if an authenticated socket link is possible. 1148 * Authentication refers to the authentication of the link key to 1149 * prevent man-in-the-middle type of attacks. 1150 * For example, for Bluetooth 2.1 devices, if any of the devices does not 1151 * have an input and output capability or just has the ability to 1152 * display a numeric key, a secure socket connection is not possible. 1153 * In such a case, use {#link createInsecureRfcommSocketToServiceRecord}. 1154 * For more details, refer to the Security Model section 5.2 (vol 3) of 1155 * Bluetooth Core Specification version 2.1 + EDR. 1156 * <p>Hint: If you are connecting to a Bluetooth serial board then try 1157 * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB. 1158 * However if you are connecting to an Android peer then please generate 1159 * your own unique UUID. 1160 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} 1161 * 1162 * @param uuid service record uuid to lookup RFCOMM channel 1163 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection 1164 * @throws IOException on error, for example Bluetooth not available, or 1165 * insufficient permissions 1166 */ 1167 public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException { 1168 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1, 1169 new ParcelUuid(uuid)); 1170 } 1171 1172 /** 1173 * Create an RFCOMM {@link BluetoothSocket} socket ready to start an insecure 1174 * outgoing connection to this remote device using SDP lookup of uuid. 1175 * <p> The communication channel will not have an authenticated link key 1176 * i.e it will be subject to man-in-the-middle attacks. For Bluetooth 2.1 1177 * devices, the link key will be encrypted, as encryption is mandatory. 1178 * For legacy devices (pre Bluetooth 2.1 devices) the link key will 1179 * be not be encrypted. Use {@link #createRfcommSocketToServiceRecord} if an 1180 * encrypted and authenticated communication channel is desired. 1181 * <p>This is designed to be used with {@link 1182 * BluetoothAdapter#listenUsingInsecureRfcommWithServiceRecord} for peer-peer 1183 * Bluetooth applications. 1184 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing 1185 * connection. This will also perform an SDP lookup of the given uuid to 1186 * determine which channel to connect to. 1187 * <p>The remote device will be authenticated and communication on this 1188 * socket will be encrypted. 1189 * <p>Hint: If you are connecting to a Bluetooth serial board then try 1190 * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB. 1191 * However if you are connecting to an Android peer then please generate 1192 * your own unique UUID. 1193 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} 1194 * 1195 * @param uuid service record uuid to lookup RFCOMM channel 1196 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection 1197 * @throws IOException on error, for example Bluetooth not available, or 1198 * insufficient permissions 1199 */ 1200 public BluetoothSocket createInsecureRfcommSocketToServiceRecord(UUID uuid) throws IOException { 1201 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, -1, 1202 new ParcelUuid(uuid)); 1203 } 1204 1205 /** 1206 * Construct an insecure RFCOMM socket ready to start an outgoing 1207 * connection. 1208 * Call #connect on the returned #BluetoothSocket to begin the connection. 1209 * The remote device will not be authenticated and communication on this 1210 * socket will not be encrypted. 1211 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 1212 * 1213 * @param port remote port 1214 * @return An RFCOMM BluetoothSocket 1215 * @throws IOException On error, for example Bluetooth not available, or 1216 * insufficient permissions. 1217 * @hide 1218 */ 1219 public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException { 1220 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port, 1221 null); 1222 } 1223 1224 /** 1225 * Construct a SCO socket ready to start an outgoing connection. 1226 * Call #connect on the returned #BluetoothSocket to begin the connection. 1227 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} 1228 * 1229 * @return a SCO BluetoothSocket 1230 * @throws IOException on error, for example Bluetooth not available, or 1231 * insufficient permissions. 1232 * @hide 1233 */ 1234 public BluetoothSocket createScoSocket() throws IOException { 1235 return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null); 1236 } 1237 1238 /** 1239 * Check that a pin is valid and convert to byte array. 1240 * 1241 * Bluetooth pin's are 1 to 16 bytes of UTF-8 characters. 1242 * @param pin pin as java String 1243 * @return the pin code as a UTF-8 byte array, or null if it is an invalid 1244 * Bluetooth pin. 1245 * @hide 1246 */ 1247 public static byte[] convertPinToBytes(String pin) { 1248 if (pin == null) { 1249 return null; 1250 } 1251 byte[] pinBytes; 1252 try { 1253 pinBytes = pin.getBytes("UTF-8"); 1254 } catch (UnsupportedEncodingException uee) { 1255 Log.e(TAG, "UTF-8 not supported?!?"); // this should not happen 1256 return null; 1257 } 1258 if (pinBytes.length <= 0 || pinBytes.length > 16) { 1259 return null; 1260 } 1261 return pinBytes; 1262 } 1263 1264 /** 1265 * Connect to GATT Server hosted by this device. Caller acts as GATT client. 1266 * The callback is used to deliver results to Caller, such as connection status as well 1267 * as any further GATT client operations. 1268 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct 1269 * GATT client operations. 1270 * @param callback GATT callback handler that will receive asynchronous callbacks. 1271 * @param autoConnect Whether to directly connect to the remote device (false) 1272 * or to automatically connect as soon as the remote 1273 * device becomes available (true). 1274 * @throws IllegalArgumentException if callback is null 1275 */ 1276 public BluetoothGatt connectGatt(Context context, boolean autoConnect, 1277 BluetoothGattCallback callback) { 1278 return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO)); 1279 } 1280 1281 /** 1282 * Connect to GATT Server hosted by this device. Caller acts as GATT client. 1283 * The callback is used to deliver results to Caller, such as connection status as well 1284 * as any further GATT client operations. 1285 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct 1286 * GATT client operations. 1287 * @param callback GATT callback handler that will receive asynchronous callbacks. 1288 * @param autoConnect Whether to directly connect to the remote device (false) 1289 * or to automatically connect as soon as the remote 1290 * device becomes available (true). 1291 * @param transport preferred transport for GATT connections to remote dual-mode devices 1292 * {@link BluetoothDevice#TRANSPORT_AUTO} or 1293 * {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE} 1294 * @throws IllegalArgumentException if callback is null 1295 * @hide 1296 */ 1297 public BluetoothGatt connectGatt(Context context, boolean autoConnect, 1298 BluetoothGattCallback callback, int transport) { 1299 // TODO(Bluetooth) check whether platform support BLE 1300 // Do the check here or in GattServer? 1301 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 1302 IBluetoothManager managerService = adapter.getBluetoothManager(); 1303 try { 1304 IBluetoothGatt iGatt = managerService.getBluetoothGatt(); 1305 if (iGatt == null) { 1306 // BLE is not supported 1307 return null; 1308 } 1309 BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this, transport); 1310 gatt.connect(autoConnect, callback); 1311 return gatt; 1312 } catch (RemoteException e) {Log.e(TAG, "", e);} 1313 return null; 1314 } 1315 1316} 1317