User Guide for Android SDK

This Quick Start guide will walk you through the key concepts behind AIQ's SDK and the steps required to get the included sample application up and running so you can start experimenting with the SDK as soon as possible.

For a more comprehensive guide we have divided into 3 different tutorials, which AIQ's SDK collective currently supported:

The source code of the tutorials can be found here.

Quick Start

The section summarizes the steps to use aiqkit in your Android project.

To start, users would need to login to AIQ's client portal, obtain your app's unique AppID and Secret, ingest some materials into our CRM under your account.


The App ID is shared across Operating Systems, including Android and iOS now, if the ingestion is shared

  • AppID and Ingestion
  • Add aiqkit as a Dependency
  • Initialize the SDK with AppID and Secret
  • Call image match API or invoke scanner

1. AppID and Ingestion

Before using the sdk, an AppID/Secret pair is required. This can be obtained from the client portal at
Note the staging server is for trial users. You also need to ingest some image/pdf/video before you can search for them.

2. Add aiqkit as a Dependency

The library is available from both jcenter and mavenCentral.

Add aiqkit as a Dependency

dependencies {
    implementation "tech.aiq:aiqkit:0.9.4"

3. Initlaize the SDK with AppID and Secret

In your Application class, initialize the SDK with AppID and Secret

initialize sdk

public class MyApplication extends Application {
 private static final String TAG = MyApplication.class.getSimpleName();
    public void onCreate() {
        Log.d(TAG, "MyApplication Started");
        String serverUrl = BuildConfig.AIQ_APP_SERVER;
        if (TextUtils.isEmpty(serverUrl)) {
            serverUrl = AIQKit.getServiceEndPoint(AIQKit.ServiceType.STAG);
            Log.d(TAG, "Using AIQ staging server");
        //initialize aiqkit
        AIQKit.init(this, BuildConfig.AIQ_APP_ID, BuildConfig.AIQ_APP_SECRET, serverUrl);
        Log.d(TAG, "Initialized AIQKit SDK");

The code above assumes build configuration variables AIQ_APP_ID, AIQ_APP_SECRET are set, AIQ_APP_SERVER is optional. One way is put these values into and refer from build.gradle.

configure the app_id, app_secret etc

In build.gradle
    defaultConfig {
        buildConfigField('String', 'AIQ_APP_ID', "\"${AIQ_APP_ID}\"")
        buildConfigField('String', 'AIQ_APP_SECRET', "\"${AIQ_APP_SECRET}\"")
        buildConfigField('String', 'AIQ_APP_SERVER', "\"${AIQ_APP_SERVER}\"")
      AIQ_APP_ID=<app id here>
      AIQ_APP_SECRET=<app secret here>
      AIQ_APP_SERVER=<service url here>

You can retrieve the preset urls with AIQKit.getServiceEndPoint(AIQKit.ServiceType.STAG) for staging, and AIQKit.getServiceEndPoint(AIQKit.ServiceType.PROD) for production.

4. Call image match API or invoke scanner

After the sdk is initialised, the service is ready to use. You could use the service by passing a bitmap object in memory, a file from the storage or use the builtin image scanner.

4.1. Builtin Scanner

The sdk contains a builtin scanner which sends queries to AIQ backend server at a frequency at around 1fps until a query is matched. The response is usually a URL, and will be opened by an embedded webview. To start the scanner, add the following line. The best place to put this line is in event handler code, for example, a button's OnClick() handler.

start builtin scanner

public void OnClick(View view){
    AIQKit.startScanner(this); // "this" is a activity object

startScanner(Activity) starts the builtin ScannerActivity, which is basically a live camera view with an animated scanner line overlay, indicating the scanner is actively sending queries.

4.2. Searching a static image

You can search an image file or a in-memory bitmap with the matchImage() function:

call the matchImage api

AIQKit.matchImage(image_data); // image data is either url of the image file, or a bitmap object

The matchImage() function returnes a RxJava1.* Observable which you can either synchronously or asynchronously process the response.

The following code snippet calls the match function in blocking mode. Note that it is not a good idea to block the ui thread, in the worst case it may cause your application to crash.

wait for the response

Observable<AIQKit.MatchResult> result= AIQKit.matchImage(uri);
 // use blocking mode to wait for the result
 try {
     AIQKit.MatchResult matchResult = result.toBlocking().first();
     if (matchResult != null) {
         Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(matchResult.getPayload()));
 } catch (Throwable t) {
     if (AIQKit.isImageNotFoundError(t.getCause())) {
         showToast("No match found");
     } else {
         showToast("Error: " + t.getMessage());

Instead you should invoke matchImage() in asynchronous mode:

handle the response

Observable<AIQKit.MatchResult> result= AIQKit.matchImage(uri);
        new Action1<AIQKit.MatchResult>() {
            public void call(AIQKit.MatchResult result) {
                // take the returned payload as url and show it in browser window
                if (result != null) {
                    Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(result.getPayload()));
                } else {
                    showToast("No match found");
        new Action1<Throwable>() {
            public void call(Throwable throwable) {
                // check if the result is "no match found'
                if (AIQKit.isImageNotFoundError(throwable)) {
                    showToast("No match found");
                } else {
                    showToast("Error: " + throwable.getMessage());