Get Started         Best Practices         Developer Guide         FAQ        

Tutorial: Manage on-device collections for the CraftAR Android SDKs

Last Updated: Aug 04, 2017
This article applies to the On Device Image Recognition SDK and the Augmented Reality SDK v4 +.

In order to add on-device collections to your Android app, it is necessary to:

  1. create an on-device collection in CraftAR;
  2. generate a collection bundle for your SDK version (On-device Image Recognition SDK or Augmented Reality SDK v4 +;
  3. download the bundle of that collection from CraftAR and add it to the app;

This tutorial covers third step. You can find more details for the first and second steps in the tutorial about how to create a collection in CraftAR for on-device image recognition or on-device Augmented Reality. Once you have the collection added into the device, you can start using your collection with the on-device Image Recognition SDK or the Augmented Reality SDK (v4 +)

On-device collection bundles represent a collection from the CraftAR service that can be added to a device in order to do Image Recognition or Augmented Reality on the device, without the need to connect to the network. They contain the image database and metadata of the items of the corresponding collection.

1. Adding collection bundles to the app

You can decide to create apps that have the collection bundle embedded or download the collection bundle from the CraftAR Service. The first option will increase the size of your app but will make the first use faster for the user. The second option is the opposite case and has the extra advantage that you can publish your app and modify the collection bundle later on.

Embed the collection bundle into the app

To embed the collection bundle into the app copy the collection bundle zip file into the assets directory of your android project.

Download the collection bundle from the CraftAR Service

You can download collection bundles at runtime from the CraftAR service. To do it, you can use the method

CraftAROnDeviceCollection.addCollectionWithToken(String token,AddCollectionListener listener);
The the SDK will retrieve the bundle for the collection with the provided token from the CraftAR service. This method will download the latest available bundle matching your appID and SDK version, and directly add it to the local database..

 

After adding the collection bundle to the app it is also necessary to add the bundle to the local database. See the next section for details.

2. Adding collection bundles to the local database

Add collection bundles to the local database of the device, allows to have them always available for on-device Image Recognition or on-device Augmented Reality. This step only needs to be done once in the app lifetime or when you need to update the on-device collection.

Start by initializing the SDK and get access to the CraftAROnDeviceCollectionManager module. Then, check whether your collection has already been added to this device with the method getCollection() of CraftAROnDeviceCollectionManager instance.

   
@Override   
protected void onCreate(Bundle savedInstanceState) {
   ....
   CraftAROnDeviceCollectionManager collectionManager = 
                    CraftAROnDeviceCollectionManager.Instance();
    CraftAROnDeviceCollection collection = collectionManager.get(TOKEN);
    if(collection != null){
        // Collection is already added to the device
    }else{
        // Add the collection to the local database
        collectionManager.addCollection("arbundle.zip", (AddCollectionListener)this);
    }
}
@Override
public void collectionAdded(CraftAROnDeviceCollection collection) {}

@Override
public void addCollectionFailed(CraftARError error) {}

@Override
public void addCollectionProgress(float progress) {}

Note that this can be done in any Activity. You can do this from your CraftARActivity, but it's interesting to do it a separate activity, so you don't start the camera until you know that the collection has been added and it's ready to be used.

3. Syncing your collection

Some applications as catalogs require that the app synchronizes the collection often. If this is your case, you might consider using collection synchronization. In this section we will briefly explain how to synchronize the collections in your app with your collections in CraftAR.

This method works on all our SDKs. However, at the moment it does not download the augmented reality contents.
We recommend its use for image recognition or when the augmented reality contents are added programmatically. 

In the SDK, call CraftAROnDeviceCollection.sync((SyncCollectionListener)listener) to synchronize the collection.

protected void onCreate(Bundle savedInstanceState) {
    // Initialize the SDK and get the collection
    ...
    // Sync the collection
    collection.sync((SyncCollectionListener)this)
}
 @Override
public void syncSuccessful(CraftAROnDeviceCollection collection) { }

@Override
public void syncProgress(CraftAROnDeviceCollection collection, float progress) { }

@Override
public void syncFailed(CraftAROnDeviceCollection collection, CraftARError error) { }

This call will do the following:

  • Ask the CraftAR Service for the current version of the collection to be compared with the bundle.
  • If the collection in the device is already the latest version, the SDK will directly trigger the syncSuccessful callback.
  • If the collection in the device is outdated, the call will download the new and changed items and update the collection in the app. When the collection is synchronizing, you will receive the progress in the syncProgress callback. When the synchronization finishes, you will receive the callback to syncSuccessful callback.
  • If the synchronization fails (i.e, if there’s no data connectivity, or any other error occurs), you will receive an error in the syncFailed callback. Depending on your use case, you might consider loading the collection even if it’s outdated, or avoid loading it.

We recommend you try to sync your collections when the app starts (for example, at the Splash screen), but this is completely up to you.

Below you can see the full implementation of a Splash Activity that adds the collection bundle to the local database, syncs the collection and finally, starts the camera activity.

public class SplashScreenActivity extends Activity implements AddCollectionListener,
 SyncCollectionListener{

    private final static String TAG = "SplashScreenActivity";
    private static final long SPLASH_SCREEN_DELAY = 1000;
    public final static String TOKEN = "your_collection_token";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash_screen);

        CraftARSDK.Instance().init(getApplicationContext());
        
        CraftAROnDeviceCollectionManager collectionManager = 
            CraftAROnDeviceCollectionManager.Instance();

        /**
         * The on-device collection may already be added to the device (we just add it once)
         * we can use the token to retrieve it.
         */
        CraftAROnDeviceCollection collection = collectionManager.get(TOKEN);
        if(collection != null){
            collection.sync((SyncCollectionListener)this);
        }else{
            /**
           * If not, we get the path for the bundle and add the collection to the device first.
           * The addCollection  method receives an AddCollectionListener instance that will 
           * receive the callbacks when the collection is ready.
           */
            collectionManager.addCollection("myarbundle.zip", (AddCollectionListener)this);
            
            //Alternatively, you can also download the collection from CraftAR using the token, 
            // instead of embedding it into the app resources.
            //collectionManager.addCollectionWithToken(TOKEN, (AddCollectionListener)this); 
        }
    }

    @Override
    public void collectionAdded(CraftAROnDeviceCollection collection) {
        
        //If you're adding the collection from an embedded bundle, you might want to ensure
        // that the bundle is in the latest version. Note that if you're using 
        // addCollectionWithToken(), it will be already in the latest version, because it will
        // download it. 
        collection.sync((SetCollectionListener)this);
    }

    @Override
    public void addCollectionFailed(CraftARError error) {
        Toast.makeText(getApplicationContext(), "AddCollection failed: "+
error.getErrorMessage(), Toast.LENGTH_SHORT).show();
        finish();
    }

    @Override
    public void addCollectionProgress(float progress) {
        Log.d(TAG, "addCollectionProgress "+progress);

    }
    
    @Override
    public void syncSuccessful(CraftAROnDeviceCollection collection) {
        //The collection is ready and updated! Start the craftARActivity
        startCraftARActivity();       
    }

    @Override
    public void syncProgress(CraftAROnDeviceCollection collection, float progress) {
        Log.e(TAG, "syncProgress : "+progress);
        
    }

    @Override
    public void syncFailed(CraftAROnDeviceCollection collection, CraftARError error) {
        Log.e(TAG, "syncFailed : "+error.getErrorMessage());
        // Even if the collection could not be updated, we start the camera activity, so 
        // it can still be used with the version available in the device.
        startCraftARActivity(); 
    }

     private void startCraftARActivity(){
        TimerTask task = new TimerTask() {
            public void run() {
                Intent craftarActivity = new Intent( SplashScreenActivity.this, 
                                                            MyCraftARActivity.class);
                startActivity(craftarActivity);
                finish();
            }
        };
        Timer timer = new Timer();
        timer.schedule(task, SPLASH_SCREEN_DELAY);
    }

}

Note: After modifying the items in your collection you don't need to re-generate the collection bundle.

4. Handling errors

When an error is produced in a bundle management operation in the SDK, the SDK triggers a callback with a CraftARError.

When there is an incompatibility between the SDK and the added collection bundle a runtime error is produced. There are two types of version compatibility errors:

  • COLLECTION_BUNDLE_VERSION_IS_OLD which is produced when there is an attempt to add a bundle that was generated for a version of the SDK that is older than the one running in the app; and
  • COLLECTION_BUNDLE_SDK_VERSION_IS_OLD which is produced when there is an attempt to add a bundle that was generated for a version of the SDK that is newer than the one running in the app.

When a collection is not longer valid, the method getCollection will return null for that collection, as it didn’t exist. So, in that case you should add the bundle again. If you try to add an outdated bundle, an error will be triggered in the addCollectionFailed callback. You should always add a bundle that is compatible with the app.

@Override
public void addCollectionFailed(CraftARError error) {
    //Error adding the bundle to the device internal storage. 
    Log.e(TAG,"addCollectionFailed("+error.getErrorCode()+"):"+error.getErrorMessage());
    Toast.makeText(getApplicationContext(), "Error adding collection", Toast.LENGTH_SHORT).show();
    switch(error.getErrorCode()){
    case COLLECTION_BUNDLE_SDK_VERSION_IS_OLD:
        // You are trying to add a bundle which version is newer than the SDK version. 
        // You should either update the SDK, or download and
        // add a bundle compatible with this SDK version.
        break;
    case COLLECTION_BUNDLE_VERSION_IS_OLD:
        // You are trying to add a bundle which is outdated, since the SDK
        // version is newer than the bundleSDKversion 
        // You should download a bundle compatible with the newer SDK version.
        break;
    default:
        break;
    }
}
Pay special attention when updating an app that has already been downloaded by your users. If the update of the app uses a new version of the SDK that is not compatible with the bundle that the devices may have added to the local database, the newly installed app will produce the first error. In order to prevent that, you can capture this error and force a download of the updated collection bundle.

Couldn't find what you were looking for?

support@catchoom.com
https://cdn.desk.com/
false
catchoom
Loading
seconds ago
a minute ago
minutes ago
an hour ago
hours ago
a day ago
days ago
about
false
Invalid characters found
/customer/en/portal/articles/autocomplete