Skip to content

iobeam/iobeam-client-java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

iobeam Java / Android Library

iobeam is a data platform for connected devices.

This is a Java library for sending data to iobeam, e.g., from within an Android app. For more information on iobeam, please read our full API documentation.

Please note that we are currently invite-only. You will need an invite to generate a valid token and use our APIs. (Sign up here for an invite.)

Sample apps

We've written a couple sample Android apps to illustrate how to use this library:

  1. Android Battery Data App - Basic example that tracks the current battery level on your phone. Every time the battery level changes by more than 1%, the app uploads the timestamp and current level to iobeam.

  2. Android WiFi RSSI App - Slightly more advanced example that uses Callbacks. Measures the signal strength of the WiFi on your phone using RSSI (received signal strength indicator). Measurements are taken every 20 seconds, and are uploaded to iobeam in batches of 3 or more measurements.

Before you start

Before you can start sending data to iobeam, you'll need a project_id and project_token (with write-access enabled) for a valid iobeam account. You can get these easily with our Command-line interface tool.

Installation

To install to your local Maven repository:

git clone https://github.com/iobeam/iobeam-client-java.git
cd iobeam-client-java
mvn install

It will be installed as artifact iobeam-client-java under the group com.iobeam.

If you are building an Android app, add the following lines to your app/build.gradle file:

repositories {
    ...
    mavenLocal()
    mavenCentral()
}

dependencies {
    ...
    compile('com.iobeam:iobeam-client-java:0.6.1') {
        exclude module: 'json'
    }
}

It is also available on Maven Central.

Overview

This library allows Java clients to send data to iobeam.

At a high-level, here's how it works:

  1. Initialize an Iobeam object with your project_id and project_token

  2. Register your device to get an auto-generated device_id. Optionally, you can initialize the object with a device_id in the previous step and skip this step

  3. Create a DataStore for storing data by streams, which will be tracked by the Iobeam object.

  4. Add data values to the DataStore as you get them.

  5. When you're ready, send your data to iobeam.

Getting Started

Here's how to get started, using a basic example that sends temperature data to iobeam. (For simplicity, let's assume that the current temperature can be accessed with getTemperature()).

(Reminder: Before you start, create a user account, project, and project_token (with write access) using the iobeam APIs or Command-line interface. Write down your new project_id and project_token.)

iobeam Initialization

There are several ways to initialize the Iobeam library. All require that you have project_id and project_token before hand.

Without a registered device_id

If you have not previously registered a device_id with iobeam, either via the CLI or our website, you will need to register one in code. There are two ways to register a device_id:

(1) Let iobeam generate one for you:

Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN).saveIdToPath(PATH).build();
iobeam.registerDeviceAsync();

(2) Provide your own (must be unique to your project):

Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN).saveIdToPath(PATH).build();
iobeam.registerDeviceAsync("my_desired_device_id");

The device_id will be saved to disk at the path PATH. On Android, this would be set to something like this.getFilesDir().getAbsolutePath() , which is internal storage for applications. On future calls, this on-disk storage will be read first. If a device_id exists, the registerDeviceAsync() will do nothing; otherwise, it will get a new random ID from us. If you provide a different device_id to registerDeviceWithIdAsync(), the old one will be replaced.

With a registered device_id

If you have registered a device_id (e.g. using our CLI), you can pass this in the constructor and skip the registration step.

Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN).saveIdToPath(PATH)
    .setDeviceId(DEVICE_ID).build();

You must have registered some other way (CLI, website, previous installation, etc) for this to work.

Advanced: not saving to disk

If you don't want the device_id to be automatically stored for you, set the path parameter in either constructor to be null:

// Without registered id:
Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN).build();

// With registered id:
Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN)
    .setDeviceId(DEVICE_ID).build();

This is useful for cases where you want to persist the ID yourself (e.g. in a settings file), or if you are making Iobeam objects that are temporary. For example, if the device you are using acts as a relay or proxy for other devices, it could get the device_id from those devices and have no need to save it.

Tracking Time-series Data

To track time-series data, you need to decide how to break down your data streams into "stores", a collection of data streams grouped together. You create a DataStore with a list of stream names that the store contains. So if you're tracking just temperature in a store:

DataStore store = iobeam.createDataStore(new String[]{"temperature"});

By doing this, the iobeam client now knows about your DataStore (it is "tracking" it), and each subsequent call to send data will include any new data from this DataStore. So, for every data point, you'll want to add it to the store with a timestamp when the measurement occurred:

long timestamp = System.currentTimeMillis();
store.add(timestamp, new String[]{"temperature"}, new Object[]{getTemperature()});

// Or, to just use the current timestamp:
store.add(new String[]{"temperature"}, new Object[]{getTemperature()});

You pass in the values keyed by which column they belong to. In the above format you do that by providing an array of column names and an equal size Object array of corresponding values. You can create a Map that maps columns/streams to values:

Map<String, Object> values = new HashMap<String, Object>();
values.put("temperature", getTemperature());
store.add(values);

Note that the DataStore object can hold several streams at once. For example, if you also had a getHumidity() function, you could track both in the same DataStore:

String[] columns = new String[]{"temperature", "humidity"};
DataStore store = iobeam.createDataStore(columns);

Object[] values = new Object[2];
values[0] = getTemperature();
values[1] = getHumidity();
store.add(columns, values);

Not every add() call needs all streams to have a value; if a stream is omitted from both arrays (or from the keys of a Map), it will be assumed to be null.

Connecting to iobeam

You can send your data to iobeam in two ways: synchronously and asynchronously:

iobeam.send(); // blocking
iobeam.sendAsync(); // non-blocking

Exceptions & Handling

If there are problems with the data as provided to either register() or send() (and their async variants), an ApiException is thrown. These problems include unrecoverable issues like incorrect project ID or device ID, invalid data, etc. IOException is thrown in the case of network connectivity issues. As a user of the library, you should be aware of these errors and handle them appropriately (e.g. catching them, logging, etc.).

Full Example

Here's the full source code for our example:

// Initialization
Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN)
    .saveIdToPath(PATH)
    .build();

if (iobeam.getDeviceId() == null) {
    iobeam.registerDeviceAsync(); // Registers using auto-generated device_id
}

...

// Data gathering
String[] columns = new String[]{"temperature", "humidity"};
DataStore store = iobeam.createDataStore(columns);

Object[] values = new Object[2];
values[0] = getTemperature();
values[1] = getHumidity();
store.add(columns, values);

...

// Data transmission
iobeam.sendAsync();

These instructions should hopefully be enough to get you started with the library!