Android SDK Integration Manual

Requirements

Blippar Android SDK should be linked as a part of an Android project in Android Studio or another Android IDE. The SDK supports Android 4.4 or later, you need to build your app with Android SDK Revision 19.0.0 (API Level 19) or later. The SDK is built with a target SDK version of 27.

The SDK contains four architectures: armeabi-v7a, arm64-v8a, x86_64 and x86.

Currently, the BlipparSDK only supports full screen portrait mode. This can be set in the activity xml or programmatically.

Gradle 3.x.x is not yet supported, please use 2.x.x.

License Key

You must obtain a license key from Blippar to use the SDK in your app. This key must be embedded into your app source code and then given to the SDK during its initialisation (this is shown in the example below.)

If you have more than one app then you will need separate keys for each app.

Distribution

The Android SDK bundle is distributed as an AAR module file.

Linking

Assuming you are using Android Studio 1.3 or later please follow the following steps to import the Android SDK to your project:

  1. Save the provided .AAR file locally.

  2. Open the project you want to use SDK with.

  3. Import a local .AAR file via the following menu: File>New>New Module>Import .JAR/.AAR Package.

This should automatically add the following line to your app build.gradle file under dependencies section:

dependencies {
	...
	compile project(':blipparsdk')
	...
}

Where :blipparsdk is the name you have given to the Blippar SDK module. If this line has not been added automatically, please add it manually. You may encounter an error:

Error:Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : Attribute application@theme value=(@style/AppTheme) from AndroidManifest.xml:11:9-40
  	is also present at [:blipparsdk] AndroidManifest.xml:11:18-49 value=(@style/SDKTheme).
  	Suggestion: add 'tools:replace="android:theme"' to <application> element at AndroidManifest.xml:5:5-19:19 to override.

If you add the following line to your AndroidManifest.xml <application> tag:

tools:replace="android:theme"

If tools appear in red in Android Studio then may need to hover over tools and hit alt+enter to automatically import the correct namespace.

Permissions

The SDK requires following basic permissions to function:

  • the camera,

  • internet,

  • network state.

Without these the SDK will not function.

There are a few optional permissions. The SDK will function without them, but if the blipp requires one or several optional permissions to function correctly, it may not work and even crash at runtime if permissions are not granted.

It is recommended you only acquire the permissions you know your app needs to run blipps. If you know your blipp while running in your custom app won't be saving or picking photos from the gallery/Photos then you should not acquire the permission.

When targeting Marshmallow or higher the optional permissions are requested from the SDK dynamically at runtime, if not already granted. This only happens at the point at which an operation that requires the permission is performed in the blipp. The one exception to this is the location permission, this must be explicitly acquired by the client app and is never requested by the SDK. You can overload the text used for the various permission prompts if desired.

If targetting earlier versions than Marshmallow then you'll need to request the permissions up front in your AndroidManifest.xml (see below):

<!-- Mandatory permissions -->
<uses-feature
    android:name="android.hardware.camera"
    android:required="true"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.VIBRATE"/>

<!-- Optional permissions -->

<!-- Used when writing photos taken within a blipp to the Photos/Gallery app -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Used to read from Photos/gallery when a blipp wants to choose an existing photo -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<!-- Used when performing video recording within a blipp -->
<uses-feature
        android:name="android.hardware.microphone"
        android:required="false" />
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

<!-- Blipps can vibrate the device using a JS API -->
<uses-permission android:name="android.permission.VIBRATE" />

<-- Location permissions -->
<uses-feature
    android:name="android.hardware.location"
    android:required="false" />
<uses-feature
    android:name="android.hardware.location.network"
    android:required="false" />
<uses-feature
    android:name="android.hardware.location.gps"
    android:required="false" />
<!-- Used for determining the user's location. Must still be enabled via the SDK setLocationEnabled API -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Dependencies

The SDK has a few dependencies.

compile "com.android.support:support-core-utils:${androidSupportLibVersion}"
compile "com.android.support:design:${androidSupportLibVersion}"
compile "com.android.support:preference-v14:${androidSupportLibVersion}"
// For getting saved photo orientation
compile "com.android.support:exifinterface:${androidSupportLibVersion}"
// Face detection/tracking
compile "com.google.android.gms:play-services-vision:${googlePlayServicesLibVersion}"
//  Required by Location Services
compile "com.google.android.gms:play-services-location:${googlePlayServicesLibVersion}"
// unit tests
testCompile "junit:junit:${junitLibVersion}"
testCompile "org.mockito:mockito-core:${mockitoLibVersion}"

The SDK allows these libraries to be changed via your app's build.gradle.

Below is a table that outlines the various versions:

Proguard

The SDK gradle defines a proguard configuration using the 'consumerProguardFiles 'blipparsdk_proguard-project.pro'. This means there is nothing special you should need to do.

SDK Registration

Java / Kotlin

  1. Open (or create) your Application class/Kotlin file.

  2. Add the following line at the top of the file below your own import statements (Android Studio does this automatically for you)

    import com.blippar.ar.android.sdk.Blippar;
  3. Search for the callback onCreate() or override it.

  4. Add the following lines to setup and start the Android Blippar SDK:

    	super.onCreate();
    
    	Blippar.setApplication(this);
        Blippar.setKey("enter your license key here");

    Note: Please keep your key secure. Do not store it inside any obviously textual files inside your application bundle.

Integrating SDK Fragment in an Activity

As Blippar SDK is using a camera feed to display an AR experience we assume that developer has taken care of getting the camera permission. Launching the SDK without camera permission will crash the app. Location permission is optional and is only needed if the client's custom app is going to display a location-based AR experience. See the "Permissions" chapter in this document for more detail.

The BlipparSDKFragment/BlipparView must be full screen. For more information, see this document on how to hide the status bar

If using AppCompat you will need to use windowActionBarOverlay as opposed to the android namespaced one in your activity/app's theme in xml.

If you do not make the view full screen then certain undesirable resizing of blipp content can happen on backgrounding and foregrounding of the app. We will fix this issue in a future release of the SDK.

Adding SDK Fragment Through the Activity XML Layout File

Java

  1. In the activity .xml file add a fragment with the class property set to "com.blippar.ar.android.sdk.BlipparSDKFragment". Alternatively, create the fragment programmatically based on the BlipparSDKFragment class, there is a convenience static BlipparSDKFragment.create() function.

  2. To control the SDK lifecycle you need to create an SDK observer and override its default callbacks. Use the onInitialiseSuccess callback to start blipp detection:

    private final BlipparSDK.BlipparSDKListener blipparSDKListener = new BlipparSDK.BlipparSDKListener() {
        @Override
        public void onInitialiseSuccess() {
            final BlipparSDK sdk = Blippar.getSDK();
    
            // after the SDK is initialised, start detection and rendering
            // You can add other kinds of detectionTypes with the other startDetection variant
            sdk.startDetection();
        }
    
        @Override
        public void onInitialiseError() {
        }
    
        @Override
        public void onShutdown() {
        }
    };
  3. In the activity class add an observer for the SDK:

    Blippar.getSDK().addSDKListener(blipparSDKListener);
  4. Don't forget to remove the observer after it is not used anymore (overriding onDestroy callback would be a good place for that):

    protected void onDestroy() {
            super.onDestroy();
    
            // when destroying the activity, remove the lifecycle observer
            Blippar.getSDK().removeSDKListener(blipparSDKListener);
        }

Kotlin

  1. In the activity .xml file add a fragment with the class property set to "com.blippar.ar.android.sdk.BlipparSDKFragment". Alternatively, create the fragment programmatically based on the BlipparSDKFragment class, there is a convenience static BlipparSDKFragment.create() function.

  2. To control the SDK lifecycle you need to create an SDK observer and override its default callbacks. Use the onInitialiseSuccess callback to start blipp detection:

    private var mBlipparSDKListener = object : BlipparSDK.BlipparSDKListener {
        override fun onInitialiseSuccess() {
            // Start detection with just markers
            // You can add other kinds of detectionTypes with the other startDetection variant
            Blippar.getSDK().startDetection()
        }
    
        override fun onInitialiseError(error: InitialisationError) {
            Toast.makeText(this@MainActivity, "Unable to initialise SDK with error: " + error.toString(), Toast.LENGTH_LONG).show()
            Log.e(LogTag, "Unable to initialise SDK with error: " + error.toString())
        }
    
        override fun onShutdown() {
            // Cleanup and remove the listener now
            Blippar.getSDK().removeSDKListener(this)
        }
    }
  3. In the activity class add an observer for the SDK:

    Blippar.getSDK().addSDKListener(mBlipparSDKListener)
  4. Don't forget to remove the observer after it is not used anymore (overriding onDestroy callback would be a good place for that):

    override fun onDestroy() {
        super.onDestroy()
    
        // Remove our listeners
        Blippar.getSDK().removeSDKListener(mBlipparSDKListener)
    }

Blipp Lifecycle

Java

To respond to the blipp lifecycle you need to implement a blipp state listener.

  1. Create a blipp event listener object based on the BlippStateListener class. It has several callbacks that will allow you to follow the blipp lifecycle events: onBlippLoading, onBlippError, onBlippRunning, onBlippWaitingForTrackingLock, onBlippClosing and onBlippClosed.

        private final BlippStateListener mBlippStateListener = new BlippStateListener() {
    
            @Override
            public void onBlippLoading(BlippContext context) {
                // Blipp has started loading
            }
    		
    		@Override
    		public void onBlippWaitingForTrackingLock(BlippContext context) {
    			// Blipp is waiting for the tracker to lock onto the target before loading	
    		}
            
    		@Override
    		public void onBlippLoadingProgress(BlippContext context, int progress) {
    			// Blipp is loading with the visible progress spinner
    		}
    
    		@Override
    		public void onBlippError(BlippContext context, BlipparSDKBlippErrorType errorType) {
       		 	// Blipp has failed to trigger with the given error
    		}
    
    
    		@Override
    		public void onBlippRunning(BlippContext context, BlippRunningState runState) {
    			// Blipp is running in the given state
    		}
    
    		@Override
    		public void onBlippClosing(BlippContext context) {
    			// Blipp has begun closing
    		}
    
            @Override
            public void onBlippClosed(BlippContext context) {
                // Blipp is closed
            }
    
        };
  2. You can cache the blippcontext provided by the BlippEventListener.onBlippLoading callback to control the Blipp lifecycle. However, the BlipparSDKFragment already does this so beware that cache the context may cause reference problems if you don't release it correctly. The BlipparSDKFragment there is a function to close the currently running Blipp called closeCurrentBlipp.

Kotlin

To respond to the blipp lifecycle you need to implement a blipp state listener.

  1. Create a Blipp event listener object based on the BlippStateListener class. It has several callbacks that will allow you to follow the Blipp lifecycle events: onBlippLoading, onBlippError, onBlippRunning, onBlippWaitingForTrackingLock, onBlippClosing and onBlippClosed.

    private val mBlippStateListener = object : BlippStateListener {
        override fun onBlippLoading(blippEngineContext: BlippContext) {
    		// Blipp has started loading
        }
    
        override fun onBlippWaitingForTrackingLock(context: BlippContext) {
            // Blipp is waiting for the tracker to lock onto the target before loading	
        }
    
        override fun onBlippLoadingProgress(context: BlippContext, i: Int) {
            // Blipp is loading with the visible progress spinner
        }
    
        override fun onBlippError(context: BlippContext, blipparSDKBlippErrorType: BlipparSDKBlippErrorType) {
            // Blipp has failed to trigger with the given error
        }
    
        override fun onBlippRunning(context: BlippContext, runningState: BlippRunningState) {
            // Blipp is running in the given state
        }
    
        override fun onBlippClosing(context: BlippContext) {
            // Blipp has begun closing
        }
    
        override fun onBlippClosed(context: BlippContext) {
            // Blipp is closed
        }
    }

    Register with the SDK

    Blippar.getSDK().addBlippStateListener(mBlippStateListener)

    Make sure you remove the listener in your onDestroy()

  2. You can cache the blippcontext provided by the BlippEventListener.onBlippLoading callback to control the blipp lifecycle. However, the BlipparSDKFragment already does this so beware that cache the context may cause reference problems if you don't release it correctly. The BlipparSDKFragment there is a function to close the currently running Blipp called closeCurrentBlipp.

Integrating the Debug View

  • Add com.blippar.ar.android.DebugView to your view/activity. Ideally, it would be full screen and on top of everything else.

  • The DebugView can be toggled (slid in and out) by tapping the bottom of the UI. It will slide down and reveal other options.

  • The debug view really is only useful when in a blipp but there are some helpful options within the 'More..' overflow

Testing Your App

  • Once you have a running app you may wish to test against some real markers. See the provided Sample Markers document.

  • Once the SDK has been initialised call the SDK's setDebugTestBlippsEnabled function and set this to true in order to see the sample markers.

  • Make sure you turn off this flag (by default it is off) before releasing your app to the public. It is also possible to increase the verbosity of the logging system within thSDK.

Sample Apps

  • There are two sample apps provided, one in Java and one in Kotlin.

  • They are an example of the most basic integration of the SDK.

  • The keys have been removed from the project so you need to provide your own key. You can do this in App.java or App.kt.

  • You will also need to change the package name in the AndroidManifest.xml to your licensed package name to validate the SDK.

Last updated