Skip to content

Commit

Permalink
[RELEASE] v1.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
MGasztold committed Dec 29, 2017
1 parent 53a6d58 commit 163309c
Show file tree
Hide file tree
Showing 12 changed files with 384 additions and 652 deletions.
162 changes: 91 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Android-IoT-SDK

This SDK is dedicated for handling discovery, connection and two way communication with a BLE device.
SDK also provides API to make mobile device act like a connectable BLE device.
This SDK is dedicated for handling discovery, connection and two way communication with a Bluetooth LE device.
SDK also provides API to make mobile device act like a connectable Bluetooth LE device.

## Installing

Expand All @@ -14,35 +14,34 @@ Add Ubudu nexus repository url to your `build.gradle` file:

Then add the following dependency:

dependencies {
compile('com.ubudu.iot:iot-sdk:1.4.1@aar')
// ...
}
compile('com.ubudu.iot:iot-sdk:1.5.0@aar')

## How to use?

### BLE discovery
### Bluetooth LE discovery

Create an object implementing the `DongleFilter` interface. This interface is used to let the `DongleManager` class pick the desired device from all detectable devices nearby.:
Create an object implementing the `BleDeviceFilter` interface. This interface is used to let
the `DiscoveryManager` class pick the desired device from all devices being detected nearby.:

BleDeviceFilter dongleFilter = new BleDeviceFilter() {
BleDeviceFilter bleDeviceFilter = new BleDeviceFilter() {
@Override
public boolean isCorrect(BluetoothDevice device, int rssi, byte[] scanResponse) {
// example implementation:
return device.getName() != null && device.getName().equals("MyDongle");
}
};

**NOTE:** At this point on Android N `scanResponse` is always `null`.

Then to discover a dongle:
Then to discover a Bluetooth LE device:

DongleManager.findDongle(mContext, 5000, dongleFilter, new DongleManager.DiscoveryListener() {
DiscoveryManager.discover(mContext, 5000, bleDeviceFilter, new DiscoveryManager.DiscoveryListener() {

@Override
public boolean onDongleFound(Dongle dongle) {
// matching dongle found
mDongle = dongle;
public boolean onBleDeviceFound(BleDevice bleDevice) {
// ble device that matches the given bfound
mBleDevice = bleDevice;
// Returning true will stop the BLE device scanner immediately.
// Returning false will make scanning last according to
// given duration or until stop() is called.
return true;
}

Expand All @@ -64,18 +63,18 @@ Then to discover a dongle:

The flow of discovery is as follows:

- discovery lasts for the amount of milliseconds specified in the argument of `DongleManager.findDongle` method,
- discovery lasts for the amount of milliseconds specified in the argument of `DiscoveryManager.discover` method,

- during this time all detected BLE devices matching the given `BleDeviceFilter` implementation are returned in the `onDongleFound` method,
- during this time all detected Bluetooth LE devices matching the given `BleDeviceFilter` implementation are returned in the `onBleDeviceFound` callback,

- if at some point the `onDongleFound` returns `true`, the discovery will be stopped immediately.
- if at some point the `onBleDeviceFound` implementation returns `true`, the discovery will be stopped immediately.


### BLE connection
### Bluetooth LE connection

Then to connect to the BLE device call the following:

mDongle.connect(mContext, new BleDevice.ConnectionListener() {
mBleDevice.connect(mContext, new BleDevice.ConnectionListener() {
@Override
public void onConnected() {
// connected to dongle
Expand All @@ -95,68 +94,81 @@ Then to connect to the BLE device call the following:

To disconnect from the device please call:

mDongle.disconnect();
mBleDevice.disconnect();

### BLE communication
### Bluetooth LE communication

Before communicating with the BLE device its BLE services have to be discovered:
Before communicating with the device its Bluetooth GATT services have to be discovered:

mDongle.discoverServices(new BleDevice.ServicesDiscoveryListener() {
@Override
public void onServicesDiscovered(List<BluetoothGattService> services) {
// services found
}

@Override
public void onError(Error error) {
// error
}
});
mBleDevice.discoverServices(new BleDevice.ServicesDiscoveryListener() {
@Override
public void onServicesDiscovered(List<BluetoothGattService> services) {
// services found
}
@Override
public void onError(Error error) {
// error
}
});

With the BLE services of the device discovered it is possible to establish a 2 way communication channel.
In order to do this one GATT characteristic with WRITE permission and one with NOTIFICATIONS
permission have to be chosen. It is possible to set single GATT characteristic for both purposes:
With the Bluetooth LE services of the device discovered it is possible to establish a 2 way
communication channel:

mDongle.setGattCharacteristicForWriting(characteristic);

dongle.registerForNotifications(characteristic, new BleDevice.RegisterForNotificationsListener() {
@Override
public void onRegistered(BluetoothGattCharacteristic characteristic) {
// success
}

@Override
public void onError(Error error) {
// error
}
});
1) In order to be able to receive data from Bluetooth LE device one of the GATT characteristics
available within one of the services should have `BluetoothGattCharacteristic.PROPERTY_NOTIFY` property.
2) In order to be able to send data to Bluetooth LE device one of the GATT characteristics
available within one of the services should have `BluetoothGattCharacteristic.PROPERTY_WRITE` or
`BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE` property.

It is possible to use single GATT characteristic for both purposes if device provides such characteristic.

mBleDevice.registerForNotifications(characteristic, new BleDevice.RegisterForNotificationsListener() {
@Override
public void onRegistered(BluetoothGattCharacteristic gattCharacteristic) {
// success
}

@Override
public void onError(Error error) {
// error
}
});

Data being received from the Bleutooth LE device is received by the listener interface that has to be set:

mDongle.setDataReceivedEventListener(new BleDevice.ReceiveDataEventListener() {
@Override
public void onDataReceived(byte[] data) {
// data received from dongle
}
});
mBleDevice.setDataReceivedEventListener(new DataListener() {
@Override
public void onDataReceived(byte[] data) {
// data received from the device
}
});

Now when 2 way communication is set up the app can send data to the BLE device:
The `DataListener` can be set any time before registering for notifications, e.g. right after successful connection.


To send data to the Bleutooth LE device:

String message = "My message.";
mDongle.send(message.getBytes(), new BleDevice.SendDataEventListener() {
@Override
public void onDataSent(byte[] data) {
// data sent
}
@Override
public void onCommunicationError(Error error) {
// communication error
}
mBleDevice.send(message.getBytes(), gattCharacteristic);

To be notified about the result of sending the data a `DataSentListener` implementation must be set on the `BleDevice` instance:

mBleDevice.setDataSentListener(new DataSentListener() {
@Override
public void onDataSent(byte[] data) {
// data sent successfuly
}
@Override
public void onError(Error error) {
// error
}
});

### Make mobile device act as a connectable BLE device
### Make mobile device act as a connectable Bluetooth LE device

To make that happen the following code should be called to setup the `BluetoothGattServer`:
To make that happen the Bluetooth GATT server has to be opened. The following code configures it:

peripheralManager = new PeripheralManager(mContext, new DeviceProfile() {

Expand Down Expand Up @@ -207,6 +219,8 @@ To make that happen the following code should be called to setup the `BluetoothG
}
});

To open the Bluetooth GATT server:

peripheralManager.openGattServer();

To stop the device from being a connectable peripheral:
Expand Down Expand Up @@ -243,4 +257,10 @@ Start advertising as IBeacon:

To stop advertising at any time call the following:

advertiser.stopAdvertising();
advertiser.stopAdvertising();

Foreign Bluetooth LE device can register for notifications to the read characteristic specified in `getReadCharacteristicUuid` method being a `DeviceProfile` implementation. If mobile device acting as peripheral wants to write some data to the foreign device then this read characteristic must be written. It is done when the following method is used:

peripheralManager.writeData(data);

The data received from the foreign device will trigger a `onCharacteristicWritten` callback of the given `PeripheralManager.PeripheralListener` instance.
10 changes: 3 additions & 7 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ buildscript {
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply plugin: 'android-apt'

repositories {
Expand All @@ -23,8 +22,8 @@ android {
applicationId "com.ubudu.iot.sample"
minSdkVersion 18
targetSdkVersion 26
versionCode 24
versionName "1.6"
versionCode 25
versionName "1.7"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand All @@ -49,15 +48,12 @@ dependencies {
compile 'com.jakewharton:butterknife:8.5.1'
apt 'com.jakewharton:butterknife-compiler:8.5.1'

compile('com.ubudu.iot:iot-sdk:1.4.1@aar')
compile('com.ubudu.iot:iot-sdk:1.5.0@aar')

compile 'com.afollestad.material-dialogs:core:0.9.4.7'

//slider
compile 'org.adw.library:discrete-seekbar:1.0.1'
compile('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
transitive = true;
}

compile 'com.wang.avi:library:2.1.3'
}
3 changes: 0 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
</intent-filter>
</activity>

<meta-data
android:name="io.fabric.ApiKey"
android:value="551ba6a2fe2a419c46b411612399179d86820e30" />
</application>

</manifest>
Loading

0 comments on commit 163309c

Please sign in to comment.