FileDocCategorySizeDatePackage
BluetoothGatt.javaAPI DocAndroid 5.1 API51469Thu Mar 12 22:22:10 GMT 2015android.bluetooth

BluetoothGatt

public final class BluetoothGatt extends Object implements BluetoothProfile
Public API for the Bluetooth GATT Profile.

This class provides Bluetooth GATT functionality to enable communication with Bluetooth Smart or Smart Ready devices.

To connect to a remote peripheral device, create a {@link BluetoothGattCallback} and call {@link BluetoothDevice#connectGatt} to get a instance of this class. GATT capable devices can be discovered using the Bluetooth device discovery or BLE scan process.

Fields Summary
private static final String
TAG
private static final boolean
DBG
private static final boolean
VDBG
private final android.content.Context
mContext
private IBluetoothGatt
mService
private BluetoothGattCallback
mCallback
private int
mClientIf
private boolean
mAuthRetry
private BluetoothDevice
mDevice
private boolean
mAutoConnect
private int
mConnState
private final Object
mStateLock
private Boolean
mDeviceBusy
private int
mTransport
private static final int
CONN_STATE_IDLE
private static final int
CONN_STATE_CONNECTING
private static final int
CONN_STATE_CONNECTED
private static final int
CONN_STATE_DISCONNECTING
private static final int
CONN_STATE_CLOSED
private List
mServices
public static final int
GATT_SUCCESS
A GATT operation completed successfully
public static final int
GATT_READ_NOT_PERMITTED
GATT read operation is not permitted
public static final int
GATT_WRITE_NOT_PERMITTED
GATT write operation is not permitted
public static final int
GATT_INSUFFICIENT_AUTHENTICATION
Insufficient authentication for a given operation
public static final int
GATT_REQUEST_NOT_SUPPORTED
The given request is not supported
public static final int
GATT_INSUFFICIENT_ENCRYPTION
Insufficient encryption for a given operation
public static final int
GATT_INVALID_OFFSET
A read or write operation was requested with an invalid offset
public static final int
GATT_INVALID_ATTRIBUTE_LENGTH
A write operation exceeds the maximum length of the attribute
public static final int
GATT_CONNECTION_CONGESTED
A remote device connection is congested.
public static final int
GATT_FAILURE
A GATT operation failed, errors other than the above
public static final int
CONNECTION_PRIORITY_BALANCED
Connection paramter update - Use the connection paramters recommended by the Bluetooth SIG. This is the default value if no connection parameter update is requested.
public static final int
CONNECTION_PRIORITY_HIGH
Connection paramter update - Request a high priority, low latency connection. An application should only request high priority connection paramters to transfer large amounts of data over LE quickly. Once the transfer is complete, the application should request {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED} connectoin parameters to reduce energy use.
public static final int
CONNECTION_PRIORITY_LOW_POWER
Connection paramter update - Request low power, reduced data rate connection parameters.
static final int
AUTHENTICATION_NONE
No authentication required.
static final int
AUTHENTICATION_NO_MITM
Authentication requested; no man-in-the-middle protection required.
static final int
AUTHENTICATION_MITM
Authentication with man-in-the-middle protection requested.
private final IBluetoothGattCallback
mBluetoothGattCallback
Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation.
Constructors Summary
BluetoothGatt(android.content.Context context, IBluetoothGatt iGatt, BluetoothDevice device, int transport)


    /*package*/      
                                  
        mContext = context;
        mService = iGatt;
        mDevice = device;
        mTransport = transport;
        mServices = new ArrayList<BluetoothGattService>();

        mConnState = CONN_STATE_IDLE;
    
Methods Summary
public voidabortReliableWrite()
Cancels a reliable write transaction for a given device.

Calling this function will discard all queued characteristic write operations for a given remote device.

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

        if (VDBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress());
        if (mService == null || mClientIf == 0) return;

        try {
            mService.endReliableWrite(mClientIf, mDevice.getAddress(), false);
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
        }
    
public voidabortReliableWrite(BluetoothDevice mDevice)

deprecated
Use {@link #abortReliableWrite()}

        abortReliableWrite();
    
public booleanbeginReliableWrite()
Initiates a reliable write transaction for a given remote device.

Once a reliable write transaction has been initiated, all calls to {@link #writeCharacteristic} are sent to the remote device for verification and queued up for atomic execution. The application will receive an {@link BluetoothGattCallback#onCharacteristicWrite} callback in response to every {@link #writeCharacteristic} call and is responsible for verifying if the value has been transmitted accurately.

After all characteristics have been queued up and verified, {@link #executeReliableWrite} will execute all writes. If a characteristic was not written correctly, calling {@link #abortReliableWrite} will cancel the current transaction without commiting any values on the remote device.

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

return
true, if the reliable write transaction has been initiated

        if (VDBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress());
        if (mService == null || mClientIf == 0) return false;

        try {
            mService.beginReliableWrite(mClientIf, mDevice.getAddress());
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }

        return true;
    
public voidclose()
Close this Bluetooth GATT client. Application should call this method as early as possible after it is done with this GATT client.

        if (DBG) Log.d(TAG, "close()");

        unregisterApp();
        mConnState = CONN_STATE_CLOSED;
    
booleanconnect(java.lang.Boolean autoConnect, BluetoothGattCallback callback)
Initiate a connection to a Bluetooth GATT capable device.

The connection may not be established right away, but will be completed when the remote device is available. A {@link BluetoothGattCallback#onConnectionStateChange} callback will be invoked when the connection state changes as a result of this function.

The autoConnect parameter determines whether to actively connect to the remote device, or rather passively scan and finalize the connection when the remote device is in range/available. Generally, the first ever connection to a device should be direct (autoConnect set to false) and subsequent connections to known devices should be invoked with the autoConnect parameter set to true.

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

param
device Remote device to connect to
param
autoConnect Whether to directly connect to the remote device (false) or to automatically connect as soon as the remote device becomes available (true).
return
true, if the connection attempt was initiated successfully

        if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
        synchronized(mStateLock) {
            if (mConnState != CONN_STATE_IDLE) {
                throw new IllegalStateException("Not idle");
            }
            mConnState = CONN_STATE_CONNECTING;
        }
        if (!registerApp(callback)) {
            synchronized(mStateLock) {
                mConnState = CONN_STATE_IDLE;
            }
            Log.e(TAG, "Failed to register callback");
            return false;
        }

        // the connection will continue after successful callback registration
        mAutoConnect = autoConnect;
        return true;
    
public booleanconnect()
Connect back to remote device.

This method is used to re-connect to a remote device after the connection has been dropped. If the device is not in range, the re-connection will be triggered once the device is back in range.

return
true, if the connection attempt was initiated successfully

        try {
            mService.clientConnect(mClientIf, mDevice.getAddress(),
                                   false, mTransport); // autoConnect is inverse of "isDirect"
            return true;
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }
    
public voiddisconnect()
Disconnects an established connection, or cancels a connection attempt currently in progress.

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

        if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress());
        if (mService == null || mClientIf == 0) return;

        try {
            mService.clientDisconnect(mClientIf, mDevice.getAddress());
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
        }
    
public booleandiscoverServices()
Discovers services offered by a remote device as well as their characteristics and descriptors.

This is an asynchronous operation. Once service discovery is completed, the {@link BluetoothGattCallback#onServicesDiscovered} callback is triggered. If the discovery was successful, the remote services can be retrieved using the {@link #getServices} function.

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

return
true, if the remote service discovery has been started

        if (DBG) Log.d(TAG, "discoverServices() - device: " + mDevice.getAddress());
        if (mService == null || mClientIf == 0) return false;

        mServices.clear();

        try {
            mService.discoverServices(mClientIf, mDevice.getAddress());
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }

        return true;
    
public booleanexecuteReliableWrite()
Executes a reliable write transaction for a given remote device.

This function will commit all queued up characteristic write operations for a given remote device.

A {@link BluetoothGattCallback#onReliableWriteCompleted} callback is invoked to indicate whether the transaction has been executed correctly.

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

return
true, if the request to execute the transaction has been sent

        if (VDBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
        if (mService == null || mClientIf == 0) return false;

        synchronized(mDeviceBusy) {
            if (mDeviceBusy) return false;
            mDeviceBusy = true;
        }

        try {
            mService.endReliableWrite(mClientIf, mDevice.getAddress(), true);
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            mDeviceBusy = false;
            return false;
        }

        return true;
    
public java.util.ListgetConnectedDevices()
Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} with {@link BluetoothProfile#GATT} as argument

throws
UnsupportedOperationException

        throw new UnsupportedOperationException
            ("Use BluetoothManager#getConnectedDevices instead.");
    
public intgetConnectionState(BluetoothDevice device)
Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} with {@link BluetoothProfile#GATT} as argument

throws
UnsupportedOperationException

        throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead.");
    
public BluetoothDevicegetDevice()
Return the remote bluetooth device this GATT client targets to

return
remote bluetooth device

        return mDevice;
    
public java.util.ListgetDevicesMatchingConnectionStates(int[] states)
Not supported - please use {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])} with {@link BluetoothProfile#GATT} as first argument

throws
UnsupportedOperationException

        throw new UnsupportedOperationException
            ("Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
    
public BluetoothGattServicegetService(java.util.UUID uuid)
Returns a {@link BluetoothGattService}, if the requested UUID is supported by the remote device.

This function requires that service discovery has been completed for the given device.

If multiple instances of the same service (as identified by UUID) exist, the first instance of the service is returned.

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

param
uuid UUID of the requested service
return
BluetoothGattService if supported, or null if the requested service is not offered by the remote device.

        for (BluetoothGattService service : mServices) {
            if (service.getDevice().equals(mDevice) &&
                service.getUuid().equals(uuid)) {
                return service;
            }
        }

        return null;
    
BluetoothGattServicegetService(BluetoothDevice device, java.util.UUID uuid, int instanceId, int type)
Returns a service by UUID, instance and type.

hide

        for(BluetoothGattService svc : mServices) {
            if (svc.getDevice().equals(device) &&
                svc.getType() == type &&
                svc.getInstanceId() == instanceId &&
                svc.getUuid().equals(uuid)) {
                return svc;
            }
        }
        return null;
    
public java.util.ListgetServices()
Returns a list of GATT services offered by the remote device.

This function requires that service discovery has been completed for the given device.

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

return
List of services on the remote device. Returns an empty list if service discovery has not yet been performed.

        List<BluetoothGattService> result =
                new ArrayList<BluetoothGattService>();

        for (BluetoothGattService service : mServices) {
            if (service.getDevice().equals(mDevice)) {
                result.add(service);
            }
        }

        return result;
    
public booleanreadCharacteristic(BluetoothGattCharacteristic characteristic)
Reads the requested characteristic from the associated remote device.

This is an asynchronous operation. The result of the read operation is reported by the {@link BluetoothGattCallback#onCharacteristicRead} callback.

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

param
characteristic Characteristic to read from the remote device
return
true, if the read operation was initiated successfully

        if ((characteristic.getProperties() &
                BluetoothGattCharacteristic.PROPERTY_READ) == 0) return false;

        if (VDBG) Log.d(TAG, "readCharacteristic() - uuid: " + characteristic.getUuid());
        if (mService == null || mClientIf == 0) return false;

        BluetoothGattService service = characteristic.getService();
        if (service == null) return false;

        BluetoothDevice device = service.getDevice();
        if (device == null) return false;

        synchronized(mDeviceBusy) {
            if (mDeviceBusy) return false;
            mDeviceBusy = true;
        }

        try {
            mService.readCharacteristic(mClientIf, device.getAddress(),
                service.getType(), service.getInstanceId(),
                new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
                new ParcelUuid(characteristic.getUuid()), AUTHENTICATION_NONE);
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            mDeviceBusy = false;
            return false;
        }

        return true;
    
public booleanreadDescriptor(BluetoothGattDescriptor descriptor)
Reads the value for a given descriptor from the associated remote device.

Once the read operation has been completed, the {@link BluetoothGattCallback#onDescriptorRead} callback is triggered, signaling the result of the operation.

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

param
descriptor Descriptor value to read from the remote device
return
true, if the read operation was initiated successfully

        if (VDBG) Log.d(TAG, "readDescriptor() - uuid: " + descriptor.getUuid());
        if (mService == null || mClientIf == 0) return false;

        BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
        if (characteristic == null) return false;

        BluetoothGattService service = characteristic.getService();
        if (service == null) return false;

        BluetoothDevice device = service.getDevice();
        if (device == null) return false;

        synchronized(mDeviceBusy) {
            if (mDeviceBusy) return false;
            mDeviceBusy = true;
        }

        try {
            mService.readDescriptor(mClientIf, device.getAddress(), service.getType(),
                service.getInstanceId(), new ParcelUuid(service.getUuid()),
                characteristic.getInstanceId(), new ParcelUuid(characteristic.getUuid()),
                descriptor.getInstanceId(), new ParcelUuid(descriptor.getUuid()),
                AUTHENTICATION_NONE);
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            mDeviceBusy = false;
            return false;
        }

        return true;
    
public booleanreadRemoteRssi()
Read the RSSI for a connected remote device.

The {@link BluetoothGattCallback#onReadRemoteRssi} callback will be invoked when the RSSI value has been read.

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

return
true, if the RSSI value has been requested successfully

        if (DBG) Log.d(TAG, "readRssi() - device: " + mDevice.getAddress());
        if (mService == null || mClientIf == 0) return false;

        try {
            mService.readRemoteRssi(mClientIf, mDevice.getAddress());
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }

        return true;
    
public booleanrefresh()
Clears the internal cache and forces a refresh of the services from the remote device.

hide

        if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress());
        if (mService == null || mClientIf == 0) return false;

        try {
            mService.refreshDevice(mClientIf, mDevice.getAddress());
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }

        return true;
    
private booleanregisterApp(BluetoothGattCallback callback)
Register an application callback to start using GATT.

This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered} is used to notify success or failure if the function returns true.

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

param
callback GATT callback handler that will receive asynchronous callbacks.
return
If true, the callback will be called to notify success or failure, false on immediate error

        if (DBG) Log.d(TAG, "registerApp()");
        if (mService == null) return false;

        mCallback = callback;
        UUID uuid = UUID.randomUUID();
        if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid);

        try {
            mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }

        return true;
    
public booleanrequestConnectionPriority(int connectionPriority)
Request a connection parameter update.

This function will send a connection parameter update request to the remote device.

param
connectionPriority Request a specific connection priority. Must be one of {@link BluetoothGatt#CONNECTION_PRIORITY_BALANCED}, {@link BluetoothGatt#CONNECTION_PRIORITY_HIGH} or {@link BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER}.
throws
IllegalArgumentException If the parameters are outside of their specified range.

        if (connectionPriority < CONNECTION_PRIORITY_BALANCED ||
            connectionPriority > CONNECTION_PRIORITY_LOW_POWER) {
            throw new IllegalArgumentException("connectionPriority not within valid range");
        }

        if (DBG) Log.d(TAG, "requestConnectionPriority() - params: " + connectionPriority);
        if (mService == null || mClientIf == 0) return false;

        try {
            mService.connectionParameterUpdate(mClientIf, mDevice.getAddress(), connectionPriority);
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }

        return true;
    
public booleanrequestMtu(int mtu)
Request an MTU size used for a given connection.

When performing a write request operation (write without response), the data sent is truncated to the MTU size. This function may be used to request a larger MTU size to be able to send more data at once.

A {@link BluetoothGattCallback#onMtuChanged} callback will indicate whether this operation was successful.

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

return
true, if the new MTU value has been requested successfully

        if (DBG) Log.d(TAG, "configureMTU() - device: " + mDevice.getAddress()
                            + " mtu: " + mtu);
        if (mService == null || mClientIf == 0) return false;

        try {
            mService.configureMTU(mClientIf, mDevice.getAddress(), mtu);
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }

        return true;
    
public booleansetCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enable)
Enable or disable notifications/indications for a given characteristic.

Once notifications are enabled for a characteristic, a {@link BluetoothGattCallback#onCharacteristicChanged} callback will be triggered if the remote device indicates that the given characteristic has changed.

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

param
characteristic The characteristic for which to enable notifications
param
enable Set to true to enable notifications/indications
return
true, if the requested notification status was set successfully

        if (DBG) Log.d(TAG, "setCharacteristicNotification() - uuid: " + characteristic.getUuid()
                         + " enable: " + enable);
        if (mService == null || mClientIf == 0) return false;

        BluetoothGattService service = characteristic.getService();
        if (service == null) return false;

        BluetoothDevice device = service.getDevice();
        if (device == null) return false;

        try {
            mService.registerForNotification(mClientIf, device.getAddress(),
                service.getType(), service.getInstanceId(),
                new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
                new ParcelUuid(characteristic.getUuid()),
                enable);
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            return false;
        }

        return true;
    
private voidunregisterApp()
Unregister the current application and callbacks.

        if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf);
        if (mService == null || mClientIf == 0) return;

        try {
            mCallback = null;
            mService.unregisterClient(mClientIf);
            mClientIf = 0;
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
        }
    
public booleanwriteCharacteristic(BluetoothGattCharacteristic characteristic)
Writes a given characteristic and its values to the associated remote device.

Once the write operation has been completed, the {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked, reporting the result of the operation.

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

param
characteristic Characteristic to write on the remote device
return
true, if the write operation was initiated successfully

        if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0
            && (characteristic.getProperties() &
                BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) return false;

        if (VDBG) Log.d(TAG, "writeCharacteristic() - uuid: " + characteristic.getUuid());
        if (mService == null || mClientIf == 0 || characteristic.getValue() == null) return false;

        BluetoothGattService service = characteristic.getService();
        if (service == null) return false;

        BluetoothDevice device = service.getDevice();
        if (device == null) return false;

        synchronized(mDeviceBusy) {
            if (mDeviceBusy) return false;
            mDeviceBusy = true;
        }

        try {
            mService.writeCharacteristic(mClientIf, device.getAddress(),
                service.getType(), service.getInstanceId(),
                new ParcelUuid(service.getUuid()), characteristic.getInstanceId(),
                new ParcelUuid(characteristic.getUuid()),
                characteristic.getWriteType(), AUTHENTICATION_NONE,
                characteristic.getValue());
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            mDeviceBusy = false;
            return false;
        }

        return true;
    
public booleanwriteDescriptor(BluetoothGattDescriptor descriptor)
Write the value of a given descriptor to the associated remote device.

A {@link BluetoothGattCallback#onDescriptorWrite} callback is triggered to report the result of the write operation.

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

param
descriptor Descriptor to write to the associated remote device
return
true, if the write operation was initiated successfully

        if (VDBG) Log.d(TAG, "writeDescriptor() - uuid: " + descriptor.getUuid());
        if (mService == null || mClientIf == 0 || descriptor.getValue() == null) return false;

        BluetoothGattCharacteristic characteristic = descriptor.getCharacteristic();
        if (characteristic == null) return false;

        BluetoothGattService service = characteristic.getService();
        if (service == null) return false;

        BluetoothDevice device = service.getDevice();
        if (device == null) return false;

        synchronized(mDeviceBusy) {
            if (mDeviceBusy) return false;
            mDeviceBusy = true;
        }

        try {
            mService.writeDescriptor(mClientIf, device.getAddress(), service.getType(),
                service.getInstanceId(), new ParcelUuid(service.getUuid()),
                characteristic.getInstanceId(), new ParcelUuid(characteristic.getUuid()),
                descriptor.getInstanceId(), new ParcelUuid(descriptor.getUuid()),
                characteristic.getWriteType(), AUTHENTICATION_NONE,
                descriptor.getValue());
        } catch (RemoteException e) {
            Log.e(TAG,"",e);
            mDeviceBusy = false;
            return false;
        }

        return true;