Provider

For native applications, a convenience AAR library is available to access the provider information directly without the complexity of implementing your own content provider code. This library contains a static class LauncherProviderHelper with functions to access configuration or session data.

Using this provider, applications will have the ability to access the current session from the Launcher to get information about the current logged-in user and the store information, configuration, etc.

LauncherProvider method

A wrapper class for the above content provider access is provided using an aar library, to simplify access to the session information. Typically, you should try to retrieve the session information in the on-resume of your application’s activity, so you can take action or re-authenticate if the session is invalid.

Example Java Code

Gradle

// in your project's build.gradle file:
dependencies {
    ...
    compile(name: 'launcherprovider-x.x.x, ext:'aar')
    ...
}

Code

In your java class:

import com.bluefletch.launcher.provider.LauncherProvider;
import com.bluefletch.launcher.provider.SessionInformation;

...
public class SampleActivity extends Activity {

  LauncherProvider mProvider;
  ...

  // in this example, getProviderInfo is the local method used to retrieve the
  // current session information
  protected void getProviderInfo() {
    Session sessionInfo = mProvider.getSession();

    // all fields should be present. If group is “*” then there is no
    // logged in session so the app should handle accordingly.

    String userId = sessionInfo.getUserId();
    String userName = sessionInfo.getUserName();
    String group = sessionInfo.getGroup();

    // extended attributes. Actual keys defined by the keys defined
    // in the LoginActivity.
    HashMap<String, String> ea = mProvider.getExtendedAttributes();
    String storeNumber = ea.get("storeId");
    String storeName = ea.get("storeName");

  }

Example Cordova Plugin

Install the Cordova Plugin for accessing Content Providers:

cordova plugin add com.phearme.cordovaplugin.contentproviderplugin

Using the content provider of com.bluefletch.launcherprovider, use this Javascript to get session information:


if (window.plugins && window.plugins.contentproviderplugin) {
    window.plugins.contentproviderplugin.query({
        contentUri: "content://com.bluefletch.launcherprovider/session",
        projection: ["data"],
        selection: null,
        selectionArgs: null,
        sortOrder: null
    }, function (data) {
        console.log('session data is:', data);
        var sessionData = {};
        if (data.length > 0) {
            sessionData = JSON.parse(data[0]["DATA"]);
        }
        // get the user id
        var userid = sessionData.userId;
        var username = sessionData.userName;
        var groups = sessionData.groups;
        var extendedAttrs = JSON.parse(sessionData.extendedAttributes);
        var extAttrAccessToken = extendedAttrs.accessToken;

    }, function (err) {
        // use default
        console.log('session error:', err);
    });
}

Example React Native

Reference

https://facebook.github.io/react-native/docs/native-modules-android

High Level

  1. Android: Update the project with the following:
    • Include the AAR for Launcher Provider
    • Update the Gradle file to include Launcher Provider AAR
    • Include React Bridge Code
    • Update Main Application to include React Bridge Code
  2. React Code
    • Include the Launcher Exported Javascript

Steps in detail

Android

AAR: Within the project tree, under “app” folder, create a folder named “libs”. Place the ​launcherProvider-x.x.x.aar ​within the libs directory.

Gradle: Include a reference to the library within the application build.gradle by adding the following to the dependency list:

implementation(​name​: ​'launcherProvider-x.x.x'​, ​ext​: ​'aar'​, ​version​: ​'x.x.x'​)

Ensure your Project build.gradle allows pulling from the libs directory by adding the Flat Directory to the repositories list

allprojects {
    repositories {
        mavenLocal()
        google()
        jcenter()
        maven {
            ​// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            u​rl​"​$rootDir​/../node_modules/react-native/android" ​
        }
        flatDir {
            dirs ​'libs' ​//this way we can find the .aar files in libs folder
        }
    ​}
}

Bridge code:

Within MainApplication, create an instance of 'LauncherSessionPackage'

@Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),

          new LauncherSessionPackage()
      );
    }

LauncherSessionPackage

LauncherSessionPackage defines the package interface.

public class LauncherSessionPackage implements ReactPackage {

    @Nonnull
    @Override
    public List<ViewManager> createViewManagers(@Nonnull ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<NativeModule> createNativeModules( ReactApplicationContext reactContext ) {

        List<NativeModule> modules = new ArrayList<>();

        modules.add( new LauncherSessionProvider(reactContext) );

        return modules;
    }

}

LauncherSessionProvider

LauncherSessionProvider is the code that talks to Launcher to get the Session contents. The main method within the LauncherSessionProvider is ‘getSession’.

import com.bluefletch.launcherprovider.LauncherProviderHelper;
import com.bluefletch.launcherprovider.Session;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;

import javax.annotation.Nonnull;

public class LauncherSessionProvider extends ReactContextBaseJavaModule {

    private class ExposedSession extends Object {

    };

    public LauncherSessionProvider(@Nonnull ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Nonnull
    @Override
    public String getName() {
        return "LauncherSessionProvider";
    }


    @ReactMethod
    public void getSession(Callback sessionCallback) {

        Log.d("LauncherProvider", "getSession");
        try {

            if ( sessionCallback != null ) {

                WritableMap map = Arguments.createMap();
                Session session = internalGetSession();
                if ( session != null ) {
                    map.putString(Session.LOCATION, session.get(Session.LOCATION));
                    map.putString(Session.ROLE, session.get(Session.ROLE));
                    map.putString(Session.USER_ID, session.get(Session.USER_ID));
                    map.putString(Session.USERNAME, session.get(Session.USERNAME));
                    map.putString(Session.EXTENSION, session.get(Session.EXTENSION));

                    map.putString("accessToken", LauncherProviderHelper.getExtendedAttribute( getReactApplicationContext(), "accessToken") );

                    map.putString("idToken", LauncherProviderHelper.getExtendedAttribute( getReactApplicationContext(), "idToken") );

                    map.putString("refreshToken", LauncherProviderHelper.getExtendedAttribute( getReactApplicationContext(), "refreshToken") );

                } else {
                    Log.e("LauncherProvider", "getSession, Session not available" );
                }

                sessionCallback.invoke(map);
            } else {
                Log.e("LauncherProvider", "getSession, Callback not provided" );
            }

        } catch ( Exception e ) {
            Log.e("LauncherProvider", "getSession error ", e);
        }
    }

    private Session internalGetExtendAttributes() {

        return LauncherProviderHelper.getCurrentSession( getReactApplicationContext() );
    }

    private Session internalGetSession() {
        return LauncherProviderHelper.getCurrentSession( getReactApplicationContext() );
    }


}
React code

Here are code peices to get the Session information.

LauncherSessionProvider.js

Add the Launcher Provider script file to the React project. The file contents are just to import the bridge logic.

/**
 * This exposes the Launcher Session Provider
 *
 * Refer to https://facebook.github.io/react-native/docs/native-modules-android
 */
import {NativeModules} from 'react-native';
module.exports = NativeModules.LauncherSessionProvider;

App.js

Example code to read the session information.

import LauncherSessionProvider from './LauncherSessionProvider';

    populatSession = () => {
        LauncherSessionProvider.getSession((session)=>{
            console.log(`Session userName:${session.userName}`);
            console.log(`Session userId:${session.userId}`);
            console.log(`Session role:${session.role}`);
            console.log(`Session location:${session.location}`);
            console.log(`Session extension:${session.extension}`);

            this.setState({
                session:session
            })
        });
    }

Full Example App.js

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';

import LauncherSessionProvider from './LauncherSessionProvider';



const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
  android:
    'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu -- what is going on?',
});

type Props = {};
export default class App extends Component<Props> {

    constructor(props) {
        super(props);

        this.state = {
            loaded: true,
            error: null,
            session: null
        };
        console.log("APP  constructor");

        this.populatSession();
    }

    populatSession = () => {
        LauncherSessionProvider.getSession((session)=>{
            console.log(`Session userName:${session.userName}`);
            console.log(`Session userId:${session.userId}`);
            console.log(`Session role:${session.role}`);
            console.log(`Session location:${session.location}`);
            console.log(`Session extension:${session.extension}`);

            this.setState({
                session:session
            })
        });
    }
  render() {

    console.log('start of render');
    let userName='not set';
    if ( this.state.session && this.state.session.userName ) {
        userName = this.state.session.userName;

        console.log(`RENDER Session userName:${userName}`);
    }


    console.log('done with session');

    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>

        <Text style={styles.instructions}>UserName :{userName}</Text>

        <Text style={styles.instructions}>do you see the session stuff</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});