blob: 849e6c7b246414f5db974734cb428d9fbe540aa2 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
Nick Pellybd022f42009-08-14 18:33:38 -07002 * Copyright (C) 2009 The Android Open Source Project
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003 *
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
Nick Pelly005b2282009-09-10 10:21:56 -070019import android.annotation.SdkConstant;
20import android.annotation.SdkConstant.SdkConstantType;
Nick Pellybd022f42009-08-14 18:33:38 -070021import android.os.IBinder;
22import android.os.Parcel;
23import android.os.Parcelable;
Nick Pellyaef439e2009-09-28 12:33:17 -070024import android.os.ParcelUuid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.os.RemoteException;
Nick Pellybd022f42009-08-14 18:33:38 -070026import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.util.Log;
28
Nick Pellybd022f42009-08-14 18:33:38 -070029import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import java.io.UnsupportedEncodingException;
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -070031import java.util.UUID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032
33/**
Nick Pellybd022f42009-08-14 18:33:38 -070034 * Represents a remote Bluetooth device.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035 *
Nick Pelly45e27042009-08-19 11:00:00 -070036 * <p>Use {@link BluetoothAdapter#getRemoteDevice} to create a {@link
37 * BluetoothDevice}.
38 *
39 * <p>This class is really just a thin wrapper for a Bluetooth hardware
40 * address. Objects of this class are immutable. Operations on this class
41 * are performed on the remote Bluetooth hardware address, using the
42 * {@link BluetoothAdapter} that was used to create this {@link
43 * BluetoothDevice}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044 */
Nick Pellybd022f42009-08-14 18:33:38 -070045public final class BluetoothDevice implements Parcelable {
46 private static final String TAG = "BluetoothDevice";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
Nick Pellyb24e11b2009-09-08 17:40:43 -070048 /**
49 * Sentinel error value for this class. Guaranteed to not equal any other
50 * integer constant in this class. Provided as a convenience for functions
51 * that require a sentinel error value, for example:
Nick Pelly005b2282009-09-10 10:21:56 -070052 * <p><code>Intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
53 * BluetoothDevice.ERROR)</code>
Nick Pellyb24e11b2009-09-08 17:40:43 -070054 */
Nick Pelly005b2282009-09-10 10:21:56 -070055 public static final int ERROR = Integer.MIN_VALUE;
Nick Pellyb24e11b2009-09-08 17:40:43 -070056
Nick Pelly005b2282009-09-10 10:21:56 -070057 /**
58 * Broadcast Action: Remote device discovered.
59 * <p>Sent when a remote device is found during discovery.
60 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
61 * #EXTRA_CLASS}. Can contain the extra fields {@link #EXTRA_NAME} and/or
62 * {@link #EXTRA_RSSI} if they are available.
63 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
64 */
65 // TODO: Change API to not broadcast RSSI if not available (incoming connection)
66 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
67 public static final String ACTION_FOUND =
68 "android.bluetooth.device.action.FOUND";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
Nick Pelly005b2282009-09-10 10:21:56 -070070 /**
71 * Broadcast Action: Remote device disappeared.
72 * <p>Sent when a remote device that was found in the last discovery is not
73 * found in the current discovery.
74 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
75 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
76 * @hide
77 */
78 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
79 public static final String ACTION_DISAPPEARED =
80 "android.bluetooth.device.action.DISAPPEARED";
81
82 /**
83 * Broadcast Action: Bluetooth class of a remote device has changed.
84 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
85 * #EXTRA_CLASS}.
86 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
87 * @see {@link BluetoothClass}
88 */
89 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
90 public static final String ACTION_CLASS_CHANGED =
91 "android.bluetooth.device.action.CLASS_CHANGED";
92
93 /**
94 * Broadcast Action: Indicates a low level (ACL) connection has been
95 * established with a remote device.
96 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
97 * <p>ACL connections are managed automatically by the Android Bluetooth
98 * stack.
99 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
100 */
101 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
102 public static final String ACTION_ACL_CONNECTED =
103 "android.bluetooth.device.action.ACL_CONNECTED";
104
105 /**
106 * Broadcast Action: Indicates that a low level (ACL) disconnection has
107 * been requested for a remote device, and it will soon be disconnected.
108 * <p>This is useful for graceful disconnection. Applications should use
109 * this intent as a hint to immediately terminate higher level connections
110 * (RFCOMM, L2CAP, or profile connections) to the remote device.
111 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
112 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
113 */
114 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
115 public static final String ACTION_ACL_DISCONNECT_REQUESTED =
116 "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
117
118 /**
119 * Broadcast Action: Indicates a low level (ACL) disconnection from a
120 * remote device.
121 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
122 * <p>ACL connections are managed automatically by the Android Bluetooth
123 * stack.
124 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
125 */
126 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
127 public static final String ACTION_ACL_DISCONNECTED =
128 "android.bluetooth.device.action.ACL_DISCONNECTED";
129
130 /**
131 * Broadcast Action: Indicates the friendly name of a remote device has
132 * been retrieved for the first time, or changed since the last retrieval.
133 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
134 * #EXTRA_NAME}.
135 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
136 */
137 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
138 public static final String ACTION_NAME_CHANGED =
139 "android.bluetooth.device.action.NAME_CHANGED";
140
141 /**
142 * Broadcast Action: Indicates a change in the bond state of a remote
143 * device. For example, if a device is bonded (paired).
144 * <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link
145 * #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}.
146 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
147 */
148 // Note: When EXTRA_BOND_STATE is BOND_NONE then this will also
149 // contain a hidden extra field EXTRA_REASON with the result code.
150 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
151 public static final String ACTION_BOND_STATE_CHANGED =
152 "android.bluetooth.device.action.BOND_STATE_CHANGED";
153
154 /**
155 * Used as a Parcelable {@link BluetoothDevice} extra field in every intent
156 * broadcast by this class. It contains the {@link BluetoothDevice} that
157 * the intent applies to.
158 */
159 public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
160
161 /**
162 * Used as a String extra field in {@link #ACTION_NAME_CHANGED} and {@link
163 * #ACTION_FOUND} intents. It contains the friendly Bluetooth name.
164 */
165 public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
166
167 /**
168 * Used as an optional short extra field in {@link #ACTION_FOUND} intents.
169 * Contains the RSSI value of the remote device as reported by the
170 * Bluetooth hardware.
171 */
172 public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
173
174 /**
175 * Used as an Parcelable {@link BluetoothClass} extra field in {@link
176 * #ACTION_FOUND} and {@link #ACTION_CLASS_CHANGED} intents.
177 */
178 public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
179
180 /**
181 * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
182 * Contains the bond state of the remote device.
183 * <p>Possible values are:
184 * {@link #BOND_NONE},
185 * {@link #BOND_BONDING},
186 * {@link #BOND_BONDED}.
187 */
188 public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
189 /**
190 * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
191 * Contains the previous bond state of the remote device.
192 * <p>Possible values are:
193 * {@link #BOND_NONE},
194 * {@link #BOND_BONDING},
195 * {@link #BOND_BONDED}.
196 */
197 public static final String EXTRA_PREVIOUS_BOND_STATE =
198 "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
199 /**
200 * Indicates the remote device is not bonded (paired).
201 * <p>There is no shared link key with the remote device, so communication
202 * (if it is allowed at all) will be unauthenticated and unencrypted.
203 */
204 public static final int BOND_NONE = 10;
205 /**
206 * Indicates bonding (pairing) is in progress with the remote device.
207 */
208 public static final int BOND_BONDING = 11;
209 /**
210 * Indicates the remote device is bonded (paired).
211 * <p>A shared link keys exists locally for the remote device, so
212 * communication can be authenticated and encrypted.
213 * <p><i>Being bonded (paired) with a remote device does not necessarily
214 * mean the device is currently connected. It just means that the ponding
215 * procedure was compeleted at some earlier time, and the link key is still
216 * stored locally, ready to use on the next connection.
217 * </i>
218 */
219 public static final int BOND_BONDED = 12;
220
221 /** @hide */
222 public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
223 /** @hide */
224 public static final String EXTRA_PAIRING_VARIANT =
225 "android.bluetooth.device.extra.PAIRING_VARIANT";
226 /** @hide */
227 public static final String EXTRA_PASSKEY = "android.bluetooth.device.extra.PASSKEY";
228
229 /**
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700230 * Broadcast Action: This intent is used to broadcast the {@link UUID}
Nick Pellyaef439e2009-09-28 12:33:17 -0700231 * wrapped as a {@link android.os.ParcelUuid} of the remote device after it
232 * has been fetched. This intent is sent only when the UUIDs of the remote
233 * device are requested to be fetched using Service Discovery Protocol
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700234 * <p> Always contains the extra field {@link #EXTRA_DEVICE}
235 * <p> Always contains the extra filed {@link #EXTRA_UUID}
236 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
237 * @hide
238 */
239 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
240 public static final String ACTION_UUID =
241 "android.bleutooth.device.action.UUID";
242
243 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700244 * Broadcast Action: Indicates a failure to retrieve the name of a remote
245 * device.
246 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
247 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
248 * @hide
249 */
250 //TODO: is this actually useful?
251 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
252 public static final String ACTION_NAME_FAILED =
253 "android.bluetooth.device.action.NAME_FAILED";
254
255 /** @hide */
256 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
257 public static final String ACTION_PAIRING_REQUEST =
258 "android.bluetooth.device.action.PAIRING_REQUEST";
259 /** @hide */
260 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
261 public static final String ACTION_PAIRING_CANCEL =
262 "android.bluetooth.device.action.PAIRING_CANCEL";
Yue Lixina4433af2009-07-09 16:56:43 +0800263
Nick Pellyb24e11b2009-09-08 17:40:43 -0700264 /** A bond attempt succeeded
265 * @hide */
266 public static final int BOND_SUCCESS = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 /** A bond attempt failed because pins did not match, or remote device did
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700268 * not respond to pin request in time
Nick Pelly45e27042009-08-19 11:00:00 -0700269 * @hide */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 public static final int UNBOND_REASON_AUTH_FAILED = 1;
271 /** A bond attempt failed because the other side explicilty rejected
Nick Pelly45e27042009-08-19 11:00:00 -0700272 * bonding
273 * @hide */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 public static final int UNBOND_REASON_AUTH_REJECTED = 2;
Nick Pelly45e27042009-08-19 11:00:00 -0700275 /** A bond attempt failed because we canceled the bonding process
276 * @hide */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 public static final int UNBOND_REASON_AUTH_CANCELED = 3;
Nick Pelly45e27042009-08-19 11:00:00 -0700278 /** A bond attempt failed because we could not contact the remote device
279 * @hide */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
Nick Pelly45e27042009-08-19 11:00:00 -0700281 /** A bond attempt failed because a discovery is in progress
282 * @hide */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700284 /** A bond attempt failed because of authentication timeout
285 * @hide */
286 public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
287 /** A bond attempt failed because of repeated attempts
288 * @hide */
289 public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
Jaikumar Ganeshe5d93b72009-10-08 02:27:52 -0700290 /** A bond attempt failed because we received an Authentication Cancel
291 * by remote end
292 * @hide */
293 public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
Nick Pelly45e27042009-08-19 11:00:00 -0700294 /** An existing bond was explicitly revoked
295 * @hide */
Jaikumar Ganeshe5d93b72009-10-08 02:27:52 -0700296 public static final int UNBOND_REASON_REMOVED = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297
Nick Pelly45e27042009-08-19 11:00:00 -0700298 /** The user will be prompted to enter a pin
299 * @hide */
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700300 public static final int PAIRING_VARIANT_PIN = 0;
Nick Pelly45e27042009-08-19 11:00:00 -0700301 /** The user will be prompted to enter a passkey
302 * @hide */
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700303 public static final int PAIRING_VARIANT_PASSKEY = 1;
Nick Pelly45e27042009-08-19 11:00:00 -0700304 /** The user will be prompted to confirm the passkey displayed on the screen
305 * @hide */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700306 public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
307 /** The user will be prompted to accept or deny the incoming pairing request
308 * @hide */
309 public static final int PAIRING_VARIANT_CONSENT = 3;
310 /** The user will be prompted to enter the passkey displayed on remote device
311 * @hide */
312 public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700313
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700314 /**
315 * Used as an extra field in {@link #ACTION_UUID} intents,
Nick Pellyaef439e2009-09-28 12:33:17 -0700316 * Contains the {@link android.os.ParcelUuid}s of the remote device which
317 * is a parcelable version of {@link UUID}.
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700318 * @hide
319 */
320 public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
321
Nick Pelly16fb88a2009-10-07 07:44:03 +0200322 /**
323 * Lazy initialization. Guaranteed final after first object constructed, or
324 * getService() called.
325 * TODO: Unify implementation of sService amongst BluetoothFoo API's
326 */
327 private static IBluetooth sService;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700328
Nick Pellybd022f42009-08-14 18:33:38 -0700329 private final String mAddress;
330
Nick Pelly16fb88a2009-10-07 07:44:03 +0200331 /*package*/ static IBluetooth getService() {
332 synchronized (BluetoothDevice.class) {
333 if (sService == null) {
Nick Pellyf242b7b2009-10-08 00:12:45 +0200334 IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
Nick Pelly16fb88a2009-10-07 07:44:03 +0200335 if (b == null) {
336 throw new RuntimeException("Bluetooth service not available");
337 }
338 sService = IBluetooth.Stub.asInterface(b);
339 }
340 }
341 return sService;
342 }
343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 /**
Nick Pellybd022f42009-08-14 18:33:38 -0700345 * Create a new BluetoothDevice
346 * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
347 * and is validated in this constructor.
348 * @param address valid Bluetooth MAC address
349 * @throws RuntimeException Bluetooth is not available on this platform
350 * @throws IllegalArgumentException address is invalid
351 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 */
Nick Pellybd022f42009-08-14 18:33:38 -0700353 /*package*/ BluetoothDevice(String address) {
Nick Pelly16fb88a2009-10-07 07:44:03 +0200354 getService(); // ensures sService is initialized
Nick Pelly005b2282009-09-10 10:21:56 -0700355 if (!BluetoothAdapter.checkBluetoothAddress(address)) {
Nick Pellybd022f42009-08-14 18:33:38 -0700356 throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
357 }
358
359 mAddress = address;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 }
361
Nick Pellybd022f42009-08-14 18:33:38 -0700362 @Override
363 public boolean equals(Object o) {
364 if (o instanceof BluetoothDevice) {
365 return mAddress.equals(((BluetoothDevice)o).getAddress());
366 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 return false;
368 }
369
Nick Pellybd022f42009-08-14 18:33:38 -0700370 @Override
371 public int hashCode() {
372 return mAddress.hashCode();
The Android Open Source Project10592532009-03-18 17:39:46 -0700373 }
374
Nick Pelly45e27042009-08-19 11:00:00 -0700375 /**
376 * Returns a string representation of this BluetoothDevice.
377 * <p>Currently this is the Bluetooth hardware address, for example
378 * "00:11:22:AA:BB:CC". However, you should always use {@link #getAddress}
379 * if you explicitly require the Bluetooth hardware address in case the
380 * {@link #toString} representation changes in the future.
381 * @return string representation of this BluetoothDevice
382 */
Nick Pellybd022f42009-08-14 18:33:38 -0700383 @Override
384 public String toString() {
385 return mAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 }
387
Nick Pellybd022f42009-08-14 18:33:38 -0700388 public int describeContents() {
389 return 0;
390 }
391
392 public static final Parcelable.Creator<BluetoothDevice> CREATOR =
393 new Parcelable.Creator<BluetoothDevice>() {
394 public BluetoothDevice createFromParcel(Parcel in) {
395 return new BluetoothDevice(in.readString());
396 }
397 public BluetoothDevice[] newArray(int size) {
398 return new BluetoothDevice[size];
399 }
400 };
401
402 public void writeToParcel(Parcel out, int flags) {
403 out.writeString(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 }
405
Nick Pelly45e27042009-08-19 11:00:00 -0700406 /**
407 * Returns the hardware address of this BluetoothDevice.
408 * <p> For example, "00:11:22:AA:BB:CC".
409 * @return Bluetooth hardware address as string
410 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 public String getAddress() {
Nick Pellybd022f42009-08-14 18:33:38 -0700412 return mAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 }
414
415 /**
Nick Pelly45e27042009-08-19 11:00:00 -0700416 * Get the friendly Bluetooth name of the remote device.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 *
Nick Pelly45e27042009-08-19 11:00:00 -0700418 * <p>The local adapter will automatically retrieve remote names when
419 * performing a device scan, and will cache them. This method just returns
420 * the name for this device from the cache.
Nick Pellyde893f52009-09-08 13:15:33 -0700421 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 *
423 * @return the Bluetooth name, or null if there was a problem.
424 */
425 public String getName() {
426 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700427 return sService.getRemoteName(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 } catch (RemoteException e) {Log.e(TAG, "", e);}
429 return null;
430 }
431
432 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700433 * Start the bonding (pairing) process with the remote device.
434 * <p>This is an asynchronous call, it will return immediately. Register
435 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
436 * the bonding process completes, and its result.
437 * <p>Android system services will handle the necessary user interactions
438 * to confirm and complete the bonding process.
439 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 *
Nick Pelly005b2282009-09-10 10:21:56 -0700441 * @return false on immediate error, true if bonding will begin
Nick Pelly18b1e792009-09-24 11:14:15 -0700442 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 */
Nick Pellybd022f42009-08-14 18:33:38 -0700444 public boolean createBond() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700446 return sService.createBond(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 } catch (RemoteException e) {Log.e(TAG, "", e);}
448 return false;
449 }
450
451 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700452 * Cancel an in-progress bonding request started with {@link #createBond}.
453 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
454 *
455 * @return true on sucess, false on error
Nick Pelly18b1e792009-09-24 11:14:15 -0700456 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 */
Nick Pellybd022f42009-08-14 18:33:38 -0700458 public boolean cancelBondProcess() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700460 return sService.cancelBondProcess(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 } catch (RemoteException e) {Log.e(TAG, "", e);}
462 return false;
463 }
464
465 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700466 * Remove bond (pairing) with the remote device.
467 * <p>Delete the link key associated with the remote device, and
468 * immediately terminate connections to that device that require
469 * authentication and encryption.
470 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 *
Nick Pelly005b2282009-09-10 10:21:56 -0700472 * @return true on sucess, false on error
Nick Pelly18b1e792009-09-24 11:14:15 -0700473 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 */
Nick Pellybd022f42009-08-14 18:33:38 -0700475 public boolean removeBond() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700477 return sService.removeBond(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 } catch (RemoteException e) {Log.e(TAG, "", e);}
Nick Pellybd022f42009-08-14 18:33:38 -0700479 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 }
481
482 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700483 * Get the bond state of the remote device.
484 * <p>Possible values for the bond state are:
485 * {@link #BOND_NONE},
486 * {@link #BOND_BONDING},
487 * {@link #BOND_BONDED}.
488 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800489 *
Nick Pelly005b2282009-09-10 10:21:56 -0700490 * @return the bond state
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 */
Nick Pellybd022f42009-08-14 18:33:38 -0700492 public int getBondState() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700494 return sService.getBondState(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 } catch (RemoteException e) {Log.e(TAG, "", e);}
Nick Pelly005b2282009-09-10 10:21:56 -0700496 return BOND_NONE;
497 }
498
499 /**
500 * Get the Bluetooth class of the remote device.
501 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
502 *
503 * @return Bluetooth class object, or null on error
504 */
505 public BluetoothClass getBluetoothClass() {
506 try {
507 int classInt = sService.getRemoteClass(mAddress);
508 if (classInt == BluetoothClass.ERROR) return null;
509 return new BluetoothClass(classInt);
510 } catch (RemoteException e) {Log.e(TAG, "", e);}
511 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 }
513
Lixin Yueefa1dd72009-08-31 15:55:13 +0800514 /**
515 * Get trust state of a remote device.
Nick Pellye6ee3be2009-10-08 23:27:28 +0200516 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
Lixin Yueefa1dd72009-08-31 15:55:13 +0800517 * @hide
518 */
519 public boolean getTrustState() {
520 try {
521 return sService.getTrustState(mAddress);
522 } catch (RemoteException e) {
523 Log.e(TAG, "", e);
524 }
525 return false;
526 }
527
528 /**
529 * Set trust state for a remote device.
Nick Pellye6ee3be2009-10-08 23:27:28 +0200530 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
Lixin Yueefa1dd72009-08-31 15:55:13 +0800531 * @param value the trust state value (true or false)
532 * @hide
533 */
534 public boolean setTrust(boolean value) {
535 try {
536 return sService.setTrust(mAddress, value);
537 } catch (RemoteException e) {
538 Log.e(TAG, "", e);
539 }
540 return false;
541 }
542
Nick Pelly45e27042009-08-19 11:00:00 -0700543 /** @hide */
Jaikumar Ganeshdd0463a2009-09-16 12:30:02 -0700544 public ParcelUuid[] getUuids() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700546 return sService.getRemoteUuids(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 } catch (RemoteException e) {Log.e(TAG, "", e);}
548 return null;
549 }
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700550
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700551 /**
552 * Perform a SDP query on the remote device to get the UUIDs
553 * supported. This API is asynchronous and an Intent is sent,
554 * with the UUIDs supported by the remote end. If there is an error
555 * in getting the SDP records or if the process takes a long time,
556 * an Intent is sent with the UUIDs that is currently present in the
557 * cache. Clients should use the {@link getUuids} to get UUIDs
558 * is SDP is not to be performed.
559 *
560 * @return False if the sanity check fails, True if the process
561 * of initiating an ACL connection to the remote device
562 * was started.
563 * @hide
564 */
565 public boolean fetchUuidsWithSdp() {
566 try {
Nick Pelly16fb88a2009-10-07 07:44:03 +0200567 return sService.fetchRemoteUuids(mAddress, null, null);
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700568 } catch (RemoteException e) {Log.e(TAG, "", e);}
569 return false;
570 }
571
Nick Pelly45e27042009-08-19 11:00:00 -0700572 /** @hide */
Jaikumar Ganeshdd0463a2009-09-16 12:30:02 -0700573 public int getServiceChannel(ParcelUuid uuid) {
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700574 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700575 return sService.getRemoteServiceChannel(mAddress, uuid);
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700576 } catch (RemoteException e) {Log.e(TAG, "", e);}
Nick Pellyb24e11b2009-09-08 17:40:43 -0700577 return BluetoothDevice.ERROR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 }
579
Nick Pelly45e27042009-08-19 11:00:00 -0700580 /** @hide */
Nick Pellybd022f42009-08-14 18:33:38 -0700581 public boolean setPin(byte[] pin) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700583 return sService.setPin(mAddress, pin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 } catch (RemoteException e) {Log.e(TAG, "", e);}
585 return false;
586 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700587
Nick Pelly45e27042009-08-19 11:00:00 -0700588 /** @hide */
Nick Pellybd022f42009-08-14 18:33:38 -0700589 public boolean setPasskey(int passkey) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700591 return sService.setPasskey(mAddress, passkey);
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700592 } catch (RemoteException e) {Log.e(TAG, "", e);}
593 return false;
594 }
595
Nick Pelly45e27042009-08-19 11:00:00 -0700596 /** @hide */
Nick Pellybd022f42009-08-14 18:33:38 -0700597 public boolean setPairingConfirmation(boolean confirm) {
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700598 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700599 return sService.setPairingConfirmation(mAddress, confirm);
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700600 } catch (RemoteException e) {Log.e(TAG, "", e);}
601 return false;
602 }
603
Nick Pelly45e27042009-08-19 11:00:00 -0700604 /** @hide */
Nick Pellybd022f42009-08-14 18:33:38 -0700605 public boolean cancelPairingUserInput() {
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700606 try {
Nick Pellybd022f42009-08-14 18:33:38 -0700607 return sService.cancelPairingUserInput(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 } catch (RemoteException e) {Log.e(TAG, "", e);}
609 return false;
610 }
611
612 /**
Nick Pelly45e27042009-08-19 11:00:00 -0700613 * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
Nick Pelly16fb88a2009-10-07 07:44:03 +0200614 * outgoing connection to this remote device on given channel.
Nick Pelly45e27042009-08-19 11:00:00 -0700615 * <p>The remote device will be authenticated and communication on this
616 * socket will be encrypted.
617 * <p>Use {@link BluetoothSocket#connect} to intiate the outgoing
618 * connection.
619 * <p>Valid RFCOMM channels are in range 1 to 30.
Nick Pellycf440592009-09-08 10:12:06 -0700620 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
Nick Pellyde893f52009-09-08 13:15:33 -0700621 *
Nick Pelly45e27042009-08-19 11:00:00 -0700622 * @param channel RFCOMM channel to connect to
623 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Nick Pellybd022f42009-08-14 18:33:38 -0700624 * @throws IOException on error, for example Bluetooth not available, or
Nick Pelly45e27042009-08-19 11:00:00 -0700625 * insufficient permissions
Nick Pelly16fb88a2009-10-07 07:44:03 +0200626 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -0700627 */
Nick Pelly45e27042009-08-19 11:00:00 -0700628 public BluetoothSocket createRfcommSocket(int channel) throws IOException {
Nick Pelly16fb88a2009-10-07 07:44:03 +0200629 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel,
630 null);
631 }
632
633 /**
634 * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
635 * outgoing connection to this remote device using SDP lookup of uuid.
636 * <p>This is designed to be used with {@link
637 * BluetoothAdapter#listenUsingRfcommWithServiceRecord} for peer-peer
638 * Bluetooth applications.
639 * <p>Use {@link BluetoothSocket#connect} to intiate the outgoing
640 * connection. This will also perform an SDP lookup of the given uuid to
641 * determine which channel to connect to.
642 * <p>The remote device will be authenticated and communication on this
643 * socket will be encrypted.
644 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
645 *
646 * @param uuid service record uuid to lookup RFCOMM channel
647 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
648 * @throws IOException on error, for example Bluetooth not available, or
649 * insufficient permissions
650 */
651 public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
652 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1,
653 new ParcelUuid(uuid));
Nick Pellybd022f42009-08-14 18:33:38 -0700654 }
655
656 /**
657 * Construct an insecure RFCOMM socket ready to start an outgoing
658 * connection.
659 * Call #connect on the returned #BluetoothSocket to begin the connection.
660 * The remote device will not be authenticated and communication on this
661 * socket will not be encrypted.
Nick Pellye6ee3be2009-10-08 23:27:28 +0200662 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
663 *
Nick Pellybd022f42009-08-14 18:33:38 -0700664 * @param port remote port
665 * @return An RFCOMM BluetoothSocket
666 * @throws IOException On error, for example Bluetooth not available, or
667 * insufficient permissions.
Nick Pelly45e27042009-08-19 11:00:00 -0700668 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -0700669 */
670 public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
Nick Pelly16fb88a2009-10-07 07:44:03 +0200671 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port,
672 null);
Nick Pellybd022f42009-08-14 18:33:38 -0700673 }
674
675 /**
676 * Construct a SCO socket ready to start an outgoing connection.
677 * Call #connect on the returned #BluetoothSocket to begin the connection.
Nick Pellye6ee3be2009-10-08 23:27:28 +0200678 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
679 *
Nick Pellybd022f42009-08-14 18:33:38 -0700680 * @return a SCO BluetoothSocket
681 * @throws IOException on error, for example Bluetooth not available, or
682 * insufficient permissions.
Nick Pelly45e27042009-08-19 11:00:00 -0700683 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -0700684 */
685 public BluetoothSocket createScoSocket() throws IOException {
Nick Pelly16fb88a2009-10-07 07:44:03 +0200686 return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null);
Nick Pellybd022f42009-08-14 18:33:38 -0700687 }
688
689 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 * Check that a pin is valid and convert to byte array.
691 *
692 * Bluetooth pin's are 1 to 16 bytes of UTF8 characters.
693 * @param pin pin as java String
694 * @return the pin code as a UTF8 byte array, or null if it is an invalid
695 * Bluetooth pin.
Nick Pelly45e27042009-08-19 11:00:00 -0700696 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800697 */
698 public static byte[] convertPinToBytes(String pin) {
699 if (pin == null) {
700 return null;
701 }
702 byte[] pinBytes;
703 try {
704 pinBytes = pin.getBytes("UTF8");
705 } catch (UnsupportedEncodingException uee) {
706 Log.e(TAG, "UTF8 not supported?!?"); // this should not happen
707 return null;
708 }
709 if (pinBytes.length <= 0 || pinBytes.length > 16) {
710 return null;
711 }
712 return pinBytes;
713 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715}