FileDocCategorySizeDatePackage
BluetoothAdapter.javaAPI DocAndroid 5.1 API75094Thu Mar 12 22:22:10 GMT 2015android.bluetooth

BluetoothAdapter

public final class BluetoothAdapter extends Object
Represents the local device Bluetooth adapter. The {@link BluetoothAdapter} lets you perform fundamental Bluetooth tasks, such as initiate device discovery, query a list of bonded (paired) devices, instantiate a {@link BluetoothDevice} using a known MAC address, and create a {@link BluetoothServerSocket} to listen for connection requests from other devices, and start a scan for Bluetooth LE devices.

To get a {@link BluetoothAdapter} representing the local Bluetooth adapter, when running on JELLY_BEAN_MR1 and below, call the static {@link #getDefaultAdapter} method; when running on JELLY_BEAN_MR2 and higher, retrieve it through {@link android.content.Context#getSystemService} with {@link android.content.Context#BLUETOOTH_SERVICE}. Fundamentally, this is your starting point for all Bluetooth actions. Once you have the local adapter, you can get a set of {@link BluetoothDevice} objects representing all paired devices with {@link #getBondedDevices()}; start device discovery with {@link #startDiscovery()}; or create a {@link BluetoothServerSocket} to listen for incoming connection requests with {@link #listenUsingRfcommWithServiceRecord(String,UUID)}; or start a scan for Bluetooth LE devices with {@link #startLeScan(LeScanCallback callback)}.

Note: Most methods require the {@link android.Manifest.permission#BLUETOOTH} permission and some also require the {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.

Developer Guides

For more information about using Bluetooth, read the Bluetooth developer guide.

{@see BluetoothDevice} {@see BluetoothServerSocket}

Fields Summary
private static final String
TAG
private static final boolean
DBG
private static final boolean
VDBG
public static final int
ERROR
Sentinel error value for this class. Guaranteed to not equal any other integer constant in this class. Provided as a convenience for functions that require a sentinel error value, for example:

Intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)

public static final String
ACTION_STATE_CHANGED
Broadcast Action: The state of the local Bluetooth adapter has been changed.

For example, Bluetooth has been turned on or off.

Always contains the extra fields {@link #EXTRA_STATE} and {@link #EXTRA_PREVIOUS_STATE} containing the new and old states respectively.

Requires {@link android.Manifest.permission#BLUETOOTH} to receive.

public static final String
EXTRA_STATE
Used as an int extra field in {@link #ACTION_STATE_CHANGED} intents to request the current power state. Possible values are: {@link #STATE_OFF}, {@link #STATE_TURNING_ON}, {@link #STATE_ON}, {@link #STATE_TURNING_OFF},
public static final String
EXTRA_PREVIOUS_STATE
Used as an int extra field in {@link #ACTION_STATE_CHANGED} intents to request the previous power state. Possible values are: {@link #STATE_OFF}, {@link #STATE_TURNING_ON}, {@link #STATE_ON}, {@link #STATE_TURNING_OFF},
public static final int
STATE_OFF
Indicates the local Bluetooth adapter is off.
public static final int
STATE_TURNING_ON
Indicates the local Bluetooth adapter is turning on. However local clients should wait for {@link #STATE_ON} before attempting to use the adapter.
public static final int
STATE_ON
Indicates the local Bluetooth adapter is on, and ready for use.
public static final int
STATE_TURNING_OFF
Indicates the local Bluetooth adapter is turning off. Local clients should immediately attempt graceful disconnection of any remote links.
public static final String
ACTION_REQUEST_DISCOVERABLE
Activity Action: Show a system activity that requests discoverable mode. This activity will also request the user to turn on Bluetooth if it is not currently enabled.

Discoverable mode is equivalent to {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}. It allows remote devices to see this Bluetooth adapter when they perform a discovery.

For privacy, Android is not discoverable by default.

The sender of this Intent can optionally use extra field {@link #EXTRA_DISCOVERABLE_DURATION} to request the duration of discoverability. Currently the default duration is 120 seconds, and maximum duration is capped at 300 seconds for each request.

Notification of the result of this activity is posted using the {@link android.app.Activity#onActivityResult} callback. The resultCode will be the duration (in seconds) of discoverability or {@link android.app.Activity#RESULT_CANCELED} if the user rejected discoverability or an error has occurred.

Applications can also listen for {@link #ACTION_SCAN_MODE_CHANGED} for global notification whenever the scan mode changes. For example, an application can be notified when the device has ended discoverability.

Requires {@link android.Manifest.permission#BLUETOOTH}

public static final String
EXTRA_DISCOVERABLE_DURATION
Used as an optional int extra field in {@link #ACTION_REQUEST_DISCOVERABLE} intents to request a specific duration for discoverability in seconds. The current default is 120 seconds, and requests over 300 seconds will be capped. These values could change.
public static final String
ACTION_REQUEST_ENABLE
Activity Action: Show a system activity that allows the user to turn on Bluetooth.

This system activity will return once Bluetooth has completed turning on, or the user has decided not to turn Bluetooth on.

Notification of the result of this activity is posted using the {@link android.app.Activity#onActivityResult} callback. The resultCode will be {@link android.app.Activity#RESULT_OK} if Bluetooth has been turned on or {@link android.app.Activity#RESULT_CANCELED} if the user has rejected the request or an error has occurred.

Applications can also listen for {@link #ACTION_STATE_CHANGED} for global notification whenever Bluetooth is turned on or off.

Requires {@link android.Manifest.permission#BLUETOOTH}

public static final String
ACTION_SCAN_MODE_CHANGED
Broadcast Action: Indicates the Bluetooth scan mode of the local Adapter has changed.

Always contains the extra fields {@link #EXTRA_SCAN_MODE} and {@link #EXTRA_PREVIOUS_SCAN_MODE} containing the new and old scan modes respectively.

Requires {@link android.Manifest.permission#BLUETOOTH}

public static final String
EXTRA_SCAN_MODE
Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED} intents to request the current scan mode. Possible values are: {@link #SCAN_MODE_NONE}, {@link #SCAN_MODE_CONNECTABLE}, {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE},
public static final String
EXTRA_PREVIOUS_SCAN_MODE
Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED} intents to request the previous scan mode. Possible values are: {@link #SCAN_MODE_NONE}, {@link #SCAN_MODE_CONNECTABLE}, {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE},
public static final int
SCAN_MODE_NONE
Indicates that both inquiry scan and page scan are disabled on the local Bluetooth adapter. Therefore this device is neither discoverable nor connectable from remote Bluetooth devices.
public static final int
SCAN_MODE_CONNECTABLE
Indicates that inquiry scan is disabled, but page scan is enabled on the local Bluetooth adapter. Therefore this device is not discoverable from remote Bluetooth devices, but is connectable from remote devices that have previously discovered this device.
public static final int
SCAN_MODE_CONNECTABLE_DISCOVERABLE
Indicates that both inquiry scan and page scan are enabled on the local Bluetooth adapter. Therefore this device is both discoverable and connectable from remote Bluetooth devices.
public static final String
ACTION_DISCOVERY_STARTED
Broadcast Action: The local Bluetooth adapter has started the remote device discovery process.

This usually involves an inquiry scan of about 12 seconds, followed by a page scan of each new device to retrieve its Bluetooth name.

Register for {@link BluetoothDevice#ACTION_FOUND} to be notified as remote Bluetooth devices are found.

Device discovery is a heavyweight procedure. New connections to remote Bluetooth devices should not be attempted while discovery is in progress, and existing connections will experience limited bandwidth and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing discovery.

Requires {@link android.Manifest.permission#BLUETOOTH} to receive.

public static final String
ACTION_DISCOVERY_FINISHED
Broadcast Action: The local Bluetooth adapter has finished the device discovery process.

Requires {@link android.Manifest.permission#BLUETOOTH} to receive.

public static final String
ACTION_LOCAL_NAME_CHANGED
Broadcast Action: The local Bluetooth adapter has changed its friendly Bluetooth name.

This name is visible to remote Bluetooth devices.

Always contains the extra field {@link #EXTRA_LOCAL_NAME} containing the name.

Requires {@link android.Manifest.permission#BLUETOOTH} to receive.

public static final String
EXTRA_LOCAL_NAME
Used as a String extra field in {@link #ACTION_LOCAL_NAME_CHANGED} intents to request the local Bluetooth name.
public static final String
ACTION_CONNECTION_STATE_CHANGED
Intent used to broadcast the change in connection state of the local Bluetooth adapter to a profile of the remote device. When the adapter is not connected to any profiles of any remote devices and it attempts a connection to a profile this intent will sent. Once connected, this intent will not be sent for any more connection attempts to any profiles of any remote device. When the adapter disconnects from the last profile its connected to of any remote device, this intent will be sent.

This intent is useful for applications that are only concerned about whether the local adapter is connected to any profile of any device and are not really concerned about which profile. For example, an application which displays an icon to display whether Bluetooth is connected or not can use this intent.

This intent will have 3 extras: {@link #EXTRA_CONNECTION_STATE} - The current connection state. {@link #EXTRA_PREVIOUS_CONNECTION_STATE}- The previous connection state. {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. {@link #EXTRA_CONNECTION_STATE} or {@link #EXTRA_PREVIOUS_CONNECTION_STATE} can be any of {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING}, {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.

Requires {@link android.Manifest.permission#BLUETOOTH} to receive.

public static final String
EXTRA_CONNECTION_STATE
Extra used by {@link #ACTION_CONNECTION_STATE_CHANGED} This extra represents the current connection state.
public static final String
EXTRA_PREVIOUS_CONNECTION_STATE
Extra used by {@link #ACTION_CONNECTION_STATE_CHANGED} This extra represents the previous connection state.
public static final int
STATE_DISCONNECTED
The profile is in disconnected state
public static final int
STATE_CONNECTING
The profile is in connecting state
public static final int
STATE_CONNECTED
The profile is in connected state
public static final int
STATE_DISCONNECTING
The profile is in disconnecting state
public static final String
BLUETOOTH_MANAGER_SERVICE
private static final int
ADDRESS_LENGTH
private static final int
CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS
public static final int
ACTIVITY_ENERGY_INFO_CACHED
public static final int
ACTIVITY_ENERGY_INFO_REFRESHED
private static BluetoothAdapter
sAdapter
Lazily initialized singleton. Guaranteed final after first object constructed.
private static android.bluetooth.le.BluetoothLeScanner
sBluetoothLeScanner
private static android.bluetooth.le.BluetoothLeAdvertiser
sBluetoothLeAdvertiser
private final IBluetoothManager
mManagerService
private IBluetooth
mService
private final Object
mLock
private final Map
mLeScanClients
private final IBluetoothManagerCallback
mManagerCallback
private final ArrayList
mProxyServiceStateCallbacks
Constructors Summary
BluetoothAdapter(IBluetoothManager managerService)
Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.


        if (managerService == null) {
            throw new IllegalArgumentException("bluetooth manager service is null");
        }
        try {
            mService = managerService.registerAdapter(mManagerCallback);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        mManagerService = managerService;
        mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
    
Methods Summary
public booleancancelDiscovery()
Cancel the current device discovery process.

Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.

Because discovery is a heavyweight procedure for the Bluetooth adapter, this method should always be called before attempting to connect to a remote device with {@link android.bluetooth.BluetoothSocket#connect()}. Discovery is not managed by the Activity, but is run as a system service, so an application should always call cancel discovery even if it did not directly request a discovery, just to be sure.

If Bluetooth state is not {@link #STATE_ON}, this API will return false. After turning on Bluetooth, wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON} to get the updated value.

return
true on success, false on error

        if (getState() != STATE_ON) return false;
        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.cancelDiscovery();
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
public booleanchangeApplicationBluetoothState(boolean on, android.bluetooth.BluetoothAdapter$BluetoothStateChangeCallback callback)
Enable control of the Bluetooth Adapter for a single application.

Some applications need to use Bluetooth for short periods of time to transfer data but don't want all the associated implications like automatic connection to headsets etc.

Multiple applications can call this. This is reference counted and Bluetooth disabled only when no one else is using it. There will be no UI shown to the user while bluetooth is being enabled. Any user action will override this call. For example, if user wants Bluetooth on and the last user of this API wanted to disable Bluetooth, Bluetooth will not be turned off.

This API is only meant to be used by internal applications. Third party applications but use {@link #enable} and {@link #disable} APIs.

If this API returns true, it means the callback will be called. The callback will be called with the current state of Bluetooth. If the state is not what was requested, an internal error would be the reason. If Bluetooth is already on and if this function is called to turn it on, the api will return true and a callback will be called.

Requires {@link android.Manifest.permission#BLUETOOTH}

param
on True for on, false for off.
param
callback The callback to notify changes to the state.
hide

        if (callback == null) return false;

        //TODO(BT)
        /*
        try {
            return mService.changeApplicationBluetoothState(on, new
                    StateChangeCallbackWrapper(callback), new Binder());
        } catch (RemoteException e) {
            Log.e(TAG, "changeBluetoothState", e);
        }*/
        return false;
    
public static booleancheckBluetoothAddress(java.lang.String address)
Validate a String Bluetooth address, such as "00:43:A8:23:10:F0"

Alphabetic characters must be uppercase to be valid.

param
address Bluetooth address as string
return
true if the address is valid, false otherwise

        if (address == null || address.length() != ADDRESS_LENGTH) {
            return false;
        }
        for (int i = 0; i < ADDRESS_LENGTH; i++) {
            char c = address.charAt(i);
            switch (i % 3) {
            case 0:
            case 1:
                if ((c >= '0" && c <= '9") || (c >= 'A" && c <= 'F")) {
                    // hex character, OK
                    break;
                }
                return false;
            case 2:
                if (c == ':") {
                    break;  // OK
                }
                return false;
            }
        }
        return true;
    
public voidcloseProfileProxy(int profile, BluetoothProfile proxy)
Close the connection of the profile proxy to the Service.

Clients should call this when they are no longer using the proxy obtained from {@link #getProfileProxy}. Profile can be one of {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET} or {@link BluetoothProfile#A2DP}

param
profile
param
proxy Profile proxy object

        if (proxy == null) return;

        switch (profile) {
            case BluetoothProfile.HEADSET:
                BluetoothHeadset headset = (BluetoothHeadset)proxy;
                headset.close();
                break;
            case BluetoothProfile.A2DP:
                BluetoothA2dp a2dp = (BluetoothA2dp)proxy;
                a2dp.close();
                break;
            case BluetoothProfile.A2DP_SINK:
                BluetoothA2dpSink a2dpSink = (BluetoothA2dpSink)proxy;
                a2dpSink.close();
                break;
            case BluetoothProfile.AVRCP_CONTROLLER:
                BluetoothAvrcpController avrcp = (BluetoothAvrcpController)proxy;
                avrcp.close();
                break;
            case BluetoothProfile.INPUT_DEVICE:
                BluetoothInputDevice iDev = (BluetoothInputDevice)proxy;
                iDev.close();
                break;
            case BluetoothProfile.PAN:
                BluetoothPan pan = (BluetoothPan)proxy;
                pan.close();
                break;
            case BluetoothProfile.HEALTH:
                BluetoothHealth health = (BluetoothHealth)proxy;
                health.close();
                break;
           case BluetoothProfile.GATT:
                BluetoothGatt gatt = (BluetoothGatt)proxy;
                gatt.close();
                break;
            case BluetoothProfile.GATT_SERVER:
                BluetoothGattServer gattServer = (BluetoothGattServer)proxy;
                gattServer.close();
                break;
            case BluetoothProfile.MAP:
                BluetoothMap map = (BluetoothMap)proxy;
                map.close();
                break;
            case BluetoothProfile.HEADSET_CLIENT:
                BluetoothHeadsetClient headsetClient = (BluetoothHeadsetClient)proxy;
                headsetClient.close();
                break;
        }
    
public booleanconfigHciSnoopLog(boolean enable)
enable or disable Bluetooth HCI snoop log.

Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission

return
true to indicate configure HCI log successfully, or false on immediate error
hide

        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.configHciSnoopLog(enable);
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
private BluetoothServerSocketcreateNewRfcommSocketAndRecord(java.lang.String name, java.util.UUID uuid, boolean auth, boolean encrypt)

        BluetoothServerSocket socket;
        socket = new BluetoothServerSocket(BluetoothSocket.TYPE_RFCOMM, auth,
                        encrypt, new ParcelUuid(uuid));
        socket.setServiceName(name);
        int errno = socket.mSocket.bindListen();
        if (errno != 0) {
            //TODO(BT): Throw the same exception error code
            // that the previous code was using.
            //socket.mSocket.throwErrnoNative(errno);
            throw new IOException("Error: " + errno);
        }
        return socket;
    
public booleandisable()
Turn off the local Bluetooth adapter—do not use without explicit user action to turn off Bluetooth.

This gracefully shuts down all Bluetooth connections, stops Bluetooth system services, and powers down the underlying Bluetooth hardware.

Bluetooth should never be disabled without direct user consent. The {@link #disable()} method is provided only for applications that include a user interface for changing system settings, such as a "power manager" app.

This is an asynchronous call: it will return immediately, and clients should listen for {@link #ACTION_STATE_CHANGED} to be notified of subsequent adapter state changes. If this call returns true, then the adapter state will immediately transition from {@link #STATE_ON} to {@link #STATE_TURNING_OFF}, and some time later transition to either {@link #STATE_OFF} or {@link #STATE_ON}. If this call returns false then there was an immediate problem that will prevent the adapter from being turned off - such as the adapter already being turned off.

Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission

return
true to indicate adapter shutdown has begun, or false on immediate error

        try {
            return mManagerService.disable(true);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
public booleandisable(boolean persist)
Turn off the local Bluetooth adapter and don't persist the setting.

Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission

return
true to indicate adapter shutdown has begun, or false on immediate error
hide


        try {
            return mManagerService.disable(persist);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
public booleanenable()
Turn on the local Bluetooth adapter—do not use without explicit user action to turn on Bluetooth.

This powers on the underlying Bluetooth hardware, and starts all Bluetooth system services.

Bluetooth should never be enabled without direct user consent. If you want to turn on Bluetooth in order to create a wireless connection, you should use the {@link #ACTION_REQUEST_ENABLE} Intent, which will raise a dialog that requests user permission to turn on Bluetooth. The {@link #enable()} method is provided only for applications that include a user interface for changing system settings, such as a "power manager" app.

This is an asynchronous call: it will return immediately, and clients should listen for {@link #ACTION_STATE_CHANGED} to be notified of subsequent adapter state changes. If this call returns true, then the adapter state will immediately transition from {@link #STATE_OFF} to {@link #STATE_TURNING_ON}, and some time later transition to either {@link #STATE_OFF} or {@link #STATE_ON}. If this call returns false then there was an immediate problem that will prevent the adapter from being turned on - such as Airplane mode, or the adapter is already turned on.

Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission

return
true to indicate adapter startup has begun, or false on immediate error

        if (isEnabled() == true){
            if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
            return true;
        }
        try {
            return mManagerService.enable();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
public booleanenableNoAutoConnect()
Enable the Bluetooth Adapter, but don't auto-connect devices and don't persist state. Only for use by system applications.

hide


                            
       
        if (isEnabled() == true){
            if (DBG) Log.d(TAG, "enableNoAutoConnect(): BT is already enabled..!");
            return true;
        }
        try {
            return mManagerService.enableNoAutoConnect();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
protected voidfinalize()

        try {
            mManagerService.unregisterAdapter(mManagerCallback);
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        } finally {
            super.finalize();
        }
    
public java.lang.StringgetAddress()
Returns the hardware address of the local Bluetooth adapter.

For example, "00:11:22:AA:BB:CC".

Requires {@link android.Manifest.permission#BLUETOOTH}

return
Bluetooth hardware address as string

        try {
            return mManagerService.getAddress();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return null;
    
public android.bluetooth.le.BluetoothLeAdvertisergetBluetoothLeAdvertiser()
Returns a {@link BluetoothLeAdvertiser} object for Bluetooth LE Advertising operations. Will return null if Bluetooth is turned off or if Bluetooth LE Advertising is not supported on this device.

Use {@link #isMultipleAdvertisementSupported()} to check whether LE Advertising is supported on this device before calling this method.

        if (getState() != STATE_ON) {
            return null;
        }
        if (!isMultipleAdvertisementSupported() && !isPeripheralModeSupported()) {
            Log.e(TAG, "bluetooth le advertising not supported");
            return null;
        }
        synchronized(mLock) {
            if (sBluetoothLeAdvertiser == null) {
                sBluetoothLeAdvertiser = new BluetoothLeAdvertiser(mManagerService);
            }
        }
        return sBluetoothLeAdvertiser;
    
public android.bluetooth.le.BluetoothLeScannergetBluetoothLeScanner()
Returns a {@link BluetoothLeScanner} object for Bluetooth LE scan operations.

        if (getState() != STATE_ON) {
            return null;
        }
        synchronized(mLock) {
            if (sBluetoothLeScanner == null) {
                sBluetoothLeScanner = new BluetoothLeScanner(mManagerService);
            }
        }
        return sBluetoothLeScanner;
    
IBluetoothManagergetBluetoothManager()

            return mManagerService;
    
IBluetoothgetBluetoothService(IBluetoothManagerCallback cb)


    /*package*/    
        synchronized (mProxyServiceStateCallbacks) {
            if (cb == null) {
                Log.w(TAG, "getBluetoothService() called with no BluetoothManagerCallback");
            } else if (!mProxyServiceStateCallbacks.contains(cb)) {
                mProxyServiceStateCallbacks.add(cb);
            }
        }
        return mService;
    
public java.util.SetgetBondedDevices()
Return the set of {@link BluetoothDevice} objects that are bonded (paired) to the local adapter.

If Bluetooth state is not {@link #STATE_ON}, this API will return an empty set. After turning on Bluetooth, wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON} to get the updated value.

Requires {@link android.Manifest.permission#BLUETOOTH}.

return
unmodifiable set of {@link BluetoothDevice}, or null on error

        if (getState() != STATE_ON) {
            return toDeviceSet(new BluetoothDevice[0]);
        }
        try {
            synchronized(mManagerCallback) {
                if (mService != null) return toDeviceSet(mService.getBondedDevices());
            }
            return toDeviceSet(new BluetoothDevice[0]);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return null;
    
public intgetConnectionState()
Get the current connection state of the local Bluetooth adapter. This can be used to check whether the local Bluetooth adapter is connected to any profile of any other remote Bluetooth Device.

Use this function along with {@link #ACTION_CONNECTION_STATE_CHANGED} intent to get the connection state of the adapter.

return
One of {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING} or {@link #STATE_DISCONNECTED}
hide

        if (getState() != STATE_ON) return BluetoothAdapter.STATE_DISCONNECTED;
        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.getAdapterConnectionState();
            }
        } catch (RemoteException e) {Log.e(TAG, "getConnectionState:", e);}
        return BluetoothAdapter.STATE_DISCONNECTED;
    
public BluetoothActivityEnergyInfogetControllerActivityEnergyInfo(int updateType)
Return the record of {@link BluetoothActivityEnergyInfo} object that has the activity and energy info. This can be used to ascertain what the controller has been up to, since the last sample.

param
updateType Type of info, cached vs refreshed.
return
a record with {@link BluetoothActivityEnergyInfo} or null if report is unavailable or unsupported
hide

        if (getState() != STATE_ON) return null;
        try {
            BluetoothActivityEnergyInfo record;
            if (!mService.isActivityAndEnergyReportingSupported()) {
                return null;
            }
            synchronized(this) {
                if (updateType == ACTIVITY_ENERGY_INFO_REFRESHED) {
                    mService.getActivityEnergyInfoFromController();
                    wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS);
                }
                record = mService.reportActivityInfo();
                if (record.isValid()) {
                    return record;
                } else {
                    return null;
                }
            }
        } catch (InterruptedException e) {
            Log.e(TAG, "getControllerActivityEnergyInfoCallback wait interrupted: " + e);
        } catch (RemoteException e) {
            Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e);
        }
        return null;
    
public static synchronized android.bluetooth.BluetoothAdaptergetDefaultAdapter()
Get a handle to the default local Bluetooth adapter.

Currently Android only supports one Bluetooth adapter, but the API could be extended to support more. This will always return the default adapter.

return
the default local adapter, or null if Bluetooth is not supported on this hardware platform


                                                                 
         
        if (sAdapter == null) {
            IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
            if (b != null) {
                IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
                sAdapter = new BluetoothAdapter(managerService);
            } else {
                Log.e(TAG, "Bluetooth binder is null");
            }
        }
        return sAdapter;
    
public intgetDiscoverableTimeout()

hide

        if (getState() != STATE_ON) return -1;
        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.getDiscoverableTimeout();
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return -1;
    
public java.lang.StringgetName()
Get the friendly Bluetooth name of the local Bluetooth adapter.

This name is visible to remote Bluetooth devices.

Requires {@link android.Manifest.permission#BLUETOOTH}

return
the Bluetooth name, or null on error

        try {
            return mManagerService.getName();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return null;
    
public intgetProfileConnectionState(int profile)
Get the current connection state of a profile. This function can be used to check whether the local Bluetooth adapter is connected to any remote device for a specific profile. Profile can be one of {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#A2DP}.

Requires {@link android.Manifest.permission#BLUETOOTH}.

Return value can be one of {@link BluetoothProfile#STATE_DISCONNECTED}, {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_DISCONNECTING}

        if (getState() != STATE_ON) return BluetoothProfile.STATE_DISCONNECTED;
        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.getProfileConnectionState(profile);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "getProfileConnectionState:", e);
        }
        return BluetoothProfile.STATE_DISCONNECTED;
    
public booleangetProfileProxy(android.content.Context context, BluetoothProfile.ServiceListener listener, int profile)
Get the profile proxy object associated with the profile.

Profile can be one of {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#A2DP}, {@link BluetoothProfile#GATT}, or {@link BluetoothProfile#GATT_SERVER}. Clients must implement {@link BluetoothProfile.ServiceListener} to get notified of the connection status and to get the proxy object.

param
context Context of the application
param
listener The service Listener for connection callbacks.
param
profile The Bluetooth profile; either {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET} or {@link BluetoothProfile#A2DP}.
return
true on success, false on error

        if (context == null || listener == null) return false;

        if (profile == BluetoothProfile.HEADSET) {
            BluetoothHeadset headset = new BluetoothHeadset(context, listener);
            return true;
        } else if (profile == BluetoothProfile.A2DP) {
            BluetoothA2dp a2dp = new BluetoothA2dp(context, listener);
            return true;
        } else if (profile == BluetoothProfile.A2DP_SINK) {
            BluetoothA2dpSink a2dpSink = new BluetoothA2dpSink(context, listener);
            return true;
        } else if (profile == BluetoothProfile.AVRCP_CONTROLLER) {
            BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener);
            return true;
        } else if (profile == BluetoothProfile.INPUT_DEVICE) {
            BluetoothInputDevice iDev = new BluetoothInputDevice(context, listener);
            return true;
        } else if (profile == BluetoothProfile.PAN) {
            BluetoothPan pan = new BluetoothPan(context, listener);
            return true;
        } else if (profile == BluetoothProfile.HEALTH) {
            BluetoothHealth health = new BluetoothHealth(context, listener);
            return true;
        } else if (profile == BluetoothProfile.MAP) {
            BluetoothMap map = new BluetoothMap(context, listener);
            return true;
        } else if (profile == BluetoothProfile.HEADSET_CLIENT) {
            BluetoothHeadsetClient headsetClient = new BluetoothHeadsetClient(context, listener);
            return true;
        } else {
            return false;
        }
    
public BluetoothDevicegetRemoteDevice(java.lang.String address)
Get a {@link BluetoothDevice} object for the given Bluetooth hardware address.

Valid Bluetooth hardware addresses must be upper case, in a format such as "00:11:22:33:AA:BB". The helper {@link #checkBluetoothAddress} is available to validate a Bluetooth address.

A {@link BluetoothDevice} will always be returned for a valid hardware address, even if this adapter has never seen that device.

param
address valid Bluetooth MAC address
throws
IllegalArgumentException if address is invalid

        return new BluetoothDevice(address);
    
public BluetoothDevicegetRemoteDevice(byte[] address)
Get a {@link BluetoothDevice} object for the given Bluetooth hardware address.

Valid Bluetooth hardware addresses must be 6 bytes. This method expects the address in network byte order (MSB first).

A {@link BluetoothDevice} will always be returned for a valid hardware address, even if this adapter has never seen that device.

param
address Bluetooth MAC address (6 bytes)
throws
IllegalArgumentException if address is invalid

        if (address == null || address.length != 6) {
            throw new IllegalArgumentException("Bluetooth address must have 6 bytes");
        }
        return new BluetoothDevice(String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
                address[0], address[1], address[2], address[3], address[4], address[5]));
    
public intgetScanMode()
Get the current Bluetooth scan mode of the local Bluetooth adapter.

The Bluetooth scan mode determines if the local adapter is connectable and/or discoverable from remote Bluetooth devices.

Possible values are: {@link #SCAN_MODE_NONE}, {@link #SCAN_MODE_CONNECTABLE}, {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.

If Bluetooth state is not {@link #STATE_ON}, this API will return {@link #SCAN_MODE_NONE}. After turning on Bluetooth, wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON} to get the updated value.

Requires {@link android.Manifest.permission#BLUETOOTH}

return
scan mode

        if (getState() != STATE_ON) return SCAN_MODE_NONE;
        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.getScanMode();
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return SCAN_MODE_NONE;
    
public intgetState()
Get the current state of the local Bluetooth adapter.

Possible return values are {@link #STATE_OFF}, {@link #STATE_TURNING_ON}, {@link #STATE_ON}, {@link #STATE_TURNING_OFF}.

Requires {@link android.Manifest.permission#BLUETOOTH}

return
current state of Bluetooth adapter

        try {
            synchronized(mManagerCallback) {
                if (mService != null)
                {
                    int state=  mService.getState();
                    if (VDBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + state);
                    return state;
                }
                // TODO(BT) there might be a small gap during STATE_TURNING_ON that
                //          mService is null, handle that case
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        if (DBG) Log.d(TAG, "" + hashCode() + ": getState() :  mService = null. Returning STATE_OFF");
        return STATE_OFF;
    
public android.os.ParcelUuid[]getUuids()
Get the UUIDs supported by the local Bluetooth adapter.

Requires {@link android.Manifest.permission#BLUETOOTH}

return
the UUIDs supported by the local Bluetooth Adapter.
hide

        if (getState() != STATE_ON) return null;
        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.getUuids();
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return null;
    
public booleanisDiscovering()
Return true if the local Bluetooth adapter is currently in the device discovery process.

Device discovery is a heavyweight procedure. New connections to remote Bluetooth devices should not be attempted while discovery is in progress, and existing connections will experience limited bandwidth and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing discovery.

Applications can also register for {@link #ACTION_DISCOVERY_STARTED} or {@link #ACTION_DISCOVERY_FINISHED} to be notified when discovery starts or completes.

If Bluetooth state is not {@link #STATE_ON}, this API will return false. After turning on Bluetooth, wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON} to get the updated value.

Requires {@link android.Manifest.permission#BLUETOOTH}.

return
true if discovering

        if (getState() != STATE_ON) return false;
        try {
            synchronized(mManagerCallback) {
                if (mService != null ) return mService.isDiscovering();
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
public booleanisEnabled()
Return true if Bluetooth is currently enabled and ready for use.

Equivalent to: getBluetoothState() == STATE_ON

Requires {@link android.Manifest.permission#BLUETOOTH}

return
true if the local adapter is turned on


        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.isEnabled();
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
public booleanisMultipleAdvertisementSupported()
Return true if the multi advertisement is supported by the chipset

return
true if Multiple Advertisement feature is supported

        if (getState() != STATE_ON) return false;
        try {
            return mService.isMultiAdvertisementSupported();
        } catch (RemoteException e) {
            Log.e(TAG, "failed to get isMultipleAdvertisementSupported, error: ", e);
        }
        return false;
    
public booleanisOffloadedFilteringSupported()
Return true if offloaded filters are supported

return
true if chipset supports on-chip filtering

        if (getState() != STATE_ON) return false;
        try {
            return mService.isOffloadedFilteringSupported();
        } catch (RemoteException e) {
            Log.e(TAG, "failed to get isOffloadedFilteringSupported, error: ", e);
        }
        return false;
    
public booleanisOffloadedScanBatchingSupported()
Return true if offloaded scan batching is supported

return
true if chipset supports on-chip scan batching

        if (getState() != STATE_ON) return false;
        try {
            return mService.isOffloadedScanBatchingSupported();
        } catch (RemoteException e) {
            Log.e(TAG, "failed to get isOffloadedScanBatchingSupported, error: ", e);
        }
        return false;
    
public booleanisPeripheralModeSupported()
Returns whether peripheral mode is supported.

hide

        if (getState() != STATE_ON) return false;
        try {
            return mService.isPeripheralModeSupported();
        } catch (RemoteException e) {
            Log.e(TAG, "failed to get peripheral mode capability: ", e);
        }
        return false;
    
public BluetoothServerSocketlistenUsingEncryptedRfcommOn(int port)
Construct an encrypted, RFCOMM server socket. Call #accept to retrieve connections to this socket.

return
An RFCOMM BluetoothServerSocket
throws
IOException On error, for example Bluetooth not available, or insufficient permissions.
hide

        BluetoothServerSocket socket = new BluetoothServerSocket(
                BluetoothSocket.TYPE_RFCOMM, false, true, port);
        int errno = socket.mSocket.bindListen();
        if (errno < 0) {
            //TODO(BT): Throw the same exception error code
            // that the previous code was using.
            //socket.mSocket.throwErrnoNative(errno);
            throw new IOException("Error: " + errno);
        }
        return socket;
    
public BluetoothServerSocketlistenUsingEncryptedRfcommWithServiceRecord(java.lang.String name, java.util.UUID uuid)
Create a listening, encrypted, RFCOMM Bluetooth socket with Service Record.

The link will be encrypted, but the link key is not required to be authenticated i.e the communication is vulnerable to Man In the Middle attacks. Use {@link #listenUsingRfcommWithServiceRecord}, to ensure an authenticated link key.

Use this socket if authentication of link key is not possible. For example, for Bluetooth 2.1 devices, if any of the devices does not have an input and output capability or just has the ability to display a numeric key, a secure socket connection is not possible and this socket can be used. Use {@link #listenUsingInsecureRfcommWithServiceRecord}, if encryption is not required. For Bluetooth 2.1 devices, the link will be encrypted, as encryption is mandartory. For more details, refer to the Security Model section 5.2 (vol 3) of Bluetooth Core Specification version 2.1 + EDR.

Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening {@link BluetoothServerSocket}.

The system will assign an unused RFCOMM channel to listen on.

The system will also register a Service Discovery Protocol (SDP) record with the local SDP server containing the specified UUID, service name, and auto-assigned channel. Remote Bluetooth devices can use the same UUID to query our SDP server and discover which channel to connect to. This SDP record will be removed when this socket is closed, or if this application closes unexpectedly.

Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to connect to this socket from another device using the same {@link UUID}.

Requires {@link android.Manifest.permission#BLUETOOTH}

param
name service name for SDP record
param
uuid uuid for SDP record
return
a listening RFCOMM BluetoothServerSocket
throws
IOException on error, for example Bluetooth not available, or insufficient permissions, or channel in use.
hide

        return createNewRfcommSocketAndRecord(name, uuid, false, true);
    
public BluetoothServerSocketlistenUsingInsecureRfcommOn(int port)
Construct an unencrypted, unauthenticated, RFCOMM server socket. Call #accept to retrieve connections to this socket.

return
An RFCOMM BluetoothServerSocket
throws
IOException On error, for example Bluetooth not available, or insufficient permissions.
hide

        BluetoothServerSocket socket = new BluetoothServerSocket(
                BluetoothSocket.TYPE_RFCOMM, false, false, port);
        int errno = socket.mSocket.bindListen();
        if (errno != 0) {
            //TODO(BT): Throw the same exception error code
            // that the previous code was using.
            //socket.mSocket.throwErrnoNative(errno);
            throw new IOException("Error: " + errno);
        }
        return socket;
    
public BluetoothServerSocketlistenUsingInsecureRfcommWithServiceRecord(java.lang.String name, java.util.UUID uuid)
Create a listening, insecure RFCOMM Bluetooth socket with Service Record.

The link key is not required to be authenticated, i.e the communication may be vulnerable to Man In the Middle attacks. For Bluetooth 2.1 devices, the link will be encrypted, as encryption is mandartory. For legacy devices (pre Bluetooth 2.1 devices) the link will not be encrypted. Use {@link #listenUsingRfcommWithServiceRecord}, if an encrypted and authenticated communication channel is desired.

Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening {@link BluetoothServerSocket}.

The system will assign an unused RFCOMM channel to listen on.

The system will also register a Service Discovery Protocol (SDP) record with the local SDP server containing the specified UUID, service name, and auto-assigned channel. Remote Bluetooth devices can use the same UUID to query our SDP server and discover which channel to connect to. This SDP record will be removed when this socket is closed, or if this application closes unexpectedly.

Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to connect to this socket from another device using the same {@link UUID}.

Requires {@link android.Manifest.permission#BLUETOOTH}

param
name service name for SDP record
param
uuid uuid for SDP record
return
a listening RFCOMM BluetoothServerSocket
throws
IOException on error, for example Bluetooth not available, or insufficient permissions, or channel in use.

        return createNewRfcommSocketAndRecord(name, uuid, false, false);
    
public BluetoothServerSocketlistenUsingRfcommOn(int channel)
Create a listening, secure RFCOMM Bluetooth socket.

A remote device connecting to this socket will be authenticated and communication on this socket will be encrypted.

Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening {@link BluetoothServerSocket}.

Valid RFCOMM channels are in range 1 to 30.

Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}

param
channel RFCOMM channel to listen on
return
a listening RFCOMM BluetoothServerSocket
throws
IOException on error, for example Bluetooth not available, or insufficient permissions, or channel in use.
hide

        BluetoothServerSocket socket = new BluetoothServerSocket(
                BluetoothSocket.TYPE_RFCOMM, true, true, channel);
        int errno = socket.mSocket.bindListen();
        if (errno != 0) {
            //TODO(BT): Throw the same exception error code
            // that the previous code was using.
            //socket.mSocket.throwErrnoNative(errno);
            throw new IOException("Error: " + errno);
        }
        return socket;
    
public BluetoothServerSocketlistenUsingRfcommWithServiceRecord(java.lang.String name, java.util.UUID uuid)
Create a listening, secure RFCOMM Bluetooth socket with Service Record.

A remote device connecting to this socket will be authenticated and communication on this socket will be encrypted.

Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening {@link BluetoothServerSocket}.

The system will assign an unused RFCOMM channel to listen on.

The system will also register a Service Discovery Protocol (SDP) record with the local SDP server containing the specified UUID, service name, and auto-assigned channel. Remote Bluetooth devices can use the same UUID to query our SDP server and discover which channel to connect to. This SDP record will be removed when this socket is closed, or if this application closes unexpectedly.

Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to connect to this socket from another device using the same {@link UUID}.

Requires {@link android.Manifest.permission#BLUETOOTH}

param
name service name for SDP record
param
uuid uuid for SDP record
return
a listening RFCOMM BluetoothServerSocket
throws
IOException on error, for example Bluetooth not available, or insufficient permissions, or channel in use.

        return createNewRfcommSocketAndRecord(name, uuid, true, true);
    
public static BluetoothServerSocketlistenUsingScoOn()
Construct a SCO server socket. Call #accept to retrieve connections to this socket.

return
A SCO BluetoothServerSocket
throws
IOException On error, for example Bluetooth not available, or insufficient permissions.
hide

        BluetoothServerSocket socket = new BluetoothServerSocket(
                BluetoothSocket.TYPE_SCO, false, false, -1);
        int errno = socket.mSocket.bindListen();
        if (errno < 0) {
            //TODO(BT): Throw the same exception error code
            // that the previous code was using.
            //socket.mSocket.throwErrnoNative(errno);
        }
        return socket;
    
public android.util.PairreadOutOfBandData()
Read the local Out of Band Pairing Data

Requires {@link android.Manifest.permission#BLUETOOTH}

return
Pair of Hash and Randomizer
hide

        if (getState() != STATE_ON) return null;
        //TODO(BT
        /*
        try {
            byte[] hash;
            byte[] randomizer;

            byte[] ret = mService.readOutOfBandData();

            if (ret  == null || ret.length != 32) return null;

            hash = Arrays.copyOfRange(ret, 0, 16);
            randomizer = Arrays.copyOfRange(ret, 16, 32);

            if (DBG) {
                Log.d(TAG, "readOutOfBandData:" + Arrays.toString(hash) +
                  ":" + Arrays.toString(randomizer));
            }
            return new Pair<byte[], byte[]>(hash, randomizer);

        } catch (RemoteException e) {Log.e(TAG, "", e);}*/
        return null;
    
voidremoveServiceStateCallback(IBluetoothManagerCallback cb)

        synchronized (mProxyServiceStateCallbacks) {
            mProxyServiceStateCallbacks.remove(cb);
        }
    
public voidsetDiscoverableTimeout(int timeout)

hide

        if (getState() != STATE_ON) return;
        try {
            synchronized(mManagerCallback) {
                if (mService != null) mService.setDiscoverableTimeout(timeout);
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
    
public booleansetName(java.lang.String name)
Set the friendly Bluetooth name of the local Bluetooth adapter.

This name is visible to remote Bluetooth devices.

Valid Bluetooth names are a maximum of 248 bytes using UTF-8 encoding, although many remote devices can only display the first 40 characters, and some may be limited to just 20.

If Bluetooth state is not {@link #STATE_ON}, this API will return false. After turning on Bluetooth, wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON} to get the updated value.

Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}

param
name a valid Bluetooth name
return
true if the name was set, false otherwise

        if (getState() != STATE_ON) return false;
        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.setName(name);
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
public booleansetScanMode(int mode, int duration)
Set the Bluetooth scan mode of the local Bluetooth adapter.

The Bluetooth scan mode determines if the local adapter is connectable and/or discoverable from remote Bluetooth devices.

For privacy reasons, discoverable mode is automatically turned off after duration seconds. For example, 120 seconds should be enough for a remote device to initiate and complete its discovery process.

Valid scan mode values are: {@link #SCAN_MODE_NONE}, {@link #SCAN_MODE_CONNECTABLE}, {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.

If Bluetooth state is not {@link #STATE_ON}, this API will return false. After turning on Bluetooth, wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON} to get the updated value.

Requires {@link android.Manifest.permission#WRITE_SECURE_SETTINGS}

Applications cannot set the scan mode. They should use startActivityForResult( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE}) instead.

param
mode valid scan mode
param
duration time in seconds to apply scan mode, only used for {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}
return
true if the scan mode was set, false otherwise
hide

        if (getState() != STATE_ON) return false;
        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.setScanMode(mode, duration);
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
public booleansetScanMode(int mode)

hide

        if (getState() != STATE_ON) return false;
        /* getDiscoverableTimeout() to use the latest from NV than use 0 */
        return setScanMode(mode, getDiscoverableTimeout());
    
public booleanstartDiscovery()
Start the remote device discovery process.

The discovery process usually involves an inquiry scan of about 12 seconds, followed by a page scan of each new device to retrieve its Bluetooth name.

This is an asynchronous call, it will return immediately. Register for {@link #ACTION_DISCOVERY_STARTED} and {@link #ACTION_DISCOVERY_FINISHED} intents to determine exactly when the discovery starts and completes. Register for {@link BluetoothDevice#ACTION_FOUND} to be notified as remote Bluetooth devices are found.

Device discovery is a heavyweight procedure. New connections to remote Bluetooth devices should not be attempted while discovery is in progress, and existing connections will experience limited bandwidth and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing discovery. Discovery is not managed by the Activity, but is run as a system service, so an application should always call {@link BluetoothAdapter#cancelDiscovery()} even if it did not directly request a discovery, just to be sure.

Device discovery will only find remote devices that are currently discoverable (inquiry scan enabled). Many Bluetooth devices are not discoverable by default, and need to be entered into a special mode.

If Bluetooth state is not {@link #STATE_ON}, this API will return false. After turning on Bluetooth, wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON} to get the updated value.

Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.

return
true on success, false on error

        if (getState() != STATE_ON) return false;
        try {
            synchronized(mManagerCallback) {
                if (mService != null) return mService.startDiscovery();
            }
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    
public booleanstartLeScan(android.bluetooth.BluetoothAdapter$LeScanCallback callback)
Starts a scan for Bluetooth LE devices.

Results of the scan are reported using the {@link LeScanCallback#onLeScan} callback.

Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.

param
callback the callback LE scan results are delivered
return
true, if the scan was started successfully
deprecated
use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)} instead.

        return startLeScan(null, callback);
    
public booleanstartLeScan(java.util.UUID[] serviceUuids, android.bluetooth.BluetoothAdapter$LeScanCallback callback)
Starts a scan for Bluetooth LE devices, looking for devices that advertise given services.

Devices which advertise all specified services are reported using the {@link LeScanCallback#onLeScan} callback.

Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.

param
serviceUuids Array of services to look for
param
callback the callback LE scan results are delivered
return
true, if the scan was started successfully
deprecated
use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)} instead.

        if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);
        if (callback == null) {
            if (DBG) Log.e(TAG, "startLeScan: null callback");
            return false;
        }
        BluetoothLeScanner scanner = getBluetoothLeScanner();
        if (scanner == null) {
            if (DBG) Log.e(TAG, "startLeScan: cannot get BluetoothLeScanner");
            return false;
        }

        synchronized(mLeScanClients) {
            if (mLeScanClients.containsKey(callback)) {
                if (DBG) Log.e(TAG, "LE Scan has already started");
                return false;
            }

            try {
                IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
                if (iGatt == null) {
                    // BLE is not supported
                    return false;
                }

                ScanCallback scanCallback = new ScanCallback() {
                    @Override
                    public void onScanResult(int callbackType, ScanResult result) {
                        if (callbackType != ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
                            // Should not happen.
                            Log.e(TAG, "LE Scan has already started");
                            return;
                        }
                        ScanRecord scanRecord = result.getScanRecord();
                        if (scanRecord == null) {
                            return;
                        }
                        if (serviceUuids != null) {
                            List<ParcelUuid> uuids = new ArrayList<ParcelUuid>();
                            for (UUID uuid : serviceUuids) {
                                uuids.add(new ParcelUuid(uuid));
                            }
                            List<ParcelUuid> scanServiceUuids = scanRecord.getServiceUuids();
                            if (scanServiceUuids == null || !scanServiceUuids.containsAll(uuids)) {
                                if (DBG) Log.d(TAG, "uuids does not match");
                                return;
                            }
                        }
                        callback.onLeScan(result.getDevice(), result.getRssi(),
                                scanRecord.getBytes());
                    }
                };
                ScanSettings settings = new ScanSettings.Builder()
                    .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                    .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();

                List<ScanFilter> filters = new ArrayList<ScanFilter>();
                if (serviceUuids != null && serviceUuids.length > 0) {
                    // Note scan filter does not support matching an UUID array so we put one
                    // UUID to hardware and match the whole array in callback.
                    ScanFilter filter = new ScanFilter.Builder().setServiceUuid(
                            new ParcelUuid(serviceUuids[0])).build();
                    filters.add(filter);
                }
                scanner.startScan(filters, settings, scanCallback);

                mLeScanClients.put(callback, scanCallback);
                return true;

            } catch (RemoteException e) {
                Log.e(TAG,"",e);
            }
        }
        return false;
    
public voidstopLeScan(android.bluetooth.BluetoothAdapter$LeScanCallback callback)
Stops an ongoing Bluetooth LE device scan.

Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.

param
callback used to identify which scan to stop must be the same handle used to start the scan
deprecated
Use {@link BluetoothLeScanner#stopScan(ScanCallback)} instead.

        if (DBG) Log.d(TAG, "stopLeScan()");
        BluetoothLeScanner scanner = getBluetoothLeScanner();
        if (scanner == null) {
            return;
        }
        synchronized (mLeScanClients) {
            ScanCallback scanCallback = mLeScanClients.remove(callback);
            if (scanCallback == null) {
                if (DBG) Log.d(TAG, "scan not started yet");
                return;
            }
            scanner.stopScan(scanCallback);
        }
    
private java.util.SettoDeviceSet(BluetoothDevice[] devices)

        Set<BluetoothDevice> deviceSet = new HashSet<BluetoothDevice>(Arrays.asList(devices));
        return Collections.unmodifiableSet(deviceSet);