/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.bluetooth;

import android.os.ParcelUuid;
import android.os.RemoteException;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

Public API for the Bluetooth GATT Profile server role.

This class provides Bluetooth GATT server role functionality, allowing applications to create Bluetooth Smart services and characteristics.

BluetoothGattServer is a proxy object for controlling the Bluetooth Service via IPC. Use BluetoothManager.openGattServer to get an instance of this class.

/** * Public API for the Bluetooth GATT Profile server role. * * <p>This class provides Bluetooth GATT server role functionality, * allowing applications to create Bluetooth Smart services and * characteristics. * * <p>BluetoothGattServer is a proxy object for controlling the Bluetooth Service * via IPC. Use {@link BluetoothManager#openGattServer} to get an instance * of this class. */
public final class BluetoothGattServer implements BluetoothProfile { private static final String TAG = "BluetoothGattServer"; private static final boolean DBG = true; private static final boolean VDBG = false; private BluetoothAdapter mAdapter; private IBluetoothGatt mService; private BluetoothGattServerCallback mCallback; private Object mServerIfLock = new Object(); private int mServerIf; private int mTransport; private BluetoothGattService mPendingService; private List<BluetoothGattService> mServices; private static final int CALLBACK_REG_TIMEOUT = 10000;
Bluetooth GATT interface callbacks
/** * Bluetooth GATT interface callbacks */
private final IBluetoothGattServerCallback mBluetoothGattServerCallback = new IBluetoothGattServerCallback.Stub() {
Application interface registered - app is ready to go
@hide
/** * Application interface registered - app is ready to go * @hide */
@Override public void onServerRegistered(int status, int serverIf) { if (DBG) { Log.d(TAG, "onServerRegistered() - status=" + status + " serverIf=" + serverIf); } synchronized (mServerIfLock) { if (mCallback != null) { mServerIf = serverIf; mServerIfLock.notify(); } else { // registration timeout Log.e(TAG, "onServerRegistered: mCallback is null"); } } }
Server connection state changed
@hide
/** * Server connection state changed * @hide */
@Override public void onServerConnectionState(int status, int serverIf, boolean connected, String address) { if (DBG) { Log.d(TAG, "onServerConnectionState() - status=" + status + " serverIf=" + serverIf + " device=" + address); } try { mCallback.onConnectionStateChange(mAdapter.getRemoteDevice(address), status, connected ? BluetoothProfile.STATE_CONNECTED : BluetoothProfile.STATE_DISCONNECTED); } catch (Exception ex) { Log.w(TAG, "Unhandled exception in callback", ex); } }
Service has been added
@hide
/** * Service has been added * @hide */
@Override public void onServiceAdded(int status, BluetoothGattService service) { if (DBG) { Log.d(TAG, "onServiceAdded() - handle=" + service.getInstanceId() + " uuid=" + service.getUuid() + " status=" + status); } if (mPendingService == null) { return; } BluetoothGattService tmp = mPendingService; mPendingService = null; // Rewrite newly assigned handles to existing service. tmp.setInstanceId(service.getInstanceId()); List<BluetoothGattCharacteristic> temp_chars = tmp.getCharacteristics(); List<BluetoothGattCharacteristic> svc_chars = service.getCharacteristics(); for (int i = 0; i < svc_chars.size(); i++) { BluetoothGattCharacteristic temp_char = temp_chars.get(i); BluetoothGattCharacteristic svc_char = svc_chars.get(i); temp_char.setInstanceId(svc_char.getInstanceId()); List<BluetoothGattDescriptor> temp_descs = temp_char.getDescriptors(); List<BluetoothGattDescriptor> svc_descs = svc_char.getDescriptors(); for (int j = 0; j < svc_descs.size(); j++) { temp_descs.get(j).setInstanceId(svc_descs.get(j).getInstanceId()); } } mServices.add(tmp); try { mCallback.onServiceAdded((int) status, tmp); } catch (Exception ex) { Log.w(TAG, "Unhandled exception in callback", ex); } }
Remote client characteristic read request.
@hide
/** * Remote client characteristic read request. * @hide */
@Override public void onCharacteristicReadRequest(String address, int transId, int offset, boolean isLong, int handle) { if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle); BluetoothDevice device = mAdapter.getRemoteDevice(address); BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle); if (characteristic == null) { Log.w(TAG, "onCharacteristicReadRequest() no char for handle " + handle); return; } try { mCallback.onCharacteristicReadRequest(device, transId, offset, characteristic); } catch (Exception ex) { Log.w(TAG, "Unhandled exception in callback", ex); } }
Remote client descriptor read request.
@hide
/** * Remote client descriptor read request. * @hide */
@Override public void onDescriptorReadRequest(String address, int transId, int offset, boolean isLong, int handle) { if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle); BluetoothDevice device = mAdapter.getRemoteDevice(address); BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle); if (descriptor == null) { Log.w(TAG, "onDescriptorReadRequest() no desc for handle " + handle); return; } try { mCallback.onDescriptorReadRequest(device, transId, offset, descriptor); } catch (Exception ex) { Log.w(TAG, "Unhandled exception in callback", ex); } }
Remote client characteristic write request.
@hide
/** * Remote client characteristic write request. * @hide */
@Override public void onCharacteristicWriteRequest(String address, int transId, int offset, int length, boolean isPrep, boolean needRsp, int handle, byte[] value) { if (VDBG) Log.d(TAG, "onCharacteristicWriteRequest() - handle=" + handle); BluetoothDevice device = mAdapter.getRemoteDevice(address); BluetoothGattCharacteristic characteristic = getCharacteristicByHandle(handle); if (characteristic == null) { Log.w(TAG, "onCharacteristicWriteRequest() no char for handle " + handle); return; } try { mCallback.onCharacteristicWriteRequest(device, transId, characteristic, isPrep, needRsp, offset, value); } catch (Exception ex) { Log.w(TAG, "Unhandled exception in callback", ex); } }
Remote client descriptor write request.
@hide
/** * Remote client descriptor write request. * @hide */
@Override public void onDescriptorWriteRequest(String address, int transId, int offset, int length, boolean isPrep, boolean needRsp, int handle, byte[] value) { if (VDBG) Log.d(TAG, "onDescriptorWriteRequest() - handle=" + handle); BluetoothDevice device = mAdapter.getRemoteDevice(address); BluetoothGattDescriptor descriptor = getDescriptorByHandle(handle); if (descriptor == null) { Log.w(TAG, "onDescriptorWriteRequest() no desc for handle " + handle); return; } try { mCallback.onDescriptorWriteRequest(device, transId, descriptor, isPrep, needRsp, offset, value); } catch (Exception ex) { Log.w(TAG, "Unhandled exception in callback", ex); } }
Execute pending writes.
@hide
/** * Execute pending writes. * @hide */
@Override public void onExecuteWrite(String address, int transId, boolean execWrite) { if (DBG) { Log.d(TAG, "onExecuteWrite() - " + "device=" + address + ", transId=" + transId + "execWrite=" + execWrite); } BluetoothDevice device = mAdapter.getRemoteDevice(address); if (device == null) return; try { mCallback.onExecuteWrite(device, transId, execWrite); } catch (Exception ex) { Log.w(TAG, "Unhandled exception in callback", ex); } }
A notification/indication has been sent.
@hide
/** * A notification/indication has been sent. * @hide */
@Override public void onNotificationSent(String address, int status) { if (VDBG) { Log.d(TAG, "onNotificationSent() - " + "device=" + address + ", status=" + status); } BluetoothDevice device = mAdapter.getRemoteDevice(address); if (device == null) return; try { mCallback.onNotificationSent(device, status); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } }
The MTU for a connection has changed
@hide
/** * The MTU for a connection has changed * @hide */
@Override public void onMtuChanged(String address, int mtu) { if (DBG) { Log.d(TAG, "onMtuChanged() - " + "device=" + address + ", mtu=" + mtu); } BluetoothDevice device = mAdapter.getRemoteDevice(address); if (device == null) return; try { mCallback.onMtuChanged(device, mtu); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } }
The PHY for a connection was updated
@hide
/** * The PHY for a connection was updated * @hide */
@Override public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) { if (DBG) { Log.d(TAG, "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy + ", rxPHy=" + rxPhy); } BluetoothDevice device = mAdapter.getRemoteDevice(address); if (device == null) return; try { mCallback.onPhyUpdate(device, txPhy, rxPhy, status); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } }
The PHY for a connection was read
@hide
/** * The PHY for a connection was read * @hide */
@Override public void onPhyRead(String address, int txPhy, int rxPhy, int status) { if (DBG) { Log.d(TAG, "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy + ", rxPHy=" + rxPhy); } BluetoothDevice device = mAdapter.getRemoteDevice(address); if (device == null) return; try { mCallback.onPhyRead(device, txPhy, rxPhy, status); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } }
Callback invoked when the given connection is updated
@hide
/** * Callback invoked when the given connection is updated * @hide */
@Override public void onConnectionUpdated(String address, int interval, int latency, int timeout, int status) { if (DBG) { Log.d(TAG, "onConnectionUpdated() - Device=" + address + " interval=" + interval + " latency=" + latency + " timeout=" + timeout + " status=" + status); } BluetoothDevice device = mAdapter.getRemoteDevice(address); if (device == null) return; try { mCallback.onConnectionUpdated(device, interval, latency, timeout, status); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } } };
Create a BluetoothGattServer proxy object.
/** * Create a BluetoothGattServer proxy object. */
/*package*/ BluetoothGattServer(IBluetoothGatt iGatt, int transport) { mService = iGatt; mAdapter = BluetoothAdapter.getDefaultAdapter(); mCallback = null; mServerIf = 0; mTransport = transport; mServices = new ArrayList<BluetoothGattService>(); }
Returns a characteristic with given handle.
@hide
/** * Returns a characteristic with given handle. * * @hide */
/*package*/ BluetoothGattCharacteristic getCharacteristicByHandle(int handle) { for (BluetoothGattService svc : mServices) { for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) { if (charac.getInstanceId() == handle) { return charac; } } } return null; }
Returns a descriptor with given handle.
@hide
/** * Returns a descriptor with given handle. * * @hide */
/*package*/ BluetoothGattDescriptor getDescriptorByHandle(int handle) { for (BluetoothGattService svc : mServices) { for (BluetoothGattCharacteristic charac : svc.getCharacteristics()) { for (BluetoothGattDescriptor desc : charac.getDescriptors()) { if (desc.getInstanceId() == handle) { return desc; } } } } return null; }
Close this GATT server instance. Application should call this method as early as possible after it is done with this GATT server.
/** * Close this GATT server instance. * * Application should call this method as early as possible after it is done with * this GATT server. */
public void close() { if (DBG) Log.d(TAG, "close()"); unregisterCallback(); }
Register an application callback to start using GattServer.

This is an asynchronous call. The callback is used to notify success or failure if the function returns true.

Requires BLUETOOTH.BLUETOOTH permission.

Params:
  • callback – GATT callback handler that will receive asynchronous callbacks.
Returns:true, the callback will be called to notify success or failure, false on immediate error
/** * Register an application callback to start using GattServer. * * <p>This is an asynchronous call. The callback is used to notify * success or failure if the function returns true. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param callback GATT callback handler that will receive asynchronous callbacks. * @return true, the callback will be called to notify success or failure, false on immediate * error */
/*package*/ boolean registerCallback(BluetoothGattServerCallback callback) { if (DBG) Log.d(TAG, "registerCallback()"); if (mService == null) { Log.e(TAG, "GATT service not available"); return false; } UUID uuid = UUID.randomUUID(); if (DBG) Log.d(TAG, "registerCallback() - UUID=" + uuid); synchronized (mServerIfLock) { if (mCallback != null) { Log.e(TAG, "App can register callback only once"); return false; } mCallback = callback; try { mService.registerServer(new ParcelUuid(uuid), mBluetoothGattServerCallback); } catch (RemoteException e) { Log.e(TAG, "", e); mCallback = null; return false; } try { mServerIfLock.wait(CALLBACK_REG_TIMEOUT); } catch (InterruptedException e) { Log.e(TAG, "" + e); mCallback = null; } if (mServerIf == 0) { mCallback = null; return false; } else { return true; } } }
Unregister the current application and callbacks.
/** * Unregister the current application and callbacks. */
private void unregisterCallback() { if (DBG) Log.d(TAG, "unregisterCallback() - mServerIf=" + mServerIf); if (mService == null || mServerIf == 0) return; try { mCallback = null; mService.unregisterServer(mServerIf); mServerIf = 0; } catch (RemoteException e) { Log.e(TAG, "", e); } }
Returns a service by UUID, instance and type.
@hide
/** * Returns a service by UUID, instance and type. * * @hide */
/*package*/ BluetoothGattService getService(UUID uuid, int instanceId, int type) { for (BluetoothGattService svc : mServices) { if (svc.getType() == type && svc.getInstanceId() == instanceId && svc.getUuid().equals(uuid)) { return svc; } } return null; }
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 BluetoothGattServerCallback.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 BLUETOOTH.BLUETOOTH permission.

Params:
  • autoConnect – Whether to directly connect to the remote device (false) or to automatically connect as soon as the remote device becomes available (true).
Returns:true, if the connection attempt was initiated successfully
/** * Initiate a connection to a Bluetooth GATT capable device. * * <p>The connection may not be established right away, but will be * completed when the remote device is available. A * {@link BluetoothGattServerCallback#onConnectionStateChange} callback will be * invoked when the connection state changes as a result of this function. * * <p>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. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @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 */
public boolean connect(BluetoothDevice device, boolean autoConnect) { if (DBG) { Log.d(TAG, "connect() - device: " + device.getAddress() + ", auto: " + autoConnect); } if (mService == null || mServerIf == 0) return false; try { // autoConnect is inverse of "isDirect" mService.serverConnect(mServerIf, device.getAddress(), !autoConnect, mTransport); } catch (RemoteException e) { Log.e(TAG, "", e); return false; } return true; }
Disconnects an established connection, or cancels a connection attempt currently in progress.

Requires BLUETOOTH.BLUETOOTH permission.

Params:
  • device – Remote device
/** * Disconnects an established connection, or cancels a connection attempt * currently in progress. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param device Remote device */
public void cancelConnection(BluetoothDevice device) { if (DBG) Log.d(TAG, "cancelConnection() - device: " + device.getAddress()); if (mService == null || mServerIf == 0) return; try { mService.serverDisconnect(mServerIf, device.getAddress()); } catch (RemoteException e) { Log.e(TAG, "", e); } }
Set the preferred connection PHY for this app. Please note that this is just a recommendation, whether the PHY change will happen depends on other applications peferences, local and remote controller capabilities. Controller can override these settings.

BluetoothGattServerCallback.onPhyUpdate will be triggered as a result of this call, even if no PHY change happens. It is also triggered when remote device updates the PHY.

Params:
/** * Set the preferred connection PHY for this app. Please note that this is just a * recommendation, whether the PHY change will happen depends on other applications peferences, * local and remote controller capabilities. Controller can override these settings. <p> {@link * BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even if * no PHY change happens. It is also triggered when remote device updates the PHY. * * @param device The remote device to send this response to * @param txPhy preferred transmitter PHY. Bitwise OR of any of {@link * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link * BluetoothDevice#PHY_LE_CODED_MASK}. * @param rxPhy preferred receiver PHY. Bitwise OR of any of {@link * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link * BluetoothDevice#PHY_LE_CODED_MASK}. * @param phyOptions preferred coding to use when transmitting on the LE Coded PHY. Can be one * of {@link BluetoothDevice#PHY_OPTION_NO_PREFERRED}, {@link BluetoothDevice#PHY_OPTION_S2} or * {@link BluetoothDevice#PHY_OPTION_S8} */
public void setPreferredPhy(BluetoothDevice device, int txPhy, int rxPhy, int phyOptions) { try { mService.serverSetPreferredPhy(mServerIf, device.getAddress(), txPhy, rxPhy, phyOptions); } catch (RemoteException e) { Log.e(TAG, "", e); } }
Read the current transmitter PHY and receiver PHY of the connection. The values are returned in BluetoothGattServerCallback.onPhyRead
Params:
  • device – The remote device to send this response to
/** * Read the current transmitter PHY and receiver PHY of the connection. The values are returned * in {@link BluetoothGattServerCallback#onPhyRead} * * @param device The remote device to send this response to */
public void readPhy(BluetoothDevice device) { try { mService.serverReadPhy(mServerIf, device.getAddress()); } catch (RemoteException e) { Log.e(TAG, "", e); } }
Send a response to a read or write request to a remote device.

This function must be invoked in when a remote read/write request is received by one of these callback methods:

Requires BLUETOOTH.BLUETOOTH permission.

Params:
  • device – The remote device to send this response to
  • requestId – The ID of the request that was received with the callback
  • status – The status of the request to be sent to the remote devices
  • offset – Value offset for partial read/write response
  • value – The value of the attribute that was read/written (optional)
/** * Send a response to a read or write request to a remote device. * * <p>This function must be invoked in when a remote read/write request * is received by one of these callback methods: * * <ul> * <li>{@link BluetoothGattServerCallback#onCharacteristicReadRequest} * <li>{@link BluetoothGattServerCallback#onCharacteristicWriteRequest} * <li>{@link BluetoothGattServerCallback#onDescriptorReadRequest} * <li>{@link BluetoothGattServerCallback#onDescriptorWriteRequest} * </ul> * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param device The remote device to send this response to * @param requestId The ID of the request that was received with the callback * @param status The status of the request to be sent to the remote devices * @param offset Value offset for partial read/write response * @param value The value of the attribute that was read/written (optional) */
public boolean sendResponse(BluetoothDevice device, int requestId, int status, int offset, byte[] value) { if (VDBG) Log.d(TAG, "sendResponse() - device: " + device.getAddress()); if (mService == null || mServerIf == 0) return false; try { mService.sendResponse(mServerIf, device.getAddress(), requestId, status, offset, value); } catch (RemoteException e) { Log.e(TAG, "", e); return false; } return true; }
Send a notification or indication that a local characteristic has been updated.

A notification or indication is sent to the remote device to signal that the characteristic has been updated. This function should be invoked for every client that requests notifications/indications by writing to the "Client Configuration" descriptor for the given characteristic.

Requires BLUETOOTH.BLUETOOTH permission.

Params:
  • device – The remote device to receive the notification/indication
  • characteristic – The local characteristic that has been updated
  • confirm – true to request confirmation from the client (indication), false to send a notification
Throws:
Returns:true, if the notification has been triggered successfully
/** * Send a notification or indication that a local characteristic has been * updated. * * <p>A notification or indication is sent to the remote device to signal * that the characteristic has been updated. This function should be invoked * for every client that requests notifications/indications by writing * to the "Client Configuration" descriptor for the given characteristic. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param device The remote device to receive the notification/indication * @param characteristic The local characteristic that has been updated * @param confirm true to request confirmation from the client (indication), false to send a * notification * @return true, if the notification has been triggered successfully * @throws IllegalArgumentException */
public boolean notifyCharacteristicChanged(BluetoothDevice device, BluetoothGattCharacteristic characteristic, boolean confirm) { if (VDBG) Log.d(TAG, "notifyCharacteristicChanged() - device: " + device.getAddress()); if (mService == null || mServerIf == 0) return false; BluetoothGattService service = characteristic.getService(); if (service == null) return false; if (characteristic.getValue() == null) { throw new IllegalArgumentException("Chracteristic value is empty. Use " + "BluetoothGattCharacteristic#setvalue to update"); } try { mService.sendNotification(mServerIf, device.getAddress(), characteristic.getInstanceId(), confirm, characteristic.getValue()); } catch (RemoteException e) { Log.e(TAG, "", e); return false; } return true; }
Add a service to the list of services to be hosted.

Once a service has been addded to the list, the service and its included characteristics will be provided by the local device.

If the local device has already exposed services when this function is called, a service update notification will be sent to all clients.

The BluetoothGattServerCallback.onServiceAdded callback will indicate whether this service has been added successfully. Do not add another service before this callback.

Requires BLUETOOTH.BLUETOOTH permission.

Params:
  • service – Service to be added to the list of services provided by this device.
Returns:true, if the request to add service has been initiated
/** * Add a service to the list of services to be hosted. * * <p>Once a service has been addded to the list, the service and its * included characteristics will be provided by the local device. * * <p>If the local device has already exposed services when this function * is called, a service update notification will be sent to all clients. * * <p>The {@link BluetoothGattServerCallback#onServiceAdded} callback will indicate * whether this service has been added successfully. Do not add another service * before this callback. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param service Service to be added to the list of services provided by this device. * @return true, if the request to add service has been initiated */
public boolean addService(BluetoothGattService service) { if (DBG) Log.d(TAG, "addService() - service: " + service.getUuid()); if (mService == null || mServerIf == 0) return false; mPendingService = service; try { mService.addService(mServerIf, service); } catch (RemoteException e) { Log.e(TAG, "", e); return false; } return true; }
Removes a service from the list of services to be provided.

Requires BLUETOOTH.BLUETOOTH permission.

Params:
  • service – Service to be removed.
Returns:true, if the service has been removed
/** * Removes a service from the list of services to be provided. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param service Service to be removed. * @return true, if the service has been removed */
public boolean removeService(BluetoothGattService service) { if (DBG) Log.d(TAG, "removeService() - service: " + service.getUuid()); if (mService == null || mServerIf == 0) return false; BluetoothGattService intService = getService(service.getUuid(), service.getInstanceId(), service.getType()); if (intService == null) return false; try { mService.removeService(mServerIf, service.getInstanceId()); mServices.remove(intService); } catch (RemoteException e) { Log.e(TAG, "", e); return false; } return true; }
Remove all services from the list of provided services.

Requires BLUETOOTH.BLUETOOTH permission.

/** * Remove all services from the list of provided services. * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. */
public void clearServices() { if (DBG) Log.d(TAG, "clearServices()"); if (mService == null || mServerIf == 0) return; try { mService.clearServices(mServerIf); mServices.clear(); } catch (RemoteException e) { Log.e(TAG, "", e); } }
Returns a list of GATT services offered by this device.

An application must call addService to add a serice to the list of services offered by this device.

Requires BLUETOOTH.BLUETOOTH permission.

Returns:List of services. Returns an empty list if no services have been added yet.
/** * Returns a list of GATT services offered by this device. * * <p>An application must call {@link #addService} to add a serice to the * list of services offered by this device. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @return List of services. Returns an empty list if no services have been added yet. */
public List<BluetoothGattService> getServices() { return mServices; }
Returns a BluetoothGattService from the list of services offered by this device.

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

Requires BLUETOOTH.BLUETOOTH permission.

Params:
  • uuid – UUID of the requested service
Returns:BluetoothGattService if supported, or null if the requested service is not offered by this device.
/** * Returns a {@link BluetoothGattService} from the list of services offered * by this device. * * <p>If multiple instances of the same service (as identified by UUID) * exist, the first instance of the service is returned. * * <p>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 * this device. */
public BluetoothGattService getService(UUID uuid) { for (BluetoothGattService service : mServices) { if (service.getUuid().equals(uuid)) { return service; } } return null; }
Not supported - please use BluetoothManager.getConnectedDevices(int) with BluetoothProfile.GATT as argument
Throws:
/** * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} * with {@link BluetoothProfile#GATT} as argument * * @throws UnsupportedOperationException */
@Override public int getConnectionState(BluetoothDevice device) { throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead."); }
Not supported - please use BluetoothManager.getConnectedDevices(int) with BluetoothProfile.GATT as argument
Throws:
/** * Not supported - please use {@link BluetoothManager#getConnectedDevices(int)} * with {@link BluetoothProfile#GATT} as argument * * @throws UnsupportedOperationException */
@Override public List<BluetoothDevice> getConnectedDevices() { throw new UnsupportedOperationException( "Use BluetoothManager#getConnectedDevices instead."); }
Throws:
/** * Not supported - please use * {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])} * with {@link BluetoothProfile#GATT} as first argument * * @throws UnsupportedOperationException */
@Override public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { throw new UnsupportedOperationException( "Use BluetoothManager#getDevicesMatchingConnectionStates instead."); } }