Android

Getting started

Example App Source Code

You can find a sample App implementation of the SDK here

For the sample App you need to provide a base url, an OAuth-Token and a ssl certificate. All informations can be found here

ToDo for the sample App:

  • BookingManager - get Schedules of a unit
  • BookingManager - end Booking now
  • BookingManager - delete a Booking

JavaDoc

For detailed description of the SDK methodes you can find the JavaDocs here

Installation

Grab the latest SDK via Gradle:

implementation 'com.sensorberg.smartworkspace:sdk:VERSION'

to let Gradle download the SDK from our servers. You can find the latest VERSION on our Maven Repository. You also need to create a global gradle.properties file in USER_HOME/.gradle/

MAVEN_URL=http://maven.sensorberg.io/artifactory/smart-workspaces/
MAVEN_USERNAME=<username>
MAVEN_PASSWORD=<password>

replace <username> and <password> with the credentials provided by us.

To setup the maven repository in your app you have to open the build.gradle file of your app module (not the root) and add the following snippet:

repositories {
    maven {
        url MAVEN_URL
        credentials {
            username = MAVEN_USERNAME
            password = MAVEN_PASSWORD
        }
    }
}

Because of the changes and improvements of the Bluetooth API and BLE with Android 5.0 the Android minSdkVersion for our SDK is 21. So your project needs to set the minSdkVersion also to 21 or higher.

SDK Initialization

Use the SmartWorkspaceSdk.Builder to initialize the SDK

Kotlin
val sdk = SmartWorkspaceSdk.Builder(this)
            .baseUrl(BASE_URL)
            .oauthId(OAUTH_TOKEN)
            .certificate(CERTIFICATE)
            .build()
Java

You need to provide the BASE_URL of the server, the OAUTH_TOKEN to authenticate the app at the server and the SSL certificate CERTIFICATE of the server. All this information will be provided by us.

As of LiveData is the new way in Android to have lifecycle safe operations, our SDK is using LiveData. If you are not familiar with LiveData please visit the Android Developers Guide

If you like you can also view the JavaDocs to get an overview of all included methods.

Permissions

Following permissions will be merged to your projects AndroidManifest.xml automagicaly by Gradle

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

The only thing you have to do is to ask the user for location permission to use the SDK.

Logging

We are using Timber for logging in our SDK (See Timber GitHub). If you want to see the logging of the SDK use Timber and add an Timber.Tree to enable logging.

Kotlin
Timber.plant(object : Timber.Tree() {
    override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
        Log.d("DEBUG", message)
    }
})
Java

Operation Result

Instead of callbacks for operations we are using Android LiveData. Any operation which you can call with the SDK will return a LiveData<T> object which can be observed for the result of the operation. For simple operations like login or open the SDK returns a LiveData<OperationResult> which can be OperationSuccess or OperationFail. To observe this object you can see an example in the code below

Kotlin
//do some operation and get the LiveData<OperationResult> object
//after that observe the object for the result
operationResult.observe(this, Observer { operationResult ->
    when (operationResult) {
        is OperationSuccess -> //the operation was successful
        is OperationFail -> //the operation failed
    }
})
Java

Observe the SDK State

The SDK has a state which you can observe at any time to get the current state of the SDK. To do so see the following code:

Kotlin
sdk.getStatus().observe(this, Observer<SmartWorkspaceStatus> {
            when(it){
                is SmartWorkspaceSdk.Status.NotLoggedIn -> Log.d("DEBUG", "not logged in")
                is SmartWorkspaceSdk.Status.LoggingOut -> Log.d("DEBUG", "logging out")
                is SmartWorkspaceSdk.Status.NotAuthorized -> Log.d("DEBUG", "not authorized")
                is SmartWorkspaceSdk.Status.Initializing -> Log.d("DEBUG", "Initializing")
                is SmartWorkspaceSdk.Status.InitializingFail -> Log.d("DEBUG", "initializing failed")
                is SmartWorkspaceSdk.Status.Ready -> Log.d("DEBUG", "Ready")
                null -> Log.d("DEBUG", "should not happen")
            }
        })
Java

Login

The SDK provides 3 different types of login for the user

  • Username and Password
  • OAuth2
  • external Token Login

After initialization the state of the SDK is SmartWorkspaceSdk.Status.NotLoggedIn

Login via username and password

When running the login request for login with username and password the state of the SDK will switch to SmartWorkspaceSdk.Status.Initializing and after login was successful the state jumps to SmartWorkspaceSdk.Status.Ready.

Kotlin
val result = sdk.usernamePasswordLogin(username, password)
result.observe(this, Observer { result ->
    when (result) {
        is OperationSuccess -> //the operation was successful
        is OperationFail -> //the operation failed
    }
})
Java

For failing login see Login failed

Login via OAuth2

To login with OAuth2 you have to do the login in an external webview. The URL to call for the external url consists of the BASE_URL + /auth/ + OAUTH_ID

Kotlin

val uri = Uri.parse("${baseUrl}/auth/${oauthId}")
CustomTabsIntent.Builder()
    .setToolbarColor(activity.resources.getColor(R.color.colorSecondary)).build()
    .launchUrl(activity, uri)

Java

We recomment to use the CustomTabsIntent class of Android. This is the new seamless way to open a browser tab within your app context. To use the CustomTabsIntent you have to add implementation "com.android.support:customtabs:27.1.1" as a dependency into your build.gradle file

After the login succeeded you will receive the redirectedUrl to login to the SDK

Kotlin
val result = sdk.oAuth2Login(redirectedUrl)
result.observe(this, Observer { result ->
    when (result) {
        is OperationSuccess -> //the operation was successful
        is OperationFail -> //the operation failed
    }
})
Java

Login using external Token

To login the user using server-to-server pre-shared authentication token your backend has to register a token for the user on the Smart Workspace Server and provide it to the following method.

Kotlin
val result = sdk.externalTokenLogin(authToken)
result.observe(this, Observer { result ->
    when (result) {
        is OperationSuccess -> //the operation was successful
        is OperationFail -> //the operation failed
    }
})
Java

Login failed

If the login failed the state of the SDK will be SmartWorkspaceSdk.Status.NotAuthorized and then SmartWorkspaceSdk.Status.NotLoggedIn for all login variations. SmartWorkspaceSdk.Status.NotAuthorized also has a message string with the explanation, why the authorization failed.

Logout

To logout a user simply call:

val result = sdk.logout()
result.observe(this, Observer { result ->
    when (result) {
        is OperationSuccess -> //the operation was successful
        is OperationFail -> //the operation failed
    }
})
Java

Change password

You can only change the password, if you are using login via username and password

You can change the password of a logged in user, like in the following example:

Kotlin
val result = sdk.changePassword(oldPassword, newPassword, newPasswordConfirm)
result.observe(this, Observer { result ->
    when (result) {
        is OperationSuccess -> //the operation was successful
        is OperationFail -> //the operation failed
    }
})
Java

The method changePassword() will return a LiveData object to observe the OperationResult.

Get user information

To get all available user information (f.e. email, firstname, lastname, salutation) use the following code

Kotlin
val user = sdk.getMe()
user.observe(this, Observer { user ->
    user?.let {
        //do something
    }
})
Java

The Unit Controller

The UnitController is the controller class to control any operation with a Unit. A unit can be any IoT device to interact with, like doors or lockers etc.

To receive a controller from the SDK call

Kotlin / Java
sdk.getUnitController()

Get Units from the controller

After you received a UnitController you can ask for available units or for nearby units. You either receive a list of units of specific type or you can receive a list with all kind of types of units.

In the example below we are receiving all available units of type DOOR which the user is allowed to open:

Kotlin
val unitController = sdk.getUnitController()
val availableUnits = unitController.getAvailableUnits(IotUnit.Type.DOOR)
availableUnits.observe(this, Observer { units ->
    units?.let {
        //do something
    }
})
Java

If you call unitController.getNearbyUnits(...) the returned observable will be called each time the scan of the nearby devices is finished.

Opening a Unit

With the UnitController you also can open a unit. To open a unit you just call

Kotlin
val result = unitController.open(unit)
result.observe(this, Observer { result ->
    when (result) {
        is OperationSuccess -> //the operation was successful
        is OperationFail -> //the operation failed
    }
})
Java

The OperationResult returned by this method will be updated with state SUCCESS if the opening succeeded or FAILED if the opening failed for some reason.

The open operation has no timeout and will try to find and open the unit device forever. If you want to cancel this operation just call unitController.cancel()

If your App does not have the permission to access location, nothing will happen if you call unitController.open(unit). The state of unitController.getStatus() will be NoLocationPermission

The Booking Manager

With the BookingManager you are able to create bookings of a room or a locker, delete bookings which are not started yet or end currently ongoing bookings.

To receive the BookingManager from the SDK call

Kotlin / Java
sdk.getBookingManager()

Create a booking

To create a booking for a unit call

Kotlin
val result = bookingManager.createBooking(unit, startsAt, endsAt)
result.observe(this, Observer { result ->
    when (result) {
        is OperationSuccess -> //the operation was successful
        is OperationFail -> //the operation failed
    }
})
Java

where unit is the unit you want to book, startAt is the time in milliseconds when the booking should start at and the optional endAt if the booking is not open end and have to end at some point.

Delete a booking

To delete a booking call bookingManager.deleteBooking(booking) and the given booking will be deleted. Deleting a booking will remove it from the backend.

val result = bookingManager.deleteBooking(booking)
result.observe(this, Observer { operationResult ->
    when (operationResult) {
        is OperationSuccess -> doSomething()
        is OperationFail -> doSomething()
    }
})
Java

End a booking (now)

To end a booking while it is ongoing, call bookingManager.endBookingNow(booking) and the ongoing booking will be ended.

Ending a booking will only update the booking to end at current time (now), this will not delete the booking.

Kotlin
val result = bookingManager.endBookingNow(booking)
result.observe(this, Observer { operationResult ->
    when (operationResult) {
        is OperationSuccess -> doSomething()
        is OperationFail -> doSomething()
    }
})
Java

Get my bookings

To get all bookings of the user call bookingManager.getMyBookings()

Kotlin
val myBookings = bookingManager.getMyBookings()
myBookings.observe(this, Observer { myBookings ->
    myBookings?.let {
        //do something
    }
})
Java

This returns a list of bookings.

Get Schedules

Call bookingManager.getSchedules(localDateFrom, localDateTo, iotUnit) to get a list of schedules for the given iotUnit, or if null, for all IotUnits the user has access to in the requested period.

Kotlin
val schedules = bookingManager.getSchedules(localDateFrom, localDateTo, iotUnit)
schedules.observe(this, Observer { schedules ->
    schedules?.let {
        //do something
    }
})
Java

the schedule object contains a list of TimePeriod with the periods when the provided iotUnit is already booked.