Sign in

Sign in to confirm

Have you forgotten your password?

... or login with Facebook:

Don't have an AndroidPIT account yet? Sign up

App Licensing – How-To

Prerequisites

You are already using LVL?

If you are already using the Android License Verification Library, implementing the AndroidPIT Licensing Library is really simple.

1.

Download the AndroidPIT Licensing Library and add it to your project.

2.

Change the following two variable definitions from

    private LicenseCheckerCallback mLicenseCheckerCallback;
    private LicenseChecker mChecker;

to

    private IAndroidPitLicenseCheckerCallback mLicenseCheckerCallback;
    private AndroidPitLicenseChecker mChecker;

3.

Change the creation of the checker from

    mChecker = new LicenseChecker(
            this,
            new ServerManagedPolicy(
                    this,
                    new AESObfuscator(SALT, getPackageName(), deviceId)),
            GOOGLE_PUBLIC_KEY);

to

    mChecker = new AndroidPitLicenseChecker(
            this,
            getPackageName(),
            ANDROIDPIT_PUBLIC_KEY,
            new ServerManagedPolicy(
                    this,
                    new AESObfuscator(SALT, getPackageName(), deviceId)),
            GOOGLE_PUBLIC_KEY);

4.

Change the definition of your listener from (example)

    class MyLicenseCheckerCallback implements LicenseCheckerCallback

to

    class MyLicenseCheckerCallback implements IAndroidPitLicenseCheckerCallback

5.

Change the type of the errorCode parameter in the applicationError method from

    public void applicationError(ApplicationErrorCode errorCode)

to

    public void applicationError(AndroidPitLicenseCheckCode errorCode)

and extend the error handling with the AndroidPIT response codes (see below).

Thatʼs it! The call to the checker method as well as the allow() and dontAllow() callback method implementations do not need to be changed.

On the Quick Run

The AndroidPIT Licensing Library is very similar to Googleʼs Android License Verification Library (LVL). To use the AndroidPIT Licensing Library, add the Android License Verification Library (LVL) and the AndroidPIT Licensing Library to your project. In your onCreate() method, create an instance of the AndroidPitLicenseChecker and provide it with an instance of a class that implements the IAndroidPitLicenseCheckerCallback interface. Additionaly, you require a license key, which we will provide to you in your developer profile on the AndroidPIT website. An example of an Activity may look like this:

import android.app.Activity;

public class LicensingTest extends Activity implements OnClickListener
{

    private final String ANDROIDPIT_PUBLIC_KEY = "rO0ABXNyABRqYX...;"

    private final Handler mHandler = new Handler();

    private IAndroidPitLicenseCheckerCallback mLicenseCheckerCallback;
    private AndroidPitLicenseChecker mChecker;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        mLicenseCheckerCallback = new MyLicenseCheckerCallback();
        mChecker = new AndroidPitLicenseChecker(
                this,
                getPackageName(),
                ANDROIDPIT_PUBLIC_KEY);

        setContentView(R.layout.main);

        mChecker.checkAccess(mLicenseCheckerCallback);
    }

    @Override
    protected void onDestroy
    {
        super.onDestroy();
        mChecker.onDestroy();
    }

    class MyLicenseCheckerCallback implements IAndroidPitLicenseCheckerCallback
    {

        @Override
        public void allow()
        {
            // TODO: Handle positive response
        }

        @Override
        public void dontAllow()
        {
            // TODO: Handle negative response
        }

        @Override
        public void applicationError(AndroidPitLicenseCheckCode errorCode)
        {
            // TODO: Handle application error
        }

    }

}

Additionally to checking for a valid license on AndroidPIT, you can easily allow the AndroidPIT licensing to check at the Android Market, too. To do so, adapt the constructor call of the AndroidPitLicenseChecker to take the Google policy and the Google public key as well. For all other steps to setup LVL, please consult the LVL documentation.

/**
 * Creates the AndroidPitLicenseChecker with all data to check against the
 * AndroidPIT App Center and Google. Google is checked first. If it fails,
 * AndroidPIT App Center will be consulted.
 
 @param context
 *            the context of the application
 @param appPkgName
 *            the package id of the app
 @param androidPitPublicKey
 *            the developers public key at AndroidPIT
 @param googlePolicy
 *            policy for Google licensing - @see LVL documentation
 @param googlePublicKey
 *            public key for Google licensing - @see LVL documentation
 */
public AndroidPitLicenseChecker(
        final Context context,
        final String appPkgName,
        final String androidPitPublicKey,
        final Policy googlePolicy,
        final String googlePublicKey);

En Detail

The AndroidPIT licensing system is oriented on the Android License Verification Library (LVL) introduced by Google. It provides capabilities to check the validity of apps, which are purchased via the AndroidPIT App Center. A requirement so is the connection to the AncroidPIT license server through the internet. Additionally, the end user requires to have a valid AndroidPIT account.

With the help of the AndroidPIT Licensing Library, your application will check via the App Center if the end user is in posession of a valid license to run your app. The validity check happens each time the application starts but earliest once a day or when an internet connection is available. In the meantime a cached value from the last request is returned (keep in mind that the time frame in which the cache is valid may change anytime).

Step-by-Step

This step-by-step guide is based on the fact that you are using the Eclipse ADT. In the case you are using different development tools, you may be required to do some more steps.

Download the AndroidPIT Licensing library and the Android License Verification Library (LVL) and add them as projects to Eclipse. To use the AndroidPIT Licensing Library, at least Android API version 4 is requred which was introduced with Android 1.6. Create a new Android application and add the androidpit-licensing-lib in the preferences under android as a dependend library to the application project. Please also check if the library correctly links to the Android License Verification Library (LVL).

My Project shows unresolved symbols or I can not compile my App.

Please check for the paths to the Google LVL and the AndroidPIT Licensing library inside the Preferences dialog of your Android Project. They should match to the paths on your filesystem.

Application project settings

The settings for the AndroidPIT Licensing Library should look like this, matching your paths:

Library project settings

How do I setup the license check in my code?

To allow the licensing library to check for a valid license via the AndroidPIT App Center, instantiate in the onCreate() method of your activity an instance of the class MyLicenseCheckerCallback. The constructor expects an instance of the context, which usually is the activity itself. The resulting code may look like this:

mLicenseCheckerCallback = new MyLicenseCheckerCallback();
mChecker = new AndroidPitLicenseChecker(
          this, getPackageName(), ANDROIDPIT_PUBLIC_KEY);
mChecker.checkAccess(mLicenseCheckerCallback);

Furthermore, the constructor requires information about the package name of your app and the base64-encoded public key, which we provide to you in your developer profile on the AndroidPIT website.

How do I get notified from the license server?

The license is checked by calling checkAccess() on the AndroidPitLicenseChecker instance. The method requires a callback object which implements the interface IAndroidPitLicenseCheckerCallback. It is up to you to implement this class and fill it with code that suites your needs. The allow() method will be called from within the Licensing Library to notify you about a successful validation of the license of the user. In any other case dontAllow() is called. Additionally, the method applicationError() informs you about errors that may happen during the license check. You have full control on the actions, which will take place in these three methods.

class MyLicenseCheckerCallback implements IAndroidPitLicenseCheckerCallback
{

    @Override
    public void allow()
    {
        // TODO: Handle positive response
    }

    @Override
    public void dontAllow()
    {
        // TODO: Handle negative response
    }

    @Override
    public void applicationError(AndroidPitLicenseCheckCode errorCode)
    {
        // TODO: Handle application error
    }

}

How do I additionally check for a license in the Android Market?

In addition to the check against our licensing system, we provide an easy to use integration of Googleʼs Android License Verification Library (LVL). To integrate this, just add your LVL policy and public key to the constructor of our AndroidPitLicenseChecker. The license check will then take place inside the code of the license library. If the license check against Google is successful you will directly be notified by the callback object through the allow() method you wrote some minutes before. Negative responses will result in an additional request to the AndroidPIT licensing servers. Only if these calls fail, you will get a negative answer from the licensing library.

This example orients on the example from the Google API.

mChecker = new AndroidPitLicenseChecker(
               this, 
               getPackageName()
               ANDROIDPIT_PUBLIC_KEY,
               new ServerManagedPolicy(
                   this,
                   new AESObfuscator(SALT, getPackageName(), deviceId)),
               GOOGLE_PUBLIC_KEY);

How can I test different error messages from the licensing server?

On the licensing page in your developer profile at AndroidPIT, you can set up a response code that will be send by the licensing server. This is useful if you want to test if your application correctly responds to the error messages from our license server. To accomplish this, just select the appropriate value from the drop down list. Then, the license server will always answer with the selected response code if you are logged in with your developer account on your test device.

How do I disable the caching of the result in the App Center?

The App Center stores the result of the last request for at least a day or until the mobile device is able to contact our license server through the internet. To disable this caching, you can enable the debug mode in the license checker. To do this just call setDebug(true). This will disable caching of all requests send to the App Center. Donʼt forget to turn off debug mode before publishing your app.

What happens if the user is not logged in into the App Center?

If no or invalid credentials are stored in the App Center, the library will show a popup dialog to ask for the userʼs AndroidPIT e-mail address and password.

How can I make sure, that the license requests hits the license server?

The AndroidPIT license library contains the class AndroidPitSignedLicenseChecker. This class provides the possibility to check if the request reached the license server or not. To asure that the license server signes the license response using the private key of the developer of the App. The library validates the received data with the signature using the AndroidPitLicenseingResponseValidator additionaly by comparing the Salt send in the request with the Salt found in the response data. Please consider that this mechanism does not provide any caching of the license state. Every response has to be calculated at the license server by the given request data. If the user has no connection to the license server, the library responses with a ERROR_NOT_CONNECTED.

An example using the AndroidPitSignedLicenseChecker may look like this:

AndroidPitSignedLicenseChecker mChecker;

[ ... ]

mChecker = new AndroidPitSignedLicenseChecker(
               this, 
               getPackageName()
               ANDROIDPIT_PUBLIC_KEY);

Can I provide my own license validator? I want to check the validity of the response on my own behalf.

Yes, that is possible. Please implement the Inteface ILicensingResponseValidator and provide an instance of the implementing class to the AndroidPitSignedLicenseChecker. This class has to implement two methods. getSalt() has to return an integer, wich will be used as a Salt on the license check validation. This salt should be stored during the request to be able to check against the salt returned on the response if this check is desired. The method checkResponse() should validate the response data and should return a AndroidPitLicenseCheckCode.NOT_LICENSED on failure. If the validation succeeds the response code from the server has to be returned. As a sample implementation you can consult AndroidPitLicensingResponseValidator from the AndroidPIT licensing library.

My project can not find the enumeration de.androidpit.AndroidPitLicenseCheckError.

This enumeration was renamed to de.androidpit.AndroidPitLicenseCheckCode.

How can I create a PublicKey based on the Base64-String?

As you may noticed we provide you the public key as a Base64 encoded string. In order to check the signature to the response data you are required to convert this String into a PublicKey object. The following code will show you how to accomplish that.

    /**
     * Converts the base64 encoded representation of a public key into a
     * PublicKey object.
     */
    private PublicKey createPublicKey(String pubKeyBase64)
    {

        PublicKey pubKey = null;
        try
        {
            // the pub key comes in as a Base64 coded string. Decode to the
            // byte array which contains the object stream of the public key
            ByteArrayInputStream pubKeyByteArray = new ByteArrayInputStream(
                    Base64.decode(pubKeyBase64));
            ObjectInputStream publicKeyObject = new ObjectInputStream(
                    pubKeyByteArray);
            BigInteger modulus = (BigIntegerpublicKeyObject.readObject();
            BigInteger exponent = (BigIntegerpublicKeyObject.readObject();

            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
            KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA");
            pubKey = rsaKeyFactory.generatePublic(keySpec);
        }
        catch (Exception ex)
        {
            Log.e(
                    "LicenseResponseValidator",
                    "Deserialization of public key failed.",
                    ex);
        }
        return pubKey;
    }

AndroidPIT Licensing Library

If you are using the old Android Market licensing library (Package com.android.vending.licensing), please use this version of the AndroidPIT licensing library:
AndroidPIT Licensing Library Version 1.3

If you are using the new Google Play library (Package com.google.android.vending.licensing), use the following version of the AndroidPIT licensing library:
AndroidPIT Licensing Library Version 2.1