Tutorial for Android

Contents

Overview

Coordinate system

In GemSDK we use left-handed local coordinate system (fig. above).

GemSDK features:

Start with GemSDK

To begin with: Link to our Api Reference

For quick configuration please download our utility from Google Play Market or apk. With it you can configure Gems list to use and access if from your app.

Add your Gem or Gems to the white list like so (make sure that Gem is really close to the Android device):

Set up your gem

Next step is getting the GemSDK library to your project via Gradle:

project build.gradle:

repositories {
    ...
    maven { url 'https://raw.github.com/Gemsense/GemSDK-for-Android/mvn-repo' }
}

module build.gradle:

dependencies {
    ...
    compile 'com.gemsense:gemsdk:1.1.2'
}

GemSDK library contains Android service that runs in its own thread and responsible for communication, our API and additional algorithms.

Basic operations with the service:

@Override
protected void onResume() {
    super.onResume();
    //Bind the Gem Service to the app
    GemManager.getDefault().bindService(this);
}

@Override
protected void onPause() {
    super.onPause();
    //Unbind Gem Service from the application
    GemManager.getDefault().unbindService(this);
}

Connecting to the Gem:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    //Get white list of addresses form the utility app
    String[] whitelist = GemSDKUtilityApp.getWhiteList((Context)this);

    if(whitelist.length > 0) {
        //Get Gem by MAC-address
        gem = GemManager.getDefault().getGem(whitelist[0], gemListener);
    }
}

Disconnecting:

GemManager.getDefault().releaseGem(gem);

If the Gem wasn’t disconnected manually before unbinding the service, the service will keep connection for 10 sec.

Receiving data

The data streaming will start directly after connection to the Gem. Just implement the callback to pass to getGem() func:

private GemListener gemListener = new GemListener() {
    @Override
    public void onStateChanged(int state) {
        //States handling
        switch (state) {
            case Gem.STATE_CONNECTED:
                Log.d("GemDemo", "Connected to a gem");
                break;
            case Gem.STATE_DISCONNECTED:
                Log.d("GemDemo", "Gem was disconnected");
                break;
        }
    }

    @Override
    public void onSensorsChanged(GemSensorsData data) {
        float[] q = data.quaternion; // w x y z
        float[] a = data.acceleration;
        ...
    }

    @Override
    public void onErrorOccurred(int errCode) {
        //Gem not found
        if(errCode == Gem.ERR_CONNECTING_TIMEOUT) {
            Toast.makeText(MainActivity.this, "Gem device not found", Toast.LENGTH_SHORT).show();
        }
    }
};

Calibration

To consider current azimuth(yaw) angle as zero for curtain Gem just use

gem.calibrateAzimuth();

And to make rotation completely relative to current rotation use

gem.calibrateOrigin();

Handling taps

Handling tap events is also pretty easy:

gem.setTapListener(new OnTapListener() {
    @Override
    public void onTap(TapData tapData) {
        Log.i("GemDemo", "Tap!");
    }
});

Pedometer

To use pedometer set up the callback:

gem.setPedometerListener(new OnPedometerListener() {
    @Override
    public void OnPedometerUpdate(PedometerData pedometerData) {
        Log.i("GemDemo", "Steps:" + pedometerData.steps);
    }
});

And activate it in Gem’s general callback :

@Override        
public void onStateChanged(int state) {      
    if(state == Gem.STATE_CONNECTED) {       
        //Turn pedometer notifications on        
        gem.setPedometerActive(true);        
     }       
}

Using multiple gems

You can call easily use multiple gems (as much as your Android device can handle)

gem1 = GemManager.getDefault().getGem(whitelist[0], gemListener1);
gem2 = GemManager.getDefault().getGem(whitelist[1], gemListener2);

Scanning gems (Advanced)

To your own way of building Gem white list inside your app we provide API for scanning Gems around.

Create scanner class instance and specify its callback:

scanner = new GemScanner(new GemScanListener() {
    @Override
    public void onScanFinish() {
        //Your code here
    }

    @Override
    public void onDeviceDiscovered(final BluetoothDevice device, int rssi) 
    {
        Log.i("GemDemo", "Gem found: " + device.getAddress());
    }
});

Then you can start scanning:

//scanning by default lasts in 25 sec
scanner.scan();
//or specify this time manually
scanner.start(15); //15 sec

Scan process can be stopped earlier:

scanner.stop();  

NOTE: For Android 6 requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permissions

Over-the-Air updating (Advanced)

Currently API is not available. Bur you can update your Gems via Gem SDK Utility for Android mentioned above

Gesture recognition

GemSDK contains gesture recognition library. Check out
Api Reference and corresponding sample project.

Samples

To get sample projects check out our Github page

Android apps that were made with our Unity plugin are available here