Merge "Unhide Bluetooth Low Energy public APIs" into jb-mr2-dev
This commit is contained in:
184
api/current.txt
184
api/current.txt
@ -4613,8 +4613,13 @@ package android.bluetooth {
|
||||
method public boolean isEnabled();
|
||||
method public android.bluetooth.BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(java.lang.String, java.util.UUID) throws java.io.IOException;
|
||||
method public android.bluetooth.BluetoothServerSocket listenUsingRfcommWithServiceRecord(java.lang.String, java.util.UUID) throws java.io.IOException;
|
||||
method public boolean registerCallback(android.bluetooth.BluetoothAdapterCallback);
|
||||
method public boolean setName(java.lang.String);
|
||||
method public boolean startDiscovery();
|
||||
method public boolean startLeScan();
|
||||
method public boolean startLeScan(java.util.UUID[]);
|
||||
method public void stopLeScan();
|
||||
method public boolean unRegisterCallback(android.bluetooth.BluetoothAdapterCallback);
|
||||
field public static final java.lang.String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";
|
||||
field public static final java.lang.String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED";
|
||||
field public static final java.lang.String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";
|
||||
@ -4645,6 +4650,14 @@ package android.bluetooth {
|
||||
field public static final int STATE_TURNING_ON = 11; // 0xb
|
||||
}
|
||||
|
||||
public abstract class BluetoothAdapterCallback {
|
||||
ctor public BluetoothAdapterCallback();
|
||||
method public void onCallbackRegistration(int);
|
||||
method public void onLeScan(android.bluetooth.BluetoothDevice, int, byte[]);
|
||||
field public static final int CALLBACK_REGISTERED = 0; // 0x0
|
||||
field public static final int CALLBACK_REGISTRATION_FAILURE = 1; // 0x1
|
||||
}
|
||||
|
||||
public class BluetoothAssignedNumbers {
|
||||
field public static final int ACCEL_SEMICONDUCTOR = 74; // 0x4a
|
||||
field public static final int ALCATEL = 36; // 0x24
|
||||
@ -4837,6 +4850,7 @@ package android.bluetooth {
|
||||
}
|
||||
|
||||
public final class BluetoothDevice implements android.os.Parcelable {
|
||||
method public android.bluetooth.BluetoothGatt connectGattServer(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
|
||||
method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
|
||||
method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
|
||||
method public int describeContents();
|
||||
@ -4869,6 +4883,159 @@ package android.bluetooth {
|
||||
field public static final java.lang.String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
|
||||
}
|
||||
|
||||
public final class BluetoothGatt implements android.bluetooth.BluetoothProfile {
|
||||
method public void abortReliableWrite(android.bluetooth.BluetoothDevice);
|
||||
method public boolean beginReliableWrite();
|
||||
method public void disconnect();
|
||||
method public boolean discoverServices();
|
||||
method public boolean executeReliableWrite();
|
||||
method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
|
||||
method public int getConnectionState(android.bluetooth.BluetoothDevice);
|
||||
method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
|
||||
method public android.bluetooth.BluetoothGattService getService(java.util.UUID);
|
||||
method public java.util.List<android.bluetooth.BluetoothGattService> getServices();
|
||||
method public boolean readCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
|
||||
method public boolean readDescriptor(android.bluetooth.BluetoothGattDescriptor);
|
||||
method public boolean readRemoteRssi();
|
||||
method public boolean setCharacteristicNotification(android.bluetooth.BluetoothGattCharacteristic, boolean);
|
||||
method public boolean writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
|
||||
method public boolean writeDescriptor(android.bluetooth.BluetoothGattDescriptor);
|
||||
field public static final int GATT_FAILURE = 0; // 0x0
|
||||
field public static final int GATT_INSUFFICIENT_AUTHENTICATION = 5; // 0x5
|
||||
field public static final int GATT_INSUFFICIENT_ENCRYPTION = 15; // 0xf
|
||||
field public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 13; // 0xd
|
||||
field public static final int GATT_INVALID_OFFSET = 7; // 0x7
|
||||
field public static final int GATT_READ_NOT_PERMITTED = 2; // 0x2
|
||||
field public static final int GATT_REQUEST_NOT_SUPPORTED = 6; // 0x6
|
||||
field public static final int GATT_SUCCESS = 0; // 0x0
|
||||
field public static final int GATT_WRITE_NOT_PERMITTED = 3; // 0x3
|
||||
}
|
||||
|
||||
public abstract class BluetoothGattCallback {
|
||||
ctor public BluetoothGattCallback();
|
||||
method public void onCharacteristicChanged(android.bluetooth.BluetoothGattCharacteristic);
|
||||
method public void onCharacteristicRead(android.bluetooth.BluetoothGattCharacteristic, int);
|
||||
method public void onCharacteristicWrite(android.bluetooth.BluetoothGattCharacteristic, int);
|
||||
method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int);
|
||||
method public void onDescriptorRead(android.bluetooth.BluetoothGattDescriptor, int);
|
||||
method public void onDescriptorWrite(android.bluetooth.BluetoothGattDescriptor, int);
|
||||
method public void onReadRemoteRssi(android.bluetooth.BluetoothDevice, int, int);
|
||||
method public void onReliableWriteCompleted(android.bluetooth.BluetoothDevice, int);
|
||||
method public void onServicesDiscovered(android.bluetooth.BluetoothDevice, int);
|
||||
}
|
||||
|
||||
public class BluetoothGattCharacteristic {
|
||||
ctor public BluetoothGattCharacteristic(java.util.UUID, int, int);
|
||||
method public boolean addDescriptor(android.bluetooth.BluetoothGattDescriptor);
|
||||
method public android.bluetooth.BluetoothGattDescriptor getDescriptor(java.util.UUID);
|
||||
method public java.util.List<android.bluetooth.BluetoothGattDescriptor> getDescriptors();
|
||||
method public java.lang.Float getFloatValue(int, int);
|
||||
method public int getInstanceId();
|
||||
method public java.lang.Integer getIntValue(int, int);
|
||||
method public int getPermissions();
|
||||
method public int getProperties();
|
||||
method public android.bluetooth.BluetoothGattService getService();
|
||||
method public java.lang.String getStringValue(int);
|
||||
method public java.util.UUID getUuid();
|
||||
method public byte[] getValue();
|
||||
method public int getWriteType();
|
||||
method public boolean setValue(byte[]);
|
||||
method public boolean setValue(int, int, int);
|
||||
method public boolean setValue(int, int, int, int);
|
||||
method public boolean setValue(java.lang.String);
|
||||
method public void setWriteType(int);
|
||||
field public static final int FORMAT_FLOAT = 52; // 0x34
|
||||
field public static final int FORMAT_SFLOAT = 50; // 0x32
|
||||
field public static final int FORMAT_SINT16 = 34; // 0x22
|
||||
field public static final int FORMAT_SINT32 = 36; // 0x24
|
||||
field public static final int FORMAT_SINT8 = 33; // 0x21
|
||||
field public static final int FORMAT_UINT16 = 18; // 0x12
|
||||
field public static final int FORMAT_UINT32 = 20; // 0x14
|
||||
field public static final int FORMAT_UINT8 = 17; // 0x11
|
||||
field public static final int PERMISSION_READ = 1; // 0x1
|
||||
field public static final int PERMISSION_READ_ENCRYPTED = 2; // 0x2
|
||||
field public static final int PERMISSION_READ_ENCRYPTED_MITM = 4; // 0x4
|
||||
field public static final int PERMISSION_WRITE = 16; // 0x10
|
||||
field public static final int PERMISSION_WRITE_ENCRYPTED = 32; // 0x20
|
||||
field public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 64; // 0x40
|
||||
field public static final int PERMISSION_WRITE_SIGNED = 128; // 0x80
|
||||
field public static final int PERMISSION_WRITE_SIGNED_MITM = 256; // 0x100
|
||||
field public static final int PROPERTY_BROADCAST = 1; // 0x1
|
||||
field public static final int PROPERTY_EXTENDED_PROPS = 128; // 0x80
|
||||
field public static final int PROPERTY_INDICATE = 32; // 0x20
|
||||
field public static final int PROPERTY_NOTIFY = 16; // 0x10
|
||||
field public static final int PROPERTY_READ = 2; // 0x2
|
||||
field public static final int PROPERTY_SIGNED_WRITE = 64; // 0x40
|
||||
field public static final int PROPERTY_WRITE = 8; // 0x8
|
||||
field public static final int PROPERTY_WRITE_NO_RESPONSE = 4; // 0x4
|
||||
field public static final int WRITE_TYPE_DEFAULT = 2; // 0x2
|
||||
field public static final int WRITE_TYPE_NO_RESPONSE = 1; // 0x1
|
||||
field public static final int WRITE_TYPE_SIGNED = 4; // 0x4
|
||||
field protected java.util.List mDescriptors;
|
||||
}
|
||||
|
||||
public class BluetoothGattDescriptor {
|
||||
ctor public BluetoothGattDescriptor(java.util.UUID, int);
|
||||
method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic();
|
||||
method public int getPermissions();
|
||||
method public java.util.UUID getUuid();
|
||||
method public byte[] getValue();
|
||||
method public boolean setValue(byte[]);
|
||||
field public static final byte[] DISABLE_NOTIFICATION_VALUE;
|
||||
field public static final byte[] ENABLE_INDICATION_VALUE;
|
||||
field public static final byte[] ENABLE_NOTIFICATION_VALUE;
|
||||
field public static final int PERMISSION_READ = 1; // 0x1
|
||||
field public static final int PERMISSION_READ_ENCRYPTED = 2; // 0x2
|
||||
field public static final int PERMISSION_READ_ENCRYPTED_MITM = 4; // 0x4
|
||||
field public static final int PERMISSION_WRITE = 16; // 0x10
|
||||
field public static final int PERMISSION_WRITE_ENCRYPTED = 32; // 0x20
|
||||
field public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 64; // 0x40
|
||||
field public static final int PERMISSION_WRITE_SIGNED = 128; // 0x80
|
||||
field public static final int PERMISSION_WRITE_SIGNED_MITM = 256; // 0x100
|
||||
}
|
||||
|
||||
public final class BluetoothGattServer implements android.bluetooth.BluetoothProfile {
|
||||
method public boolean addService(android.bluetooth.BluetoothGattService);
|
||||
method public void cancelConnection(android.bluetooth.BluetoothDevice);
|
||||
method public void clearServices();
|
||||
method public boolean connect(android.bluetooth.BluetoothDevice, boolean);
|
||||
method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
|
||||
method public int getConnectionState(android.bluetooth.BluetoothDevice);
|
||||
method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
|
||||
method public android.bluetooth.BluetoothGattService getService(java.util.UUID);
|
||||
method public java.util.List<android.bluetooth.BluetoothGattService> getServices();
|
||||
method public boolean notifyCharacteristicChanged(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothGattCharacteristic, boolean);
|
||||
method public boolean removeService(android.bluetooth.BluetoothGattService);
|
||||
method public boolean sendResponse(android.bluetooth.BluetoothDevice, int, int, int, byte[]);
|
||||
}
|
||||
|
||||
public abstract class BluetoothGattServerCallback {
|
||||
ctor public BluetoothGattServerCallback();
|
||||
method public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattCharacteristic);
|
||||
method public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattCharacteristic, boolean, boolean, int, byte[]);
|
||||
method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int);
|
||||
method public void onDescriptorReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattDescriptor);
|
||||
method public void onDescriptorWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattDescriptor, boolean, boolean, int, byte[]);
|
||||
method public void onExecuteWrite(android.bluetooth.BluetoothDevice, int, boolean);
|
||||
method public void onServiceAdded(int, android.bluetooth.BluetoothGattService);
|
||||
}
|
||||
|
||||
public class BluetoothGattService {
|
||||
ctor public BluetoothGattService(java.util.UUID, int);
|
||||
method public boolean addCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
|
||||
method public boolean addService(android.bluetooth.BluetoothGattService);
|
||||
method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic(java.util.UUID);
|
||||
method public java.util.List<android.bluetooth.BluetoothGattCharacteristic> getCharacteristics();
|
||||
method public java.util.List<android.bluetooth.BluetoothGattService> getIncludedServices();
|
||||
method public int getInstanceId();
|
||||
method public int getType();
|
||||
method public java.util.UUID getUuid();
|
||||
field public static final int SERVICE_TYPE_PRIMARY = 0; // 0x0
|
||||
field public static final int SERVICE_TYPE_SECONDARY = 1; // 0x1
|
||||
field protected java.util.List mCharacteristics;
|
||||
field protected java.util.List mIncludedServices;
|
||||
}
|
||||
|
||||
public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
|
||||
method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
|
||||
method public int getConnectionState(android.bluetooth.BluetoothDevice);
|
||||
@ -4931,6 +5098,14 @@ package android.bluetooth {
|
||||
method public void onHealthChannelStateChange(android.bluetooth.BluetoothHealthAppConfiguration, android.bluetooth.BluetoothDevice, int, int, android.os.ParcelFileDescriptor, int);
|
||||
}
|
||||
|
||||
public final class BluetoothManager {
|
||||
method public android.bluetooth.BluetoothAdapter getAdapter();
|
||||
method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(int);
|
||||
method public int getConnectionState(android.bluetooth.BluetoothDevice, int);
|
||||
method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int, int[]);
|
||||
method public android.bluetooth.BluetoothGattServer openGattServer(android.content.Context, android.bluetooth.BluetoothGattServerCallback);
|
||||
}
|
||||
|
||||
public abstract interface BluetoothProfile {
|
||||
method public abstract java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
|
||||
method public abstract int getConnectionState(android.bluetooth.BluetoothDevice);
|
||||
@ -4938,6 +5113,8 @@ package android.bluetooth {
|
||||
field public static final int A2DP = 2; // 0x2
|
||||
field public static final java.lang.String EXTRA_PREVIOUS_STATE = "android.bluetooth.profile.extra.PREVIOUS_STATE";
|
||||
field public static final java.lang.String EXTRA_STATE = "android.bluetooth.profile.extra.STATE";
|
||||
field public static final int GATT = 7; // 0x7
|
||||
field public static final int GATT_SERVER = 8; // 0x8
|
||||
field public static final int HEADSET = 1; // 0x1
|
||||
field public static final int HEALTH = 3; // 0x3
|
||||
field public static final int STATE_CONNECTED = 2; // 0x2
|
||||
@ -5495,6 +5672,7 @@ package android.content {
|
||||
field public static final int BIND_IMPORTANT = 64; // 0x40
|
||||
field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
|
||||
field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
|
||||
field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
|
||||
field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
|
||||
field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
|
||||
field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
|
||||
@ -6658,6 +6836,7 @@ package android.content.pm {
|
||||
method public abstract boolean addPermission(android.content.pm.PermissionInfo);
|
||||
method public abstract boolean addPermissionAsync(android.content.pm.PermissionInfo);
|
||||
method public abstract deprecated void addPreferredActivity(android.content.IntentFilter, int, android.content.ComponentName[], android.content.ComponentName);
|
||||
method public android.content.Intent buildPermissionRequestIntent(java.lang.String...);
|
||||
method public abstract java.lang.String[] canonicalToCurrentPackageNames(java.lang.String[]);
|
||||
method public abstract int checkPermission(java.lang.String, java.lang.String);
|
||||
method public abstract int checkSignatures(java.lang.String, java.lang.String);
|
||||
@ -6717,7 +6896,6 @@ package android.content.pm {
|
||||
method public abstract java.util.List<android.content.pm.PermissionInfo> queryPermissionsByGroup(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
|
||||
method public abstract deprecated void removePackageFromPreferred(java.lang.String);
|
||||
method public abstract void removePermission(java.lang.String);
|
||||
method public android.content.Intent buildPermissionRequestIntent(java.lang.String...);
|
||||
method public abstract android.content.pm.ResolveInfo resolveActivity(android.content.Intent, int);
|
||||
method public abstract android.content.pm.ProviderInfo resolveContentProvider(java.lang.String, int);
|
||||
method public abstract android.content.pm.ResolveInfo resolveService(android.content.Intent, int);
|
||||
@ -16810,13 +16988,13 @@ package android.os {
|
||||
method public void setUserRestriction(java.lang.String, boolean);
|
||||
method public void setUserRestrictions(android.os.Bundle);
|
||||
method public void setUserRestrictions(android.os.Bundle, android.os.UserHandle);
|
||||
field public static final java.lang.String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_WIFI = "no_config_wifi";
|
||||
field public static final java.lang.String DISALLOW_INSTALL_APPS = "no_install_apps";
|
||||
field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
|
||||
field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
|
||||
field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location";
|
||||
field public static final java.lang.String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps";
|
||||
field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
|
||||
field public static final java.lang.String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
|
||||
field public static final java.lang.String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer";
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ package android.app;
|
||||
import com.android.internal.policy.PolicyManager;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
@ -319,7 +319,7 @@ class ContextImpl extends Context {
|
||||
|
||||
registerService(BLUETOOTH_SERVICE, new ServiceFetcher() {
|
||||
public Object createService(ContextImpl ctx) {
|
||||
return BluetoothAdapter.getDefaultAdapter();
|
||||
return new BluetoothManager(ctx);
|
||||
}});
|
||||
|
||||
registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
|
||||
|
@ -22,7 +22,6 @@ import android.content.Context;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.ParcelUuid;
|
||||
import android.os.RemoteException;
|
||||
@ -359,6 +358,8 @@ public final class BluetoothAdapter {
|
||||
private IBluetooth mService;
|
||||
|
||||
private Handler mServiceRecordHandler;
|
||||
private BluetoothAdapterCallback mCallback;
|
||||
private int mClientIf;
|
||||
|
||||
/**
|
||||
* Get a handle to the default local Bluetooth adapter.
|
||||
@ -1137,7 +1138,8 @@ public final class BluetoothAdapter {
|
||||
* Get the profile proxy object associated with the profile.
|
||||
*
|
||||
* <p>Profile can be one of {@link BluetoothProfile#HEALTH}, {@link BluetoothProfile#HEADSET},
|
||||
* or {@link BluetoothProfile#A2DP}. Clients must implement
|
||||
* {@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.
|
||||
*
|
||||
@ -1166,12 +1168,6 @@ public final class BluetoothAdapter {
|
||||
} else if (profile == BluetoothProfile.HEALTH) {
|
||||
BluetoothHealth health = new BluetoothHealth(context, listener);
|
||||
return true;
|
||||
} else if (profile == BluetoothProfile.GATT) {
|
||||
BluetoothGatt gatt = new BluetoothGatt(context, listener);
|
||||
return true;
|
||||
} else if (profile == BluetoothProfile.GATT_SERVER) {
|
||||
BluetoothGattServer gattServer = new BluetoothGattServer(context, listener);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -1411,4 +1407,230 @@ public final class BluetoothAdapter {
|
||||
mProxyServiceStateCallbacks.remove(cb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an callback to receive async results, such as LE scan result.
|
||||
*
|
||||
* <p>This is an asynchronous call. The callback
|
||||
* {@link BluetoothAdapterCallback#onCallbackRegistration}
|
||||
* is used to notify success or failure if the function returns true.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param callback BluetootAdapter callback handler that will receive asynchronous callbacks.
|
||||
* @return If true, the callback will be called to notify success or failure,
|
||||
* false on immediate error
|
||||
*/
|
||||
public boolean registerCallback(BluetoothAdapterCallback callback) {
|
||||
try {
|
||||
IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
|
||||
mCallback = callback;
|
||||
UUID uuid = UUID.randomUUID();
|
||||
if (DBG) Log.d(TAG, "registerCallback() - UUID=" + uuid);
|
||||
|
||||
iGatt.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the registered callback.
|
||||
*/
|
||||
public boolean unRegisterCallback(BluetoothAdapterCallback callback) {
|
||||
if (callback != mCallback) return false;
|
||||
try {
|
||||
IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
|
||||
|
||||
iGatt.unregisterClient(mClientIf);
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a scan for Bluetooth LE devices.
|
||||
*
|
||||
* <p>Results of the scan are reported using the
|
||||
* {@link BluetoothAdapterCallback#onLeScan} callback.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return true, if the scan was started successfully
|
||||
*/
|
||||
public boolean startLeScan() {
|
||||
if (DBG) Log.d(TAG, "startLeScan()");
|
||||
if (mClientIf == 0) return false;
|
||||
|
||||
try {
|
||||
IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
|
||||
iGatt.startScan(mClientIf, false);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a scan for Bluetooth LE devices, looking for devices that
|
||||
* advertise given services.
|
||||
*
|
||||
* <p>Devices which advertise all specified services are reported using the
|
||||
* {@link BluetoothAdapterCallback#onLeScan} callback.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param serviceUuids Array of services to look for
|
||||
* @return true, if the scan was started successfully
|
||||
*/
|
||||
public boolean startLeScan(UUID[] serviceUuids) {
|
||||
if (DBG) Log.d(TAG, "startLeScan() - with UUIDs");
|
||||
if (mClientIf == 0) return false;
|
||||
|
||||
try {
|
||||
IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
|
||||
ParcelUuid[] uuids = new ParcelUuid[serviceUuids.length];
|
||||
for(int i = 0; i != uuids.length; ++i) {
|
||||
uuids[i] = new ParcelUuid(serviceUuids[i]);
|
||||
}
|
||||
iGatt.startScanWithUuids(mClientIf, false, uuids);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops an ongoing Bluetooth LE device scan.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*/
|
||||
public void stopLeScan() {
|
||||
if (DBG) Log.d(TAG, "stopScan()");
|
||||
if (mClientIf == 0) return;
|
||||
|
||||
try {
|
||||
IBluetoothGatt iGatt = (IBluetoothGatt) mManagerService.getBluetoothGatt();
|
||||
iGatt.stopScan(mClientIf, false);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bluetooth GATT interface callbacks
|
||||
*/
|
||||
private final IBluetoothGattCallback mBluetoothGattCallback =
|
||||
new IBluetoothGattCallback.Stub() {
|
||||
/**
|
||||
* Application interface registered - app is ready to go
|
||||
*/
|
||||
public void onClientRegistered(int status, int clientIf) {
|
||||
if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status
|
||||
+ " clientIf=" + clientIf);
|
||||
mClientIf = clientIf;
|
||||
mCallback.onCallbackRegistration(status == BluetoothGatt.GATT_SUCCESS ?
|
||||
BluetoothAdapterCallback.CALLBACK_REGISTERED :
|
||||
BluetoothAdapterCallback.CALLBACK_REGISTRATION_FAILURE);
|
||||
}
|
||||
|
||||
public void onClientConnectionState(int status, int clientIf,
|
||||
boolean connected, String address) {
|
||||
// no op
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback reporting an LE scan result.
|
||||
* @hide
|
||||
*/
|
||||
public void onScanResult(String address, int rssi, byte[] advData) {
|
||||
if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
|
||||
|
||||
try {
|
||||
mCallback.onLeScan(getRemoteDevice(address), rssi, advData);
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Unhandled exception: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void onGetService(String address, int srvcType,
|
||||
int srvcInstId, ParcelUuid srvcUuid) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onGetIncludedService(String address, int srvcType,
|
||||
int srvcInstId, ParcelUuid srvcUuid,
|
||||
int inclSrvcType, int inclSrvcInstId,
|
||||
ParcelUuid inclSrvcUuid) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onGetCharacteristic(String address, int srvcType,
|
||||
int srvcInstId, ParcelUuid srvcUuid,
|
||||
int charInstId, ParcelUuid charUuid,
|
||||
int charProps) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onGetDescriptor(String address, int srvcType,
|
||||
int srvcInstId, ParcelUuid srvcUuid,
|
||||
int charInstId, ParcelUuid charUuid,
|
||||
ParcelUuid descUuid) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onSearchComplete(String address, int status) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onCharacteristicRead(String address, int status, int srvcType,
|
||||
int srvcInstId, ParcelUuid srvcUuid,
|
||||
int charInstId, ParcelUuid charUuid, byte[] value) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onCharacteristicWrite(String address, int status, int srvcType,
|
||||
int srvcInstId, ParcelUuid srvcUuid,
|
||||
int charInstId, ParcelUuid charUuid) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onNotify(String address, int srvcType,
|
||||
int srvcInstId, ParcelUuid srvcUuid,
|
||||
int charInstId, ParcelUuid charUuid,
|
||||
byte[] value) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onDescriptorRead(String address, int status, int srvcType,
|
||||
int srvcInstId, ParcelUuid srvcUuid,
|
||||
int charInstId, ParcelUuid charUuid,
|
||||
ParcelUuid descrUuid, byte[] value) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onDescriptorWrite(String address, int status, int srvcType,
|
||||
int srvcInstId, ParcelUuid srvcUuid,
|
||||
int charInstId, ParcelUuid charUuid,
|
||||
ParcelUuid descrUuid) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onExecuteWrite(String address, int status) {
|
||||
// no op
|
||||
}
|
||||
|
||||
public void onReadRemoteRssi(String address, int rssi, int status) {
|
||||
// no op
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
57
core/java/android/bluetooth/BluetoothAdapterCallback.java
Normal file
57
core/java/android/bluetooth/BluetoothAdapterCallback.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.bluetooth.BluetoothDevice;
|
||||
|
||||
/**
|
||||
* This abstract class is used to implement {@link BluetoothAdapter} callbacks.
|
||||
*/
|
||||
public abstract class BluetoothAdapterCallback {
|
||||
|
||||
/**
|
||||
* Indicates the callback has been registered successfully
|
||||
*/
|
||||
public static final int CALLBACK_REGISTERED = 0;
|
||||
|
||||
/**
|
||||
* Indicates the callback registration has failed
|
||||
*/
|
||||
public static final int CALLBACK_REGISTRATION_FAILURE = 1;
|
||||
|
||||
/**
|
||||
* Callback to inform change in registration state of the application.
|
||||
*
|
||||
* @param status Returns {@link #CALLBACK_REGISTERED} if the application
|
||||
* was successfully registered.
|
||||
*/
|
||||
public void onCallbackRegistration(int status) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback reporting an LE device found during a device scan initiated
|
||||
* by the {@link BluetoothAdapter#startLeScan} function.
|
||||
*
|
||||
* @param device Identifies the remote device
|
||||
* @param rssi The RSSI value for the remote device as reported by the
|
||||
* Bluetooth hardware. 0 if no RSSI value is available.
|
||||
* @param scanRecord The content of the advertisement record offered by
|
||||
* the remote device.
|
||||
*/
|
||||
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ package android.bluetooth;
|
||||
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
@ -1126,4 +1127,30 @@ public final class BluetoothDevice implements Parcelable {
|
||||
return pinBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to GATT Server hosted by this device. Caller acts as GATT client.
|
||||
* The callback is used to deliver results to Caller, such as connection status as well
|
||||
* as any further GATT client operations.
|
||||
* The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
|
||||
* GATT client operations.
|
||||
* @param callback GATT callback handler that will receive asynchronous callbacks.
|
||||
* @param autoConnect Whether to directly connect to the remote device (false)
|
||||
* or to automatically connect as soon as the remote
|
||||
* device becomes available (true).
|
||||
* @throws IllegalArgumentException if callback is null
|
||||
*/
|
||||
public BluetoothGatt connectGattServer(Context context, boolean autoConnect,
|
||||
BluetoothGattCallback callback) {
|
||||
// TODO(Bluetooth) check whether platform support BLE
|
||||
// Do the check here or in GattServer?
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
IBluetoothManager managerService = adapter.getBluetoothManager();
|
||||
try {
|
||||
IBluetoothGatt iGatt = managerService.getBluetoothGatt();
|
||||
BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this);
|
||||
gatt.connect(autoConnect, callback);
|
||||
return gatt;
|
||||
} catch (RemoteException e) {Log.e(TAG, "", e);}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
package android.bluetooth;
|
||||
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.bluetooth.BluetoothProfile.ServiceListener;
|
||||
@ -39,42 +37,48 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Public API for the Bluetooth Gatt Profile.
|
||||
* Public API for the Bluetooth GATT Profile.
|
||||
*
|
||||
* <p>This class provides Bluetooth Gatt functionality to enable communication
|
||||
* <p>This class provides Bluetooth GATT functionality to enable communication
|
||||
* with Bluetooth Smart or Smart Ready devices.
|
||||
*
|
||||
* <p>BluetoothGatt is a proxy object for controlling the Bluetooth Service
|
||||
* via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get the
|
||||
* BluetoothGatt proxy object.
|
||||
*
|
||||
* <p>To connect to a remote peripheral device, create a {@link BluetoothGattCallback}
|
||||
* and call {@link #registerApp} to register your application. Gatt capable
|
||||
* devices can be discovered using the {@link #startScan} function or the
|
||||
* regular Bluetooth device discovery process.
|
||||
* @hide
|
||||
* and call {@link BluetoothDevice#connectGattServer} to get a instance of this class.
|
||||
* GATT capable devices can be discovered using the Bluetooth device discovery or BLE
|
||||
* scan process.
|
||||
*/
|
||||
public final class BluetoothGatt implements BluetoothProfile {
|
||||
private static final String TAG = "BluetoothGatt";
|
||||
private static final boolean DBG = true;
|
||||
private static final boolean VDBG = true;
|
||||
|
||||
private Context mContext;
|
||||
private ServiceListener mServiceListener;
|
||||
private BluetoothAdapter mAdapter;
|
||||
private final Context mContext;
|
||||
private IBluetoothGatt mService;
|
||||
private BluetoothGattCallback mCallback;
|
||||
private int mClientIf;
|
||||
private boolean mAuthRetry = false;
|
||||
private BluetoothDevice mDevice;
|
||||
private boolean mAutoConnect;
|
||||
private int mConnState;
|
||||
private final Object mStateLock = new Object();
|
||||
|
||||
private static final int CONN_STATE_IDLE = 0;
|
||||
private static final int CONN_STATE_CONNECTING = 1;
|
||||
private static final int CONN_STATE_CONNECTED = 2;
|
||||
private static final int CONN_STATE_DISCONNECTING = 3;
|
||||
|
||||
private List<BluetoothGattService> mServices;
|
||||
|
||||
/** A Gatt operation completed successfully */
|
||||
/** A GATT operation failed */
|
||||
public static final int GATT_FAILURE = 0;
|
||||
|
||||
/** A GATT operation completed successfully */
|
||||
public static final int GATT_SUCCESS = 0;
|
||||
|
||||
/** Gatt read operation is not permitted */
|
||||
/** GATT read operation is not permitted */
|
||||
public static final int GATT_READ_NOT_PERMITTED = 0x2;
|
||||
|
||||
/** Gatt write operation is not permitted */
|
||||
/** GATT write operation is not permitted */
|
||||
public static final int GATT_WRITE_NOT_PERMITTED = 0x3;
|
||||
|
||||
/** Insufficient authentication for a given operation */
|
||||
@ -110,55 +114,6 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*/
|
||||
/*package*/ static final int AUTHENTICATION_MITM = 2;
|
||||
|
||||
/**
|
||||
* Bluetooth state change handlers
|
||||
*/
|
||||
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
|
||||
new IBluetoothStateChangeCallback.Stub() {
|
||||
public void onBluetoothStateChange(boolean up) {
|
||||
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
|
||||
if (!up) {
|
||||
if (DBG) Log.d(TAG,"Unbinding service...");
|
||||
synchronized (mConnection) {
|
||||
mService = null;
|
||||
mContext.unbindService(mConnection);
|
||||
}
|
||||
} else {
|
||||
synchronized (mConnection) {
|
||||
if (mService == null) {
|
||||
if (DBG) Log.d(TAG,"Binding service...");
|
||||
if (!mContext.bindService(new Intent(IBluetoothGatt.class.getName()),
|
||||
mConnection, 0)) {
|
||||
Log.e(TAG, "Could not bind to Bluetooth GATT Service");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Service binder handling
|
||||
*/
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
if (DBG) Log.d(TAG, "Proxy object connected");
|
||||
mService = IBluetoothGatt.Stub.asInterface(service);
|
||||
ServiceListener serviceListener = mServiceListener;
|
||||
if (serviceListener != null) {
|
||||
serviceListener.onServiceConnected(BluetoothProfile.GATT, BluetoothGatt.this);
|
||||
}
|
||||
}
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
if (DBG) Log.d(TAG, "Proxy object disconnected");
|
||||
mService = null;
|
||||
ServiceListener serviceListener = mServiceListener;
|
||||
if (serviceListener != null) {
|
||||
serviceListener.onServiceDisconnected(BluetoothProfile.GATT);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bluetooth GATT interface callbacks
|
||||
*/
|
||||
@ -171,11 +126,27 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
public void onClientRegistered(int status, int clientIf) {
|
||||
if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status
|
||||
+ " clientIf=" + clientIf);
|
||||
if (VDBG) {
|
||||
synchronized(mStateLock) {
|
||||
if (mConnState != CONN_STATE_CONNECTING) {
|
||||
Log.e(TAG, "Bad connection state: " + mConnState);
|
||||
}
|
||||
}
|
||||
}
|
||||
mClientIf = clientIf;
|
||||
if (status != GATT_SUCCESS) {
|
||||
mCallback.onConnectionStateChange(mDevice, GATT_FAILURE,
|
||||
BluetoothProfile.STATE_DISCONNECTED);
|
||||
synchronized(mStateLock) {
|
||||
mConnState = CONN_STATE_IDLE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mCallback.onAppRegistered(status);
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Unhandled exception: " + ex);
|
||||
mService.clientConnect(mClientIf, mDevice.getAddress(),
|
||||
!mAutoConnect); // autoConnect is inverse of "isDirect"
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,13 +158,24 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
boolean connected, String address) {
|
||||
if (DBG) Log.d(TAG, "onClientConnectionState() - status=" + status
|
||||
+ " clientIf=" + clientIf + " device=" + address);
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
|
||||
BluetoothProfile.STATE_DISCONNECTED;
|
||||
try {
|
||||
mCallback.onConnectionStateChange(mAdapter.getRemoteDevice(address), status,
|
||||
connected ? BluetoothProfile.STATE_CONNECTED
|
||||
: BluetoothProfile.STATE_DISCONNECTED);
|
||||
mCallback.onConnectionStateChange(mDevice, status, profileState);
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Unhandled exception: " + ex);
|
||||
}
|
||||
|
||||
synchronized(mStateLock) {
|
||||
if (connected) {
|
||||
mConnState = CONN_STATE_CONNECTED;
|
||||
} else {
|
||||
mConnState = CONN_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -201,13 +183,7 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
* @hide
|
||||
*/
|
||||
public void onScanResult(String address, int rssi, byte[] advData) {
|
||||
if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
|
||||
|
||||
try {
|
||||
mCallback.onScanResult(mAdapter.getRemoteDevice(address), rssi, advData);
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Unhandled exception: " + ex);
|
||||
}
|
||||
// no op
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,8 +195,10 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
public void onGetService(String address, int srvcType,
|
||||
int srvcInstId, ParcelUuid srvcUuid) {
|
||||
if (DBG) Log.d(TAG, "onGetService() - Device=" + address + " UUID=" + srvcUuid);
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
mServices.add(new BluetoothGattService(device, srvcUuid.getUuid(),
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
mServices.add(new BluetoothGattService(mDevice, srvcUuid.getUuid(),
|
||||
srvcInstId, srvcType));
|
||||
}
|
||||
|
||||
@ -236,10 +214,12 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
if (DBG) Log.d(TAG, "onGetIncludedService() - Device=" + address
|
||||
+ " UUID=" + srvcUuid + " Included=" + inclSrvcUuid);
|
||||
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
BluetoothGattService service = getService(device,
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
BluetoothGattService service = getService(mDevice,
|
||||
srvcUuid.getUuid(), srvcInstId, srvcType);
|
||||
BluetoothGattService includedService = getService(device,
|
||||
BluetoothGattService includedService = getService(mDevice,
|
||||
inclSrvcUuid.getUuid(), inclSrvcInstId, inclSrvcType);
|
||||
|
||||
if (service != null && includedService != null) {
|
||||
@ -260,8 +240,10 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
if (DBG) Log.d(TAG, "onGetCharacteristic() - Device=" + address + " UUID=" +
|
||||
charUuid);
|
||||
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
BluetoothGattService service = getService(device, srvcUuid.getUuid(),
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
|
||||
srvcInstId, srvcType);
|
||||
if (service != null) {
|
||||
service.addCharacteristic(new BluetoothGattCharacteristic(
|
||||
@ -281,8 +263,10 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
ParcelUuid descUuid) {
|
||||
if (DBG) Log.d(TAG, "onGetDescriptor() - Device=" + address + " UUID=" + descUuid);
|
||||
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
BluetoothGattService service = getService(device, srvcUuid.getUuid(),
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
|
||||
srvcInstId, srvcType);
|
||||
if (service == null) return;
|
||||
|
||||
@ -303,9 +287,11 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*/
|
||||
public void onSearchComplete(String address, int status) {
|
||||
if (DBG) Log.d(TAG, "onSearchComplete() = Device=" + address + " Status=" + status);
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mCallback.onServicesDiscovered(device, status);
|
||||
mCallback.onServicesDiscovered(mDevice, status);
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Unhandled exception: " + ex);
|
||||
}
|
||||
@ -322,6 +308,9 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
if (DBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address
|
||||
+ " UUID=" + charUuid + " Status=" + status);
|
||||
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
if ((status == GATT_INSUFFICIENT_AUTHENTICATION
|
||||
|| status == GATT_INSUFFICIENT_ENCRYPTION)
|
||||
&& mAuthRetry == false) {
|
||||
@ -338,8 +327,7 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
|
||||
mAuthRetry = false;
|
||||
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
BluetoothGattService service = getService(device, srvcUuid.getUuid(),
|
||||
BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
|
||||
srvcInstId, srvcType);
|
||||
if (service == null) return;
|
||||
|
||||
@ -367,8 +355,10 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
if (DBG) Log.d(TAG, "onCharacteristicWrite() - Device=" + address
|
||||
+ " UUID=" + charUuid + " Status=" + status);
|
||||
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
BluetoothGattService service = getService(device, srvcUuid.getUuid(),
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
|
||||
srvcInstId, srvcType);
|
||||
if (service == null) return;
|
||||
|
||||
@ -411,8 +401,10 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
byte[] value) {
|
||||
if (DBG) Log.d(TAG, "onNotify() - Device=" + address + " UUID=" + charUuid);
|
||||
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
BluetoothGattService service = getService(device, srvcUuid.getUuid(),
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
|
||||
srvcInstId, srvcType);
|
||||
if (service == null) return;
|
||||
|
||||
@ -439,8 +431,10 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
ParcelUuid descrUuid, byte[] value) {
|
||||
if (DBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " UUID=" + charUuid);
|
||||
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
BluetoothGattService service = getService(device, srvcUuid.getUuid(),
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
|
||||
srvcInstId, srvcType);
|
||||
if (service == null) return;
|
||||
|
||||
@ -486,8 +480,10 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
ParcelUuid descrUuid) {
|
||||
if (DBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " UUID=" + charUuid);
|
||||
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
BluetoothGattService service = getService(device, srvcUuid.getUuid(),
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
BluetoothGattService service = getService(mDevice, srvcUuid.getUuid(),
|
||||
srvcInstId, srvcType);
|
||||
if (service == null) return;
|
||||
|
||||
@ -529,9 +525,11 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
public void onExecuteWrite(String address, int status) {
|
||||
if (DBG) Log.d(TAG, "onExecuteWrite() - Device=" + address
|
||||
+ " status=" + status);
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mCallback.onReliableWriteCompleted(device, status);
|
||||
mCallback.onReliableWriteCompleted(mDevice, status);
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Unhandled exception: " + ex);
|
||||
}
|
||||
@ -544,43 +542,24 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
public void onReadRemoteRssi(String address, int rssi, int status) {
|
||||
if (DBG) Log.d(TAG, "onReadRemoteRssi() - Device=" + address +
|
||||
" rssi=" + rssi + " status=" + status);
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
if (!address.equals(mDevice.getAddress())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mCallback.onReadRemoteRssi(device, rssi, status);
|
||||
mCallback.onReadRemoteRssi(mDevice, rssi, status);
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Unhandled exception: " + ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a BluetoothGatt proxy object.
|
||||
*/
|
||||
/*package*/ BluetoothGatt(Context context, ServiceListener l) {
|
||||
/*package*/ BluetoothGatt(Context context, IBluetoothGatt iGatt, BluetoothDevice device) {
|
||||
mContext = context;
|
||||
mServiceListener = l;
|
||||
mAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
mService = iGatt;
|
||||
mDevice = device;
|
||||
mServices = new ArrayList<BluetoothGattService>();
|
||||
|
||||
IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE);
|
||||
if (b != null) {
|
||||
IBluetoothManager mgr = IBluetoothManager.Stub.asInterface(b);
|
||||
try {
|
||||
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Unable to register BluetoothStateChangeCallback", re);
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Unable to get BluetoothManager interface.");
|
||||
throw new RuntimeException("BluetoothManager inactive");
|
||||
}
|
||||
|
||||
//Bind to the service only if the Bluetooth is ON
|
||||
if(mAdapter.isEnabled()){
|
||||
if (!context.bindService(new Intent(IBluetoothGatt.class.getName()), mConnection, 0)) {
|
||||
Log.e(TAG, "Could not bind to Bluetooth Gatt Service");
|
||||
}
|
||||
}
|
||||
mConnState = CONN_STATE_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -590,24 +569,6 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
if (DBG) Log.d(TAG, "close()");
|
||||
|
||||
unregisterApp();
|
||||
mServiceListener = null;
|
||||
|
||||
IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE);
|
||||
if (b != null) {
|
||||
IBluetoothManager mgr = IBluetoothManager.Stub.asInterface(b);
|
||||
try {
|
||||
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Unable to unregister BluetoothStateChangeCallback", re);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (mConnection) {
|
||||
if (mService != null) {
|
||||
mService = null;
|
||||
mContext.unbindService(mConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -629,18 +590,18 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
|
||||
|
||||
/**
|
||||
* Register an application callback to start using Gatt.
|
||||
* Register an application callback to start using GATT.
|
||||
*
|
||||
* <p>This is an asynchronous call. The callback is used to notify
|
||||
* success or failure if the function returns true.
|
||||
* <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered}
|
||||
* 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, if application was successfully registered.
|
||||
* @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
|
||||
*/
|
||||
public boolean registerApp(BluetoothGattCallback callback) {
|
||||
private boolean registerApp(BluetoothGattCallback callback) {
|
||||
if (DBG) Log.d(TAG, "registerApp()");
|
||||
if (mService == null) return false;
|
||||
|
||||
@ -661,7 +622,7 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
/**
|
||||
* Unregister the current application and callbacks.
|
||||
*/
|
||||
public void unregisterApp() {
|
||||
private void unregisterApp() {
|
||||
if (DBG) Log.d(TAG, "unregisterApp() - mClientIf=" + mClientIf);
|
||||
if (mService == null || mClientIf == 0) return;
|
||||
|
||||
@ -675,77 +636,7 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a scan for Bluetooth LE devices.
|
||||
*
|
||||
* <p>Results of the scan are reported using the
|
||||
* {@link BluetoothGattCallback#onScanResult} callback.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return true, if the scan was started successfully
|
||||
*/
|
||||
public boolean startScan() {
|
||||
if (DBG) Log.d(TAG, "startScan()");
|
||||
if (mService == null || mClientIf == 0) return false;
|
||||
|
||||
try {
|
||||
mService.startScan(mClientIf, false);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a scan for Bluetooth LE devices, looking for devices that
|
||||
* advertise given services.
|
||||
*
|
||||
* <p>Devices which advertise all specified services are reported using the
|
||||
* {@link BluetoothGattCallback#onScanResult} callback.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param serviceUuids Array of services to look for
|
||||
* @return true, if the scan was started successfully
|
||||
*/
|
||||
public boolean startScan(UUID[] serviceUuids) {
|
||||
if (DBG) Log.d(TAG, "startScan() - with UUIDs");
|
||||
if (mService == null || mClientIf == 0) return false;
|
||||
|
||||
try {
|
||||
ParcelUuid[] uuids = new ParcelUuid[serviceUuids.length];
|
||||
for(int i = 0; i != uuids.length; ++i) {
|
||||
uuids[i] = new ParcelUuid(serviceUuids[i]);
|
||||
}
|
||||
mService.startScanWithUuids(mClientIf, false, uuids);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops an ongoing Bluetooth LE device scan.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*/
|
||||
public void stopScan() {
|
||||
if (DBG) Log.d(TAG, "stopScan()");
|
||||
if (mService == null || mClientIf == 0) return;
|
||||
|
||||
try {
|
||||
mService.stopScan(mClientIf, false);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate a connection to a Bluetooth Gatt capable device.
|
||||
* 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
|
||||
@ -757,7 +648,7 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
* 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 false.
|
||||
* autoConnect parameter set to true.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
@ -767,18 +658,24 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
* 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 || mClientIf == 0) return false;
|
||||
|
||||
try {
|
||||
mService.clientConnect(mClientIf, device.getAddress(),
|
||||
autoConnect ? false : true); // autoConnect is inverse of "isDirect"
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
/*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -787,18 +684,17 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
* 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, "cancelOpen() - device: " + device.getAddress());
|
||||
public void disconnect() {
|
||||
if (DBG) Log.d(TAG, "cancelOpen() - device: " + mDevice.getAddress());
|
||||
if (mService == null || mClientIf == 0) return;
|
||||
|
||||
try {
|
||||
mService.clientDisconnect(mClientIf, device.getAddress());
|
||||
mService.clientDisconnect(mClientIf, mDevice.getAddress());
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
// TBD deregister after conneciton is torn down
|
||||
}
|
||||
|
||||
/**
|
||||
@ -812,17 +708,16 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param device Remote device to explore
|
||||
* @return true, if the remote service discovery has been started
|
||||
*/
|
||||
public boolean discoverServices(BluetoothDevice device) {
|
||||
if (DBG) Log.d(TAG, "discoverServices() - device: " + device.getAddress());
|
||||
public boolean discoverServices() {
|
||||
if (DBG) Log.d(TAG, "discoverServices() - device: " + mDevice.getAddress());
|
||||
if (mService == null || mClientIf == 0) return false;
|
||||
|
||||
mServices.clear();
|
||||
|
||||
try {
|
||||
mService.discoverServices(mClientIf, device.getAddress());
|
||||
mService.discoverServices(mClientIf, mDevice.getAddress());
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
@ -839,16 +734,15 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param device Remote device
|
||||
* @return List of services on the remote device. Returns an empty list
|
||||
* if service discovery has not yet been performed.
|
||||
*/
|
||||
public List<BluetoothGattService> getServices(BluetoothDevice device) {
|
||||
public List<BluetoothGattService> getServices() {
|
||||
List<BluetoothGattService> result =
|
||||
new ArrayList<BluetoothGattService>();
|
||||
|
||||
for (BluetoothGattService service : mServices) {
|
||||
if (service.getDevice().equals(device)) {
|
||||
if (service.getDevice().equals(mDevice)) {
|
||||
result.add(service);
|
||||
}
|
||||
}
|
||||
@ -868,14 +762,13 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param device Remote device
|
||||
* @param uuid UUID of the requested service
|
||||
* @return BluetoothGattService if supported, or null if the requested
|
||||
* service is not offered by the remote device.
|
||||
*/
|
||||
public BluetoothGattService getService(BluetoothDevice device, UUID uuid) {
|
||||
public BluetoothGattService getService(UUID uuid) {
|
||||
for (BluetoothGattService service : mServices) {
|
||||
if (service.getDevice().equals(device) &&
|
||||
if (service.getDevice().equals(mDevice) &&
|
||||
service.getUuid().equals(uuid)) {
|
||||
return service;
|
||||
}
|
||||
@ -923,8 +816,7 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a given characteristic and it's values to the associated remote
|
||||
* device.
|
||||
* Writes a given characteristic and its values to the associated remote device.
|
||||
*
|
||||
* <p>Once the write operation has been completed, the
|
||||
* {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked,
|
||||
@ -1061,15 +953,14 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param device Remote device
|
||||
* @return true, if the reliable write transaction has been initiated
|
||||
*/
|
||||
public boolean beginReliableWrite(BluetoothDevice device) {
|
||||
if (DBG) Log.d(TAG, "beginReliableWrite() - device: " + device.getAddress());
|
||||
public boolean beginReliableWrite() {
|
||||
if (DBG) Log.d(TAG, "beginReliableWrite() - device: " + mDevice.getAddress());
|
||||
if (mService == null || mClientIf == 0) return false;
|
||||
|
||||
try {
|
||||
mService.beginReliableWrite(mClientIf, device.getAddress());
|
||||
mService.beginReliableWrite(mClientIf, mDevice.getAddress());
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
@ -1089,15 +980,14 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param device Remote device
|
||||
* @return true, if the request to execute the transaction has been sent
|
||||
*/
|
||||
public boolean executeReliableWrite(BluetoothDevice device) {
|
||||
if (DBG) Log.d(TAG, "executeReliableWrite() - device: " + device.getAddress());
|
||||
public boolean executeReliableWrite() {
|
||||
if (DBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
|
||||
if (mService == null || mClientIf == 0) return false;
|
||||
|
||||
try {
|
||||
mService.endReliableWrite(mClientIf, device.getAddress(), true);
|
||||
mService.endReliableWrite(mClientIf, mDevice.getAddress(), true);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
@ -1113,15 +1003,13 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
* operations for a given remote device.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param device Remote device
|
||||
*/
|
||||
public void abortReliableWrite(BluetoothDevice device) {
|
||||
if (DBG) Log.d(TAG, "abortReliableWrite() - device: " + device.getAddress());
|
||||
public void abortReliableWrite(BluetoothDevice mDevice) {
|
||||
if (DBG) Log.d(TAG, "abortReliableWrite() - device: " + mDevice.getAddress());
|
||||
if (mService == null || mClientIf == 0) return;
|
||||
|
||||
try {
|
||||
mService.endReliableWrite(mClientIf, device.getAddress(), false);
|
||||
mService.endReliableWrite(mClientIf, mDevice.getAddress(), false);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
@ -1172,12 +1060,12 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
* remote device.
|
||||
* @hide
|
||||
*/
|
||||
public boolean refresh(BluetoothDevice device) {
|
||||
if (DBG) Log.d(TAG, "refresh() - device: " + device.getAddress());
|
||||
public boolean refresh() {
|
||||
if (DBG) Log.d(TAG, "refresh() - device: " + mDevice.getAddress());
|
||||
if (mService == null || mClientIf == 0) return false;
|
||||
|
||||
try {
|
||||
mService.refreshDevice(mClientIf, device.getAddress());
|
||||
mService.refreshDevice(mClientIf, mDevice.getAddress());
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
@ -1194,15 +1082,14 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param device Remote device
|
||||
* @return true, if the RSSI value has been requested successfully
|
||||
*/
|
||||
public boolean readRemoteRssi(BluetoothDevice device) {
|
||||
if (DBG) Log.d(TAG, "readRssi() - device: " + device.getAddress());
|
||||
public boolean readRemoteRssi() {
|
||||
if (DBG) Log.d(TAG, "readRssi() - device: " + mDevice.getAddress());
|
||||
if (mService == null || mClientIf == 0) return false;
|
||||
|
||||
try {
|
||||
mService.readRemoteRssi(mClientIf, device.getAddress());
|
||||
mService.readRemoteRssi(mClientIf, mDevice.getAddress());
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
@ -1212,98 +1099,38 @@ public final class BluetoothGatt implements BluetoothProfile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current connection state of the profile.
|
||||
* Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
|
||||
* with {@link BluetoothProfile#GATT} as argument
|
||||
*
|
||||
* <p>This is not specific to any application configuration but represents
|
||||
* the connection state of the local Bluetooth adapter for this profile.
|
||||
* This can be used by applications like status bar which would just like
|
||||
* to know the state of the local adapter.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param device Remote bluetooth device.
|
||||
* @return State of the profile connection. One of
|
||||
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
|
||||
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
@Override
|
||||
public int getConnectionState(BluetoothDevice device) {
|
||||
if (DBG) Log.d(TAG,"getConnectionState()");
|
||||
if (mService == null) return STATE_DISCONNECTED;
|
||||
|
||||
List<BluetoothDevice> connectedDevices = getConnectedDevices();
|
||||
for(BluetoothDevice connectedDevice : connectedDevices) {
|
||||
if (device.equals(connectedDevice)) {
|
||||
return STATE_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return STATE_DISCONNECTED;
|
||||
throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connected devices for the Gatt profile.
|
||||
* Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
|
||||
* with {@link BluetoothProfile#GATT} as argument
|
||||
*
|
||||
* <p> Return the set of devices which are in state {@link #STATE_CONNECTED}
|
||||
*
|
||||
* <p>This is not specific to any application configuration but represents
|
||||
* the connection state of the local Bluetooth adapter for this profile.
|
||||
* This can be used by applications like status bar which would just like
|
||||
* to know the state of the local adapter.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return List of devices. The list will be empty on error.
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
@Override
|
||||
public List<BluetoothDevice> getConnectedDevices() {
|
||||
if (DBG) Log.d(TAG,"getConnectedDevices");
|
||||
|
||||
List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>();
|
||||
if (mService == null) return connectedDevices;
|
||||
|
||||
try {
|
||||
connectedDevices = mService.getDevicesMatchingConnectionStates(
|
||||
new int[] { BluetoothProfile.STATE_CONNECTED });
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
|
||||
return connectedDevices;
|
||||
throw new UnsupportedOperationException
|
||||
("Use BluetoothManager#getConnectedDevices instead.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of devices that match any of the given connection
|
||||
* states.
|
||||
* Not supported - please use
|
||||
* {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])}
|
||||
* with {@link BluetoothProfile#GATT} as first argument
|
||||
*
|
||||
* <p> If none of the devices match any of the given states,
|
||||
* an empty list will be returned.
|
||||
*
|
||||
* <p>This is not specific to any application configuration but represents
|
||||
* the connection state of the local Bluetooth adapter for this profile.
|
||||
* This can be used by applications like status bar which would just like
|
||||
* to know the state of the local adapter.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param states Array of states. States can be one of
|
||||
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
|
||||
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
|
||||
* @return List of devices. The list will be empty on error.
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
@Override
|
||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||
if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates");
|
||||
|
||||
List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
|
||||
if (mService == null) return devices;
|
||||
|
||||
try {
|
||||
devices = mService.getDevicesMatchingConnectionStates(states);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
|
||||
return devices;
|
||||
throw new UnsupportedOperationException
|
||||
("Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
|
||||
}
|
||||
}
|
||||
|
@ -18,34 +18,10 @@ package android.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* This abstract class is used to implement {@link BluetoothGatt} callbacks.
|
||||
* @hide
|
||||
*/
|
||||
public abstract class BluetoothGattCallback {
|
||||
/**
|
||||
* Callback to inform change in registration state of the application.
|
||||
*
|
||||
* @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the application
|
||||
* was successfully registered.
|
||||
*/
|
||||
public void onAppRegistered(int status) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback reporting an LE device found during a device scan initiated
|
||||
* by the {@link BluetoothGatt#startScan} function.
|
||||
*
|
||||
* @param device Identifies the remote device
|
||||
* @param rssi The RSSI value for the remote device as reported by the
|
||||
* Bluetooth hardware. 0 if no RSSI value is available.
|
||||
* @param scanRecord The content of the advertisement record offered by
|
||||
* the remote device.
|
||||
*/
|
||||
public void onScanResult(BluetoothDevice device, int rssi, byte[] scanRecord) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback indicating when a remote device has been connected or disconnected.
|
||||
@ -61,8 +37,8 @@ public abstract class BluetoothGattCallback {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback invoked when the list of remote services, characteristics and
|
||||
* descriptors for the remote device have been updated.
|
||||
* Callback invoked when the list of remote services, characteristics and descriptors
|
||||
* for the remote device have been updated, ie new services have been discovered.
|
||||
*
|
||||
* @param device Remote device
|
||||
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device
|
||||
@ -97,7 +73,7 @@ public abstract class BluetoothGattCallback {
|
||||
* @param status The result of the write operation
|
||||
*/
|
||||
public void onCharacteristicWrite(BluetoothGattCharacteristic characteristic,
|
||||
int status) {
|
||||
int status) {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,23 +89,21 @@ public abstract class BluetoothGattCallback {
|
||||
* Callback reporting the result of a descriptor read operation.
|
||||
*
|
||||
* @param descriptor Descriptor that was read from the associated
|
||||
* remote device.
|
||||
* remote device.
|
||||
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
|
||||
* was completed successfully
|
||||
*/
|
||||
public void onDescriptorRead(BluetoothGattDescriptor descriptor,
|
||||
int status) {
|
||||
public void onDescriptorRead(BluetoothGattDescriptor descriptor, int status) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback indicating the result of a descriptor write operation.
|
||||
*
|
||||
* @param descriptor Descriptor that was writte to the associated
|
||||
* remote device.
|
||||
* remote device.
|
||||
* @param status The result of the write operation
|
||||
*/
|
||||
public void onDescriptorWrite(BluetoothGattDescriptor descriptor,
|
||||
int status) {
|
||||
public void onDescriptorWrite(BluetoothGattDescriptor descriptor, int status) {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,7 +124,7 @@ public abstract class BluetoothGattCallback {
|
||||
*
|
||||
* @param device Identifies the remote device
|
||||
* @param rssi The RSSI value for the remote device
|
||||
* @param status 0 if the RSSI was read successfully
|
||||
* @param status {@link BluetoothGatt#GATT_SUCCESS} if the RSSI was read successfully
|
||||
*/
|
||||
public void onReadRemoteRssi(BluetoothDevice device, int rssi, int status) {
|
||||
}
|
||||
|
@ -21,8 +21,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a Bluetooth Gatt Characteristic
|
||||
* @hide
|
||||
* Represents a Bluetooth GATT Characteristic
|
||||
*/
|
||||
public class BluetoothGattCharacteristic {
|
||||
|
||||
@ -119,7 +118,7 @@ public class BluetoothGattCharacteristic {
|
||||
public static final int WRITE_TYPE_NO_RESPONSE = 0x01;
|
||||
|
||||
/**
|
||||
* Write characteristic including and authenticated signature
|
||||
* Write characteristic including authentication signature
|
||||
*/
|
||||
public static final int WRITE_TYPE_SIGNED = 0x04;
|
||||
|
||||
@ -218,6 +217,18 @@ public class BluetoothGattCharacteristic {
|
||||
*/
|
||||
protected List<BluetoothGattDescriptor> mDescriptors;
|
||||
|
||||
/**
|
||||
* Create a new BluetoothGattCharacteristic.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param uuid The UUID for this characteristic
|
||||
* @param properties Properties of this characteristic
|
||||
* @param permissions Permissions for this characteristic
|
||||
*/
|
||||
public BluetoothGattCharacteristic(UUID uuid, int properties, int permissions) {
|
||||
initCharacteristic(null, uuid, 0, properties, permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new BluetoothGattCharacteristic
|
||||
* @hide
|
||||
@ -225,6 +236,12 @@ public class BluetoothGattCharacteristic {
|
||||
/*package*/ BluetoothGattCharacteristic(BluetoothGattService service,
|
||||
UUID uuid, int instanceId,
|
||||
int properties, int permissions) {
|
||||
initCharacteristic(service, uuid, instanceId, properties, permissions);
|
||||
}
|
||||
|
||||
private void initCharacteristic(BluetoothGattService service,
|
||||
UUID uuid, int instanceId,
|
||||
int properties, int permissions) {
|
||||
mUuid = uuid;
|
||||
mInstance = instanceId;
|
||||
mProperties = properties;
|
||||
@ -249,11 +266,16 @@ public class BluetoothGattCharacteristic {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a descriptor to this characteristic
|
||||
* @hide
|
||||
* Adds a descriptor to this characteristic.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param descriptor Descriptor to be added to this characteristic.
|
||||
* @return true, if the descriptor was added to the characteristic
|
||||
*/
|
||||
/*package*/ void addDescriptor(BluetoothGattDescriptor descriptor) {
|
||||
public boolean addDescriptor(BluetoothGattDescriptor descriptor) {
|
||||
mDescriptors.add(descriptor);
|
||||
descriptor.setCharacteristic(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,9 +286,16 @@ public class BluetoothGattCharacteristic {
|
||||
return mService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service associated with this device.
|
||||
* @hide
|
||||
*/
|
||||
/*package*/ void setService(BluetoothGattService service) {
|
||||
mService = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UUID of this characteristic
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return UUID of this characteristic
|
||||
*/
|
||||
@ -280,8 +309,6 @@ public class BluetoothGattCharacteristic {
|
||||
* <p>If a remote device offers multiple characteristics with the same UUID,
|
||||
* the instance ID is used to distuinguish between characteristics.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Instance ID of this characteristic
|
||||
*/
|
||||
public int getInstanceId() {
|
||||
@ -294,8 +321,6 @@ public class BluetoothGattCharacteristic {
|
||||
* <p>The properties contain a bit mask of property flags indicating
|
||||
* the features of this characteristic.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Properties of this characteristic
|
||||
*/
|
||||
public int getProperties() {
|
||||
@ -304,7 +329,6 @@ public class BluetoothGattCharacteristic {
|
||||
|
||||
/**
|
||||
* Returns the permissions for this characteristic.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Permissions of this characteristic
|
||||
*/
|
||||
@ -314,7 +338,6 @@ public class BluetoothGattCharacteristic {
|
||||
|
||||
/**
|
||||
* Gets the write type for this characteristic.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Write type for this characteristic
|
||||
*/
|
||||
@ -329,11 +352,6 @@ public class BluetoothGattCharacteristic {
|
||||
* {@link BluetoothGatt#writeCharacteristic} function write this
|
||||
* characteristic.
|
||||
*
|
||||
* <p>The default write type for a characteristic is
|
||||
* {@link #WRITE_TYPE_DEFAULT}.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param writeType The write type to for this characteristic. Can be one
|
||||
* of:
|
||||
* {@link #WRITE_TYPE_DEFAULT},
|
||||
@ -344,9 +362,16 @@ public class BluetoothGattCharacteristic {
|
||||
mWriteType = writeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the desired key size.
|
||||
* @hide
|
||||
*/
|
||||
public void setKeySize(int keySize) {
|
||||
mKeySize = keySize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of descriptors for this characteristic.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Descriptors for this characteristic
|
||||
*/
|
||||
@ -358,9 +383,7 @@ public class BluetoothGattCharacteristic {
|
||||
* Returns a descriptor with a given UUID out of the list of
|
||||
* descriptors for this characteristic.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Gatt descriptor object or null if no descriptor with the
|
||||
* @return GATT descriptor object or null if no descriptor with the
|
||||
* given UUID was found.
|
||||
*/
|
||||
public BluetoothGattDescriptor getDescriptor(UUID uuid) {
|
||||
@ -376,12 +399,10 @@ public class BluetoothGattCharacteristic {
|
||||
* Get the stored value for this characteristic.
|
||||
*
|
||||
* <p>This function returns the stored value for this characteristic as
|
||||
* retrieved by calling {@link BluetoothGatt#readCharacteristic}. To cached
|
||||
* retrieved by calling {@link BluetoothGatt#readCharacteristic}. The cached
|
||||
* value of the characteristic is updated as a result of a read characteristic
|
||||
* operation or if a characteristic update notification has been received.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Cached value of the characteristic
|
||||
*/
|
||||
public byte[] getValue() {
|
||||
@ -397,8 +418,6 @@ public class BluetoothGattCharacteristic {
|
||||
* characteristic value at the given offset are interpreted to generate the
|
||||
* return value.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param formatType The format type used to interpret the characteristic
|
||||
* value.
|
||||
* @param offset Offset at which the integer value can be found.
|
||||
@ -436,7 +455,6 @@ public class BluetoothGattCharacteristic {
|
||||
/**
|
||||
* Return the stored value of this characteristic.
|
||||
* <p>See {@link #getValue} for details.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param formatType The format type used to interpret the characteristic
|
||||
* value.
|
||||
@ -462,7 +480,7 @@ public class BluetoothGattCharacteristic {
|
||||
/**
|
||||
* Return the stored value of this characteristic.
|
||||
* <p>See {@link #getValue} for details.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param offset Offset at which the string value can be found.
|
||||
* @return Cached value of the characteristic
|
||||
*/
|
||||
@ -481,8 +499,6 @@ public class BluetoothGattCharacteristic {
|
||||
* {@link BluetoothGatt#writeCharacteristic} to send the value to the
|
||||
* remote device.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param value New value for this characteristic
|
||||
* @return true if the locally stored value has been set, false if the
|
||||
* requested value could not be stored locally.
|
||||
@ -495,7 +511,6 @@ public class BluetoothGattCharacteristic {
|
||||
/**
|
||||
* Set the locally stored value of this characteristic.
|
||||
* <p>See {@link #setValue(byte[])} for details.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param value New value for this characteristic
|
||||
* @param formatType Integer format type used to transform the value parameter
|
||||
@ -542,7 +557,7 @@ public class BluetoothGattCharacteristic {
|
||||
/**
|
||||
* Set the locally stored value of this characteristic.
|
||||
* <p>See {@link #setValue(byte[])} for details.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param mantissa Mantissa for this characteristic
|
||||
* @param exponent exponent value for this characteristic
|
||||
* @param formatType Float format type used to transform the value parameter
|
||||
@ -582,7 +597,7 @@ public class BluetoothGattCharacteristic {
|
||||
/**
|
||||
* Set the locally stored value of this characteristic.
|
||||
* <p>See {@link #setValue(byte[])} for details.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param value New value for this characteristic
|
||||
* @return true if the locally stored value has been set
|
||||
*/
|
||||
@ -593,7 +608,6 @@ public class BluetoothGattCharacteristic {
|
||||
|
||||
/**
|
||||
* Returns the size of a give value type.
|
||||
* @hide
|
||||
*/
|
||||
private int getTypeLen(int formatType) {
|
||||
return formatType & 0xF;
|
||||
@ -601,7 +615,6 @@ public class BluetoothGattCharacteristic {
|
||||
|
||||
/**
|
||||
* Convert a signed byte to an unsigned int.
|
||||
* @hide
|
||||
*/
|
||||
private int unsignedByteToInt(byte b) {
|
||||
return b & 0xFF;
|
||||
@ -609,7 +622,6 @@ public class BluetoothGattCharacteristic {
|
||||
|
||||
/**
|
||||
* Convert signed bytes to a 16-bit unsigned int.
|
||||
* @hide
|
||||
*/
|
||||
private int unsignedBytesToInt(byte b0, byte b1) {
|
||||
return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8));
|
||||
@ -617,7 +629,6 @@ public class BluetoothGattCharacteristic {
|
||||
|
||||
/**
|
||||
* Convert signed bytes to a 32-bit unsigned int.
|
||||
* @hide
|
||||
*/
|
||||
private int unsignedBytesToInt(byte b0, byte b1, byte b2, byte b3) {
|
||||
return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8))
|
||||
@ -626,7 +637,6 @@ public class BluetoothGattCharacteristic {
|
||||
|
||||
/**
|
||||
* Convert signed bytes to a 16-bit short float value.
|
||||
* @hide
|
||||
*/
|
||||
private float bytesToFloat(byte b0, byte b1) {
|
||||
int mantissa = unsignedToSigned(unsignedByteToInt(b0)
|
||||
@ -637,7 +647,6 @@ public class BluetoothGattCharacteristic {
|
||||
|
||||
/**
|
||||
* Convert signed bytes to a 32-bit short float value.
|
||||
* @hide
|
||||
*/
|
||||
private float bytesToFloat(byte b0, byte b1, byte b2, byte b3) {
|
||||
int mantissa = unsignedToSigned(unsignedByteToInt(b0)
|
||||
@ -649,7 +658,6 @@ public class BluetoothGattCharacteristic {
|
||||
/**
|
||||
* Convert an unsigned integer value to a two's-complement encoded
|
||||
* signed value.
|
||||
* @hide
|
||||
*/
|
||||
private int unsignedToSigned(int unsigned, int size) {
|
||||
if ((unsigned & (1 << size-1)) != 0) {
|
||||
@ -660,7 +668,6 @@ public class BluetoothGattCharacteristic {
|
||||
|
||||
/**
|
||||
* Convert an integer into the signed bits of a given length.
|
||||
* @hide
|
||||
*/
|
||||
private int intToSignedBits(int i, int size) {
|
||||
if (i < 0) {
|
||||
|
@ -19,8 +19,7 @@ package android.bluetooth;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a Bluetooth Gatt Descriptor
|
||||
* @hide
|
||||
* Represents a Bluetooth GATT Descriptor
|
||||
*/
|
||||
public class BluetoothGattDescriptor {
|
||||
|
||||
@ -105,6 +104,17 @@ public class BluetoothGattDescriptor {
|
||||
*/
|
||||
protected byte[] mValue;
|
||||
|
||||
/**
|
||||
* Create a new BluetoothGattDescriptor.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param uuid The UUID for this descriptor
|
||||
* @param permissions Permissions for this descriptor
|
||||
*/
|
||||
public BluetoothGattDescriptor(UUID uuid, int permissions) {
|
||||
initDescriptor(null, uuid, permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new BluetoothGattDescriptor.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
@ -115,6 +125,11 @@ public class BluetoothGattDescriptor {
|
||||
*/
|
||||
/*package*/ BluetoothGattDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
|
||||
int permissions) {
|
||||
initDescriptor(characteristic, uuid, permissions);
|
||||
}
|
||||
|
||||
private void initDescriptor(BluetoothGattCharacteristic characteristic, UUID uuid,
|
||||
int permissions) {
|
||||
mCharacteristic = characteristic;
|
||||
mUuid = uuid;
|
||||
mPermissions = permissions;
|
||||
@ -128,9 +143,16 @@ public class BluetoothGattDescriptor {
|
||||
return mCharacteristic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the back-reference to the associated characteristic
|
||||
* @hide
|
||||
*/
|
||||
/*package*/ void setCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
mCharacteristic = characteristic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UUID of this descriptor.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return UUID of this descriptor
|
||||
*/
|
||||
@ -140,7 +162,6 @@ public class BluetoothGattDescriptor {
|
||||
|
||||
/**
|
||||
* Returns the permissions for this descriptor.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Permissions of this descriptor
|
||||
*/
|
||||
@ -152,12 +173,10 @@ public class BluetoothGattDescriptor {
|
||||
* Returns the stored value for this descriptor
|
||||
*
|
||||
* <p>This function returns the stored value for this descriptor as
|
||||
* retrieved by calling {@link BluetoothGatt#readDescriptor}. To cached
|
||||
* retrieved by calling {@link BluetoothGatt#readDescriptor}. The cached
|
||||
* value of the descriptor is updated as a result of a descriptor read
|
||||
* operation.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Cached value of the descriptor
|
||||
*/
|
||||
public byte[] getValue() {
|
||||
@ -172,8 +191,6 @@ public class BluetoothGattDescriptor {
|
||||
* {@link BluetoothGatt#writeDescriptor} to send the value to the
|
||||
* remote device.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param value New value for this descriptor
|
||||
* @return true if the locally stored value has been set, false if the
|
||||
* requested value could not be stored locally.
|
||||
|
@ -38,88 +38,30 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Public API for the Bluetooth Gatt Profile server role.
|
||||
* Public API for the Bluetooth GATT Profile server role.
|
||||
*
|
||||
* <p>This class provides Bluetooth Gatt server role functionality,
|
||||
* <p>This class provides Bluetooth GATT server role functionality,
|
||||
* allowing applications to create and advertise Bluetooth Smart services
|
||||
* and characteristics.
|
||||
*
|
||||
* <p>BluetoothGattServer is a proxy object for controlling the Bluetooth Service
|
||||
* via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get the
|
||||
* BluetoothGatt proxy object.
|
||||
* @hide
|
||||
*/
|
||||
public final class BluetoothGattServer implements BluetoothProfile {
|
||||
private static final String TAG = "BluetoothGattServer";
|
||||
private static final boolean DBG = true;
|
||||
|
||||
private Context mContext;
|
||||
private ServiceListener mServiceListener;
|
||||
private final Context mContext;
|
||||
private BluetoothAdapter mAdapter;
|
||||
private IBluetoothGatt mService;
|
||||
private BluetoothGattServerCallback mCallback;
|
||||
private int mServerIf;
|
||||
|
||||
private Object mServerIfLock = new Object();
|
||||
private int mServerIf;
|
||||
private List<BluetoothGattService> mServices;
|
||||
|
||||
/**
|
||||
* Bluetooth state change handlers
|
||||
*/
|
||||
private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
|
||||
new IBluetoothStateChangeCallback.Stub() {
|
||||
public void onBluetoothStateChange(boolean up) {
|
||||
if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
|
||||
if (!up) {
|
||||
if (DBG) Log.d(TAG,"Unbinding service...");
|
||||
synchronized (mConnection) {
|
||||
try {
|
||||
mService = null;
|
||||
mContext.unbindService(mConnection);
|
||||
} catch (Exception re) {
|
||||
Log.e(TAG,"",re);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
synchronized (mConnection) {
|
||||
try {
|
||||
if (mService == null) {
|
||||
if (DBG) Log.d(TAG,"Binding service...");
|
||||
if (!mContext.bindService(new
|
||||
Intent(IBluetoothGatt.class.getName()),
|
||||
mConnection, 0)) {
|
||||
Log.e(TAG, "Could not bind to Bluetooth GATT Service");
|
||||
}
|
||||
}
|
||||
} catch (Exception re) {
|
||||
Log.e(TAG,"",re);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Service binder handling
|
||||
*/
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
if (DBG) Log.d(TAG, "Proxy object connected");
|
||||
mService = IBluetoothGatt.Stub.asInterface(service);
|
||||
ServiceListener serviceListner = mServiceListener;
|
||||
if (serviceListner != null) {
|
||||
serviceListner.onServiceConnected(BluetoothProfile.GATT_SERVER,
|
||||
BluetoothGattServer.this);
|
||||
}
|
||||
}
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
if (DBG) Log.d(TAG, "Proxy object disconnected");
|
||||
mService = null;
|
||||
ServiceListener serviceListner = mServiceListener;
|
||||
if (serviceListner != null) {
|
||||
serviceListner.onServiceDisconnected(BluetoothProfile.GATT_SERVER);
|
||||
}
|
||||
}
|
||||
};
|
||||
private static final int CALLBACK_REG_TIMEOUT = 10000;
|
||||
|
||||
/**
|
||||
* Bluetooth GATT interface callbacks
|
||||
@ -133,11 +75,14 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
public void onServerRegistered(int status, int serverIf) {
|
||||
if (DBG) Log.d(TAG, "onServerRegistered() - status=" + status
|
||||
+ " serverIf=" + serverIf);
|
||||
mServerIf = serverIf;
|
||||
try {
|
||||
mCallback.onAppRegistered(status);
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Unhandled exception: " + ex);
|
||||
synchronized(mServerIfLock) {
|
||||
if (mCallback != null) {
|
||||
mServerIf = serverIf;
|
||||
mServerIfLock.notify();
|
||||
} else {
|
||||
// registration timeout
|
||||
Log.e(TAG, "onServerRegistered: mCallback is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,13 +92,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
*/
|
||||
public void onScanResult(String address, int rssi, byte[] advData) {
|
||||
if (DBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
|
||||
|
||||
try {
|
||||
mCallback.onScanResult(mAdapter.getRemoteDevice(address),
|
||||
rssi, advData);
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Unhandled exception: " + ex);
|
||||
}
|
||||
// no op
|
||||
}
|
||||
|
||||
/**
|
||||
@ -209,8 +148,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
BluetoothGattService service = getService(srvcUuid, srvcInstId, srvcType);
|
||||
if (service == null) return;
|
||||
|
||||
BluetoothGattCharacteristic characteristic = service.getCharacteristic(
|
||||
charUuid);
|
||||
BluetoothGattCharacteristic characteristic = service.getCharacteristic(charUuid);
|
||||
if (characteristic == null) return;
|
||||
|
||||
try {
|
||||
@ -340,31 +278,13 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
/**
|
||||
* Create a BluetoothGattServer proxy object.
|
||||
*/
|
||||
/*package*/ BluetoothGattServer(Context context, ServiceListener l) {
|
||||
/*package*/ BluetoothGattServer(Context context, IBluetoothGatt iGatt) {
|
||||
mContext = context;
|
||||
mServiceListener = l;
|
||||
mService = iGatt;
|
||||
mAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
mCallback = null;
|
||||
mServerIf = 0;
|
||||
mServices = new ArrayList<BluetoothGattService>();
|
||||
|
||||
IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE);
|
||||
if (b != null) {
|
||||
IBluetoothManager mgr = IBluetoothManager.Stub.asInterface(b);
|
||||
try {
|
||||
mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Unable to register BluetoothStateChangeCallback", re);
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Unable to get BluetoothManager interface.");
|
||||
throw new RuntimeException("BluetoothManager inactive");
|
||||
}
|
||||
|
||||
//Bind to the service only if the Bluetooth is ON
|
||||
if(mAdapter.isEnabled()){
|
||||
if (!context.bindService(new Intent(IBluetoothGatt.class.getName()), mConnection, 0)) {
|
||||
Log.e(TAG, "Could not bind to Bluetooth Gatt Service");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -372,29 +292,75 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
*/
|
||||
/*package*/ void close() {
|
||||
if (DBG) Log.d(TAG, "close()");
|
||||
unregisterCallback();
|
||||
}
|
||||
|
||||
unregisterApp();
|
||||
mServiceListener = null;
|
||||
/**
|
||||
* 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);
|
||||
|
||||
IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE);
|
||||
if (b != null) {
|
||||
IBluetoothManager mgr = IBluetoothManager.Stub.asInterface(b);
|
||||
synchronized(mServerIfLock) {
|
||||
if (mCallback != null) {
|
||||
Log.e(TAG, "App can register callback only once");
|
||||
return false;
|
||||
}
|
||||
|
||||
mCallback = callback;
|
||||
try {
|
||||
mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Unable to unregister BluetoothStateChangeCallback", re);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (mConnection) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService = null;
|
||||
mContext.unbindService(mConnection);
|
||||
} catch (Exception re) {
|
||||
Log.e(TAG,"",re);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,123 +380,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an application callback to start using Gatt.
|
||||
*
|
||||
* <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, if application was successfully registered.
|
||||
*/
|
||||
public boolean registerApp(BluetoothGattServerCallback callback) {
|
||||
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.registerServer(new ParcelUuid(uuid), mBluetoothGattServerCallback);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the current application and callbacks.
|
||||
*/
|
||||
public void unregisterApp() {
|
||||
if (DBG) Log.d(TAG, "unregisterApp() - mServerIf=" + mServerIf);
|
||||
if (mService == null || mServerIf == 0) return;
|
||||
|
||||
try {
|
||||
mCallback = null;
|
||||
mService.unregisterServer(mServerIf);
|
||||
mServerIf = 0;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a scan for Bluetooth LE devices.
|
||||
*
|
||||
* <p>Results of the scan are reported using the
|
||||
* {@link BluetoothGattServerCallback#onScanResult} callback.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return true, if the scan was started successfully
|
||||
*/
|
||||
public boolean startScan() {
|
||||
if (DBG) Log.d(TAG, "startScan()");
|
||||
if (mService == null || mServerIf == 0) return false;
|
||||
|
||||
try {
|
||||
mService.startScan(mServerIf, true);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a scan for Bluetooth LE devices, looking for devices that
|
||||
* advertise given services.
|
||||
*
|
||||
* <p>Devices which advertise all specified services are reported using the
|
||||
* {@link BluetoothGattServerCallback#onScanResult} callback.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param serviceUuids Array of services to look for
|
||||
* @return true, if the scan was started successfully
|
||||
*/
|
||||
public boolean startScan(UUID[] serviceUuids) {
|
||||
if (DBG) Log.d(TAG, "startScan() - with UUIDs");
|
||||
if (mService == null || mServerIf == 0) return false;
|
||||
|
||||
try {
|
||||
ParcelUuid[] uuids = new ParcelUuid[serviceUuids.length];
|
||||
for(int i = 0; i != uuids.length; ++i) {
|
||||
uuids[i] = new ParcelUuid(serviceUuids[i]);
|
||||
}
|
||||
mService.startScanWithUuids(mServerIf, true, uuids);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops an ongoing Bluetooth LE device scan.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*/
|
||||
public void stopScan() {
|
||||
if (DBG) Log.d(TAG, "stopScan()");
|
||||
if (mService == null || mServerIf == 0) return;
|
||||
|
||||
try {
|
||||
mService.stopScan(mServerIf, true);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate a connection to a Bluetooth Gatt capable device.
|
||||
* 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
|
||||
@ -542,11 +392,10 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
* 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 false.
|
||||
* autoConnect parameter set to true.
|
||||
*
|
||||
* <p>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).
|
||||
@ -590,7 +439,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
* 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 methots:
|
||||
* is received by one of these callback methods:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link BluetoothGattServerCallback#onCharacteristicReadRequest}
|
||||
@ -662,17 +511,17 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a service to the list of services to be advertised.
|
||||
* Add a service to the list of services to be hosted.
|
||||
*
|
||||
* <p>Once a service has been addded to the the list, the service and it's
|
||||
* included characteristics will be advertised by the local device.
|
||||
* included characteristics will be provided by the local device.
|
||||
*
|
||||
* <p>If the local device is already advertising services when this function
|
||||
* <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>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param service Service to be added to the list of services advertised
|
||||
* @param service Service to be added to the list of services provided
|
||||
* by this device.
|
||||
* @return true, if the service has been added successfully
|
||||
*/
|
||||
@ -721,11 +570,11 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a service from the list of services to be advertised.
|
||||
* Removes a service from the list of services to be provided.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param service Service to beremoved.
|
||||
* @param service Service to be removed.
|
||||
* @return true, if the service has been removed
|
||||
*/
|
||||
public boolean removeService(BluetoothGattService service) {
|
||||
@ -749,7 +598,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all services from the list of advertised services.
|
||||
* Remove all services from the list of provided services.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*/
|
||||
public void clearServices() {
|
||||
@ -765,7 +614,7 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of GATT services offered bu this device.
|
||||
* 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.
|
||||
@ -802,99 +651,40 @@ public final class BluetoothGattServer implements BluetoothProfile {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the current connection state of the profile.
|
||||
* Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
|
||||
* with {@link BluetoothProfile#GATT} as argument
|
||||
*
|
||||
* <p>This is not specific to any application configuration but represents
|
||||
* the connection state of the local Bluetooth adapter for this profile.
|
||||
* This can be used by applications like status bar which would just like
|
||||
* to know the state of the local adapter.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param device Remote bluetooth device.
|
||||
* @return State of the profile connection. One of
|
||||
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
|
||||
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
@Override
|
||||
public int getConnectionState(BluetoothDevice device) {
|
||||
if (DBG) Log.d(TAG,"getConnectionState()");
|
||||
if (mService == null) return STATE_DISCONNECTED;
|
||||
|
||||
List<BluetoothDevice> connectedDevices = getConnectedDevices();
|
||||
for(BluetoothDevice connectedDevice : connectedDevices) {
|
||||
if (device.equals(connectedDevice)) {
|
||||
return STATE_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return STATE_DISCONNECTED;
|
||||
throw new UnsupportedOperationException("Use BluetoothManager#getConnectionState instead.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connected devices for the Gatt profile.
|
||||
* Not supported - please use {@link BluetoothManager#getConnectedDevices(int)}
|
||||
* with {@link BluetoothProfile#GATT} as argument
|
||||
*
|
||||
* <p> Return the set of devices which are in state {@link #STATE_CONNECTED}
|
||||
*
|
||||
* <p>This is not specific to any application configuration but represents
|
||||
* the connection state of the local Bluetooth adapter for this profile.
|
||||
* This can be used by applications like status bar which would just like
|
||||
* to know the state of the local adapter.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return List of devices. The list will be empty on error.
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
@Override
|
||||
public List<BluetoothDevice> getConnectedDevices() {
|
||||
if (DBG) Log.d(TAG,"getConnectedDevices");
|
||||
|
||||
List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>();
|
||||
if (mService == null) return connectedDevices;
|
||||
|
||||
try {
|
||||
connectedDevices = mService.getDevicesMatchingConnectionStates(
|
||||
new int[] { BluetoothProfile.STATE_CONNECTED });
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
|
||||
return connectedDevices;
|
||||
throw new UnsupportedOperationException
|
||||
("Use BluetoothManager#getConnectedDevices instead.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of devices that match any of the given connection
|
||||
* states.
|
||||
* Not supported - please use
|
||||
* {@link BluetoothManager#getDevicesMatchingConnectionStates(int, int[])}
|
||||
* with {@link BluetoothProfile#GATT} as first argument
|
||||
*
|
||||
* <p> If none of the devices match any of the given states,
|
||||
* an empty list will be returned.
|
||||
*
|
||||
* <p>This is not specific to any application configuration but represents
|
||||
* the connection state of the local Bluetooth adapter for this profile.
|
||||
* This can be used by applications like status bar which would just like
|
||||
* to know the state of the local adapter.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param states Array of states. States can be one of
|
||||
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
|
||||
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
|
||||
* @return List of devices. The list will be empty on error.
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
@Override
|
||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
|
||||
if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates");
|
||||
|
||||
List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
|
||||
if (mService == null) return devices;
|
||||
|
||||
try {
|
||||
devices = mService.getDevicesMatchingConnectionStates(states);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
|
||||
return devices;
|
||||
throw new UnsupportedOperationException
|
||||
("Use BluetoothManager#getDevicesMatchingConnectionStates instead.");
|
||||
}
|
||||
}
|
||||
|
@ -22,30 +22,8 @@ import android.util.Log;
|
||||
|
||||
/**
|
||||
* This abstract class is used to implement {@link BluetoothGattServer} callbacks.
|
||||
* @hide
|
||||
*/
|
||||
public abstract class BluetoothGattServerCallback {
|
||||
/**
|
||||
* Callback to inform change in registration state of the application.
|
||||
*
|
||||
* @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the application
|
||||
* was successfully registered.
|
||||
*/
|
||||
public void onAppRegistered(int status) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback reporting an LE device found during a device scan initiated
|
||||
* by the {@link BluetoothGattServer#startScan} function.
|
||||
*
|
||||
* @param device Identifies the remote device
|
||||
* @param rssi The RSSI value for the remote device as reported by the
|
||||
* Bluetooth hardware. 0 if no RSSI value is available.
|
||||
* @param scanRecord The content of the advertisement record offered by
|
||||
* the remote device.
|
||||
*/
|
||||
public void onScanResult(BluetoothDevice device, int rssi, byte[] scanRecord) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback indicating when a remote device has been connected or disconnected.
|
||||
@ -101,9 +79,9 @@ public abstract class BluetoothGattServerCallback {
|
||||
* @param value The value the client wants to assign to the characteristic
|
||||
*/
|
||||
public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
|
||||
BluetoothGattCharacteristic characteristic,
|
||||
boolean preparedWrite, boolean responseNeeded,
|
||||
int offset, byte[] value) {
|
||||
BluetoothGattCharacteristic characteristic,
|
||||
boolean preparedWrite, boolean responseNeeded,
|
||||
int offset, byte[] value) {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,7 +96,7 @@ public abstract class BluetoothGattServerCallback {
|
||||
* @param descriptor Descriptor to be read
|
||||
*/
|
||||
public void onDescriptorReadRequest(BluetoothDevice device, int requestId,
|
||||
int offset, BluetoothGattDescriptor descriptor) {
|
||||
int offset, BluetoothGattDescriptor descriptor) {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,9 +115,9 @@ public abstract class BluetoothGattServerCallback {
|
||||
* @param value The value the client wants to assign to the descriptor
|
||||
*/
|
||||
public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
|
||||
BluetoothGattDescriptor descriptor,
|
||||
boolean preparedWrite, boolean responseNeeded,
|
||||
int offset, byte[] value) {
|
||||
BluetoothGattDescriptor descriptor,
|
||||
boolean preparedWrite, boolean responseNeeded,
|
||||
int offset, byte[] value) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,8 +22,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a Bluetooth Gatt Service
|
||||
* @hide
|
||||
* Represents a Bluetooth GATT Service
|
||||
*/
|
||||
public class BluetoothGattService {
|
||||
|
||||
@ -81,9 +80,14 @@ public class BluetoothGattService {
|
||||
|
||||
/**
|
||||
* Create a new BluetoothGattService.
|
||||
* @hide
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param uuid The UUID for this service
|
||||
* @param serviceType The type of this service,
|
||||
* {@link BluetoothGattService#SERVICE_TYPE_PRIMARY} or
|
||||
* {@link BluetoothGattService#SERVICE_TYPE_SECONDARY}
|
||||
*/
|
||||
/*package*/ BluetoothGattService(UUID uuid, int serviceType) {
|
||||
public BluetoothGattService(UUID uuid, int serviceType) {
|
||||
mDevice = null;
|
||||
mUuid = uuid;
|
||||
mInstanceId = 0;
|
||||
@ -115,11 +119,28 @@ public class BluetoothGattService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a characteristic to this service.
|
||||
* @hide
|
||||
* Add an included service to this service.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param service The service to be added
|
||||
* @return true, if the included service was added to the service
|
||||
*/
|
||||
/*package*/ void addCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
public boolean addService(BluetoothGattService service) {
|
||||
mIncludedServices.add(service);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a characteristic to this service.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param characteristic The characteristics to be added
|
||||
* @return true, if the characteristic was added to the service
|
||||
*/
|
||||
public boolean addCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
mCharacteristics.add(characteristic);
|
||||
characteristic.setService(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,6 +156,15 @@ public class BluetoothGattService {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the instance ID.
|
||||
* This is needed for conformance testing only.
|
||||
* @hide
|
||||
*/
|
||||
public void setInstanceId(int instanceId) {
|
||||
mInstanceId = instanceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the handle count override (conformance testing.
|
||||
* @hide
|
||||
@ -143,6 +173,15 @@ public class BluetoothGattService {
|
||||
return mHandles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the number of handles to reserve for this service.
|
||||
* This is needed for conformance testing only.
|
||||
* @hide
|
||||
*/
|
||||
public void setHandles(int handles) {
|
||||
mHandles = handles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an included service to the internal map.
|
||||
* @hide
|
||||
@ -153,7 +192,6 @@ public class BluetoothGattService {
|
||||
|
||||
/**
|
||||
* Returns the UUID of this service
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return UUID of this service
|
||||
*/
|
||||
@ -168,8 +206,6 @@ public class BluetoothGattService {
|
||||
* (ex. multiple battery services for different batteries), the instance
|
||||
* ID is used to distuinguish services.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Instance ID of this service
|
||||
*/
|
||||
public int getInstanceId() {
|
||||
@ -178,15 +214,13 @@ public class BluetoothGattService {
|
||||
|
||||
/**
|
||||
* Get the type of this service (primary/secondary)
|
||||
* @hide
|
||||
*/
|
||||
public int getType() {
|
||||
return mServiceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of included Gatt services for this service.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
* Get the list of included GATT services for this service.
|
||||
*
|
||||
* @return List of included services or empty list if no included services
|
||||
* were discovered.
|
||||
@ -197,7 +231,6 @@ public class BluetoothGattService {
|
||||
|
||||
/**
|
||||
* Returns a list of characteristics included in this service.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Characteristics included in this service
|
||||
*/
|
||||
@ -217,9 +250,7 @@ public class BluetoothGattService {
|
||||
* UUID, the first instance of a characteristic with the given UUID
|
||||
* is returned.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @return Gatt characteristic object or null if no characteristic with the
|
||||
* @return GATT characteristic object or null if no characteristic with the
|
||||
* given UUID was found.
|
||||
*/
|
||||
public BluetoothGattCharacteristic getCharacteristic(UUID uuid) {
|
||||
|
219
core/java/android/bluetooth/BluetoothManager.java
Normal file
219
core/java/android/bluetooth/BluetoothManager.java
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* 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.content.Context;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* High level manager used to obtain an instance of an {@link BluetoothAdapter}
|
||||
* and to conduct overall Bluetooth Management.
|
||||
* <p>
|
||||
* Use {@link android.content.Context#getSystemService(java.lang.String)}
|
||||
* with {@link Context#BLUETOOTH_SERVICE} to create an {@link BluetoothManager},
|
||||
* then call {@link #getAdapter} to obtain the {@link BluetoothAdapter}.
|
||||
* <p>
|
||||
* Alternately, you can just call the static helper
|
||||
* {@link BluetoothAdapter#getDefaultAdapter()}.
|
||||
*
|
||||
* <div class="special reference">
|
||||
* <h3>Developer Guides</h3>
|
||||
* <p>For more information about using BLUETOOTH, read the
|
||||
* <a href="{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> developer guide.</p>
|
||||
* </div>
|
||||
*
|
||||
* @see Context#getSystemService
|
||||
* @see BluetoothAdapter#getDefaultAdapter()
|
||||
*/
|
||||
public final class BluetoothManager {
|
||||
private static final String TAG = "BluetoothManager";
|
||||
private static final boolean DBG = true;
|
||||
private static final boolean VDBG = true;
|
||||
|
||||
private final BluetoothAdapter mAdapter;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public BluetoothManager(Context context) {
|
||||
context = context.getApplicationContext();
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"context not associated with any application (using a mock context?)");
|
||||
}
|
||||
// Legacy api - getDefaultAdapter does not take in the context
|
||||
mAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default BLUETOOTH Adapter for this device.
|
||||
*
|
||||
* @return the default BLUETOOTH Adapter
|
||||
*/
|
||||
public BluetoothAdapter getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current connection state of the profile to the remote device.
|
||||
*
|
||||
* <p>This is not specific to any application configuration but represents
|
||||
* the connection state of the local Bluetooth adapter for certain profile.
|
||||
* This can be used by applications like status bar which would just like
|
||||
* to know the state of Bluetooth.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param device Remote bluetooth device.
|
||||
* @param profile GATT or GATT_SERVER
|
||||
* @return State of the profile connection. One of
|
||||
* {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING},
|
||||
* {@link BluetoothProfile#STATE_DISCONNECTED},
|
||||
* {@link BluetoothProfile#STATE_DISCONNECTING}
|
||||
*/
|
||||
public int getConnectionState(BluetoothDevice device, int profile) {
|
||||
if (DBG) Log.d(TAG,"getConnectionState()");
|
||||
|
||||
List<BluetoothDevice> connectedDevices = getConnectedDevices(profile);
|
||||
for(BluetoothDevice connectedDevice : connectedDevices) {
|
||||
if (device.equals(connectedDevice)) {
|
||||
return BluetoothProfile.STATE_CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return BluetoothProfile.STATE_DISCONNECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connected devices for the specified profile.
|
||||
*
|
||||
* <p> Return the set of devices which are in state {@link BluetoothProfile#STATE_CONNECTED}
|
||||
*
|
||||
* <p>This is not specific to any application configuration but represents
|
||||
* the connection state of Bluetooth for this profile.
|
||||
* This can be used by applications like status bar which would just like
|
||||
* to know the state of Bluetooth.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param profile GATT or GATT_SERVER
|
||||
* @return List of devices. The list will be empty on error.
|
||||
*/
|
||||
public List<BluetoothDevice> getConnectedDevices(int profile) {
|
||||
if (DBG) Log.d(TAG,"getConnectedDevices");
|
||||
if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
|
||||
throw new IllegalArgumentException("Profile not supported: " + profile);
|
||||
}
|
||||
|
||||
List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>();
|
||||
|
||||
try {
|
||||
IBluetoothManager managerService = mAdapter.getBluetoothManager();
|
||||
IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt();
|
||||
if (iGatt == null) return connectedDevices;
|
||||
|
||||
connectedDevices = iGatt.getDevicesMatchingConnectionStates(
|
||||
new int[] { BluetoothProfile.STATE_CONNECTED });
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
|
||||
return connectedDevices;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get a list of devices that match any of the given connection
|
||||
* states.
|
||||
*
|
||||
* <p> If none of the devices match any of the given states,
|
||||
* an empty list will be returned.
|
||||
*
|
||||
* <p>This is not specific to any application configuration but represents
|
||||
* the connection state of the local Bluetooth adapter for this profile.
|
||||
* This can be used by applications like status bar which would just like
|
||||
* to know the state of the local adapter.
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param profile GATT or GATT_SERVER
|
||||
* @param states Array of states. States can be one of
|
||||
* {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING},
|
||||
* {@link BluetoothProfile#STATE_DISCONNECTED},
|
||||
* {@link BluetoothProfile#STATE_DISCONNECTING},
|
||||
* @return List of devices. The list will be empty on error.
|
||||
*/
|
||||
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int profile, int[] states) {
|
||||
if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates");
|
||||
|
||||
if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
|
||||
throw new IllegalArgumentException("Profile not supported: " + profile);
|
||||
}
|
||||
|
||||
List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
|
||||
|
||||
try {
|
||||
IBluetoothManager managerService = mAdapter.getBluetoothManager();
|
||||
IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt();
|
||||
if (iGatt == null) return devices;
|
||||
devices = iGatt.getDevicesMatchingConnectionStates(states);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a GATT Server
|
||||
* The callback is used to deliver results to Caller, such as connection status as well
|
||||
* as the results of any other GATT server operations.
|
||||
* The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
|
||||
* to conduct GATT server operations.
|
||||
* @param context App context
|
||||
* @param callback GATT server callback handler that will receive asynchronous callbacks.
|
||||
* @return BluetoothGattServer instance
|
||||
*/
|
||||
public BluetoothGattServer openGattServer(Context context,
|
||||
BluetoothGattServerCallback callback) {
|
||||
if (context == null || callback == null) {
|
||||
throw new IllegalArgumentException("null parameter: " + context + " " + callback);
|
||||
}
|
||||
|
||||
// TODO(Bluetooth) check whether platform support BLE
|
||||
// Do the check here or in GattServer?
|
||||
|
||||
try {
|
||||
IBluetoothManager managerService = mAdapter.getBluetoothManager();
|
||||
IBluetoothGatt iGatt = (IBluetoothGatt) managerService.getBluetoothGatt();
|
||||
if (iGatt == null) {
|
||||
Log.e(TAG, "Fail to get GATT Server connection");
|
||||
return null;
|
||||
}
|
||||
BluetoothGattServer mGattServer = new BluetoothGattServer(context, iGatt);
|
||||
Boolean regStatus = mGattServer.registerCallback(callback);
|
||||
return regStatus? mGattServer : null;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG,"",e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -89,13 +89,11 @@ public interface BluetoothProfile {
|
||||
|
||||
/**
|
||||
* GATT
|
||||
* @hide
|
||||
*/
|
||||
static public final int GATT = 7;
|
||||
|
||||
/**
|
||||
* GATT_SERVER
|
||||
* @hide
|
||||
*/
|
||||
static public final int GATT_SERVER = 8;
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
package android.bluetooth;
|
||||
|
||||
import android.bluetooth.IBluetooth;
|
||||
import android.bluetooth.IBluetoothGatt;
|
||||
import android.bluetooth.IBluetoothManagerCallback;
|
||||
import android.bluetooth.IBluetoothStateChangeCallback;
|
||||
|
||||
@ -35,6 +36,7 @@ interface IBluetoothManager
|
||||
boolean enable();
|
||||
boolean enableNoAutoConnect();
|
||||
boolean disable(boolean persist);
|
||||
IBluetoothGatt getBluetoothGatt();
|
||||
|
||||
String getAddress();
|
||||
String getName();
|
||||
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.IllegalFormatConversionException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Mutable variant of a Bluetooth Gatt Characteristic
|
||||
* @hide
|
||||
*/
|
||||
public class MutableBluetoothGattCharacteristic extends BluetoothGattCharacteristic {
|
||||
|
||||
/**
|
||||
* Create a new MutableBluetoothGattCharacteristic.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param uuid The UUID for this characteristic
|
||||
* @param properties Properties of this characteristic
|
||||
* @param permissions Permissions for this characteristic
|
||||
*/
|
||||
public MutableBluetoothGattCharacteristic(UUID uuid, int properties, int permissions) {
|
||||
super(null, uuid, 0, properties, permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a descriptor to this characteristic.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param descriptor Descriptor to be added to this characteristic.
|
||||
*/
|
||||
public void addDescriptor(MutableBluetoothGattDescriptor descriptor) {
|
||||
mDescriptors.add(descriptor);
|
||||
descriptor.setCharacteristic(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the desired key size.
|
||||
* @hide
|
||||
*/
|
||||
public void setKeySize(int keySize) {
|
||||
mKeySize = keySize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service associated with this device.
|
||||
* @hide
|
||||
*/
|
||||
/*package*/ void setService(BluetoothGattService service) {
|
||||
mService = service;
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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 java.util.UUID;
|
||||
|
||||
/**
|
||||
* Mutable variant of a Bluetooth Gatt Descriptor
|
||||
* @hide
|
||||
*/
|
||||
public class MutableBluetoothGattDescriptor extends BluetoothGattDescriptor {
|
||||
|
||||
/**
|
||||
* Create a new BluetoothGattDescriptor.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param uuid The UUID for this descriptor
|
||||
* @param permissions Permissions for this descriptor
|
||||
*/
|
||||
public MutableBluetoothGattDescriptor(UUID uuid, int permissions) {
|
||||
super(null, uuid, permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the back-reference to the associated characteristic
|
||||
* @hide
|
||||
*/
|
||||
/*package*/ void setCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
mCharacteristic = characteristic;
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* 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.bluetooth.BluetoothDevice;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a Bluetooth Gatt Service
|
||||
* @hide
|
||||
*/
|
||||
public class MutableBluetoothGattService extends BluetoothGattService {
|
||||
|
||||
/**
|
||||
* Create a new MutableBluetoothGattService.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param uuid The UUID for this service
|
||||
* @param serviceType The type of this service (primary/secondary)
|
||||
*/
|
||||
public MutableBluetoothGattService(UUID uuid, int serviceType) {
|
||||
super(uuid, serviceType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an included service to this service.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param service The service to be added
|
||||
* @return true, if the included service was added to the service
|
||||
*/
|
||||
public boolean addService(BluetoothGattService service) {
|
||||
mIncludedServices.add(service);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a characteristic to this service.
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
|
||||
*
|
||||
* @param characteristic The characteristics to be added
|
||||
* @return true, if the characteristic was added to the service
|
||||
*/
|
||||
public boolean addCharacteristic(MutableBluetoothGattCharacteristic characteristic) {
|
||||
mCharacteristics.add(characteristic);
|
||||
characteristic.setService(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the instance ID.
|
||||
* This is needed for conformance testing only.
|
||||
* @hide
|
||||
*/
|
||||
public void setInstanceId(int instanceId) {
|
||||
mInstanceId = instanceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the number of handles to reserve for this service.
|
||||
* This is needed for conformance testing only.
|
||||
* @hide
|
||||
*/
|
||||
public void setHandles(int handles) {
|
||||
mHandles = handles;
|
||||
}
|
||||
}
|
@ -2203,7 +2203,6 @@ public abstract class Context {
|
||||
* {@link android.bluetooth.BluetoothAdapter} for using Bluetooth.
|
||||
*
|
||||
* @see #getSystemService
|
||||
* @hide
|
||||
*/
|
||||
public static final String BLUETOOTH_SERVICE = "bluetooth";
|
||||
|
||||
|
@ -19,6 +19,7 @@ package com.android.server;
|
||||
import android.app.ActivityManager;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.IBluetooth;
|
||||
import android.bluetooth.IBluetoothGatt;
|
||||
import android.bluetooth.IBluetoothCallback;
|
||||
import android.bluetooth.IBluetoothManager;
|
||||
import android.bluetooth.IBluetoothManagerCallback;
|
||||
@ -87,6 +88,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
// and Airplane mode will have higher priority.
|
||||
private static final int BLUETOOTH_ON_AIRPLANE=2;
|
||||
|
||||
private static final int SERVICE_IBLUETOOTH = 1;
|
||||
private static final int SERVICE_IBLUETOOTHGATT = 2;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
// Locks are not provided for mName and mAddress.
|
||||
@ -97,6 +101,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
|
||||
private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
|
||||
private IBluetooth mBluetooth;
|
||||
private IBluetoothGatt mBluetoothGatt;
|
||||
private boolean mBinding;
|
||||
private boolean mUnbinding;
|
||||
// used inside handler thread
|
||||
@ -463,6 +468,11 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
public IBluetoothGatt getBluetoothGatt() {
|
||||
// sync protection
|
||||
return mBluetoothGatt;
|
||||
}
|
||||
|
||||
private void sendBluetoothStateCallback(boolean isUp) {
|
||||
int n = mStateChangeCallbacks.beginBroadcast();
|
||||
if (DBG) Log.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers.");
|
||||
@ -575,16 +585,35 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
}
|
||||
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
if (DBG) Log.d(TAG, "BluetoothServiceConnection: connected to AdapterService");
|
||||
if (DBG) Log.d(TAG, "BluetoothServiceConnection: " + className.getClassName());
|
||||
Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
|
||||
// TBD if (className.getClassName().equals(IBluetooth.class.getName())) {
|
||||
if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) {
|
||||
msg.arg1 = SERVICE_IBLUETOOTH;
|
||||
// } else if (className.getClassName().equals(IBluetoothGatt.class.getName())) {
|
||||
} else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) {
|
||||
msg.arg1 = SERVICE_IBLUETOOTHGATT;
|
||||
} else {
|
||||
Log.e(TAG, "Unknown service connected: " + className.getClassName());
|
||||
return;
|
||||
}
|
||||
msg.obj = service;
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
// Called if we unexpected disconnected.
|
||||
if (DBG) Log.d(TAG, "BluetoothServiceConnection: disconnected from AdapterService");
|
||||
if (DBG) Log.d(TAG, "BluetoothServiceConnection, disconnected: " +
|
||||
className.getClassName());
|
||||
Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED);
|
||||
if (className.getClassName().equals("com.android.bluetooth.btservice.AdapterService")) {
|
||||
msg.arg1 = SERVICE_IBLUETOOTH;
|
||||
} else if (className.getClassName().equals("com.android.bluetooth.gatt.GattService")) {
|
||||
msg.arg1 = SERVICE_IBLUETOOTHGATT;
|
||||
} else {
|
||||
Log.e(TAG, "Unknown service disconnected: " + className.getClassName());
|
||||
return;
|
||||
}
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
@ -746,13 +775,18 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
}
|
||||
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
|
||||
{
|
||||
if (DBG) Log.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED");
|
||||
|
||||
//Remove timeout
|
||||
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
|
||||
if (DBG) Log.d(TAG,"MESSAGE_BLUETOOTH_SERVICE_CONNECTED: " + msg.arg1);
|
||||
|
||||
IBinder service = (IBinder) msg.obj;
|
||||
synchronized(mConnection) {
|
||||
if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
|
||||
mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service);
|
||||
break;
|
||||
} // else must be SERVICE_IBLUETOOTH
|
||||
|
||||
//Remove timeout
|
||||
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
|
||||
|
||||
mBinding = false;
|
||||
mBluetooth = IBluetooth.Stub.asInterface(service);
|
||||
|
||||
@ -816,11 +850,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
}
|
||||
case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED:
|
||||
{
|
||||
Log.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED");
|
||||
Log.e(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED: " + msg.arg1);
|
||||
synchronized(mConnection) {
|
||||
// if service is unbinded already, do nothing and return
|
||||
if (mBluetooth == null) return;
|
||||
mBluetooth = null;
|
||||
if (msg.arg1 == SERVICE_IBLUETOOTH) {
|
||||
// if service is unbinded already, do nothing and return
|
||||
if (mBluetooth == null) break;
|
||||
mBluetooth = null;
|
||||
} else if (msg.arg1 == SERVICE_IBLUETOOTHGATT) {
|
||||
mBluetoothGatt = null;
|
||||
break;
|
||||
} else {
|
||||
Log.e(TAG, "Bad msg.arg1: " + msg.arg1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mEnable) {
|
||||
@ -1048,10 +1090,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
|
||||
boolean isUp = (newState==BluetoothAdapter.STATE_ON);
|
||||
sendBluetoothStateCallback(isUp);
|
||||
|
||||
//If Bluetooth is off, send service down event to proxy objects, and unbind
|
||||
if (!isUp && canUnbindBluetoothService()) {
|
||||
sendBluetoothServiceDownCallback();
|
||||
unbindAndFinish();
|
||||
if (isUp) {
|
||||
// connect to GattService
|
||||
Intent i = new Intent(IBluetoothGatt.class.getName());
|
||||
if (!mContext.bindServiceAsUser(i, mConnection, Context.BIND_AUTO_CREATE,
|
||||
UserHandle.CURRENT)) {
|
||||
Log.e(TAG, "Fail to bind to: " + IBluetoothGatt.class.getName());
|
||||
}
|
||||
} else {
|
||||
//If Bluetooth is off, send service down event to proxy objects, and unbind
|
||||
if (!isUp && canUnbindBluetoothService()) {
|
||||
sendBluetoothServiceDownCallback();
|
||||
unbindAndFinish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user