Implementing License Verification Library for paid Android applications

This page presents sample skeleton source code for our previous post: How to prepare and submit an application to Android Market. Android Market offers licensing services for paid applications and provides java source code for developers. This License Verification Library (LVL) must be integrated into custom Android applications. It handles all of the licensing-related communication with the Android Market client and the licensing service. An overview on licensing can be read here.
/***************************************************************************
 * Main activity of your application with license check
 * It's like a gate to your app
 */
public class MyActivity extends Activity {

    private static final String BASE64_PUBLIC_KEY = "MNc88KCAQEAjCwut0Wo3N3... here we cut it half ... AQUA";
    private static final byte[] APP_SALT = new byte[] {-00,11,11,40,17,22,-100,-88,15,16,24,50,3,117,-49,44,-32,48,-35,-71 };   // 20 random integers
    private LicenseChecker wdsLicenseChecker = null;
    private WDSLicenseCheckerCallback wdsLicenseCheckerCallback;

    /***************************************************************************
     * LicenseCheckerCallback private class
     */
    private class WDSLicenseCheckerCallback implements LicenseCheckerCallback {

        public void allow() {
            if (isFinishing()) {
                return;
            }
            // Allow user access
            Log.v("WDSLicenseCheckerCallback", "License Allowed");

            // Here set your flags or bounce to your original Activity like
            bounceToMainActivity();
        }

        public void dontAllow() {
            if (isFinishing()) {
                return;
            }
            Log.v("WDSLicenseCheckerCallback", "License Disallowed");
            // Should not allow access. An app can handle as needed, typically by informing the user that the app is not licensed
            // and then shutting down the app or limiting the user to a restricted set of features.
            // Present user some options, or set flags, or just bounce to Android Market:
            showDialog(0);
         }

        public void applicationError(ApplicationErrorCode errorCode){
            if (isFinishing()) {
                return;
            }
            Log.v("WDSLicenseCheckerCallback", "applicationError: " + errorCode);
           
            // Add your handling code, such as say sorry or bounce to your original Activity
            Toast.makeText(this, getString(R.string.license_error), Toast.LENGTH_SHORT).show();
        }
    }
   
    /***************************************************************************
     * The MyActivity activity is being created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        // Call license checker
        // You can make it a little bit more fancy
        LICENSED_APP_ID = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
        this.wdsLicenseCheckerCallback = new WDSLicenseCheckerCallback();
       
        // Construct the LicenseChecker with a policy
        // You can make it safer with custom constructor, public status flags etc.
        this.wdsLicenseChecker = new LicenseChecker(this, new ServerManagedPolicy(this,
                                        new AESObfuscator(APP_SALT, getPackageName(), LICENSED_APP_ID)),
                                        BASE64_PUBLIC_KEY);
        this.wdsLicenseChecker.checkAccess(wdsLicenseCheckerCallback);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // The activity is about to be destroyed.
        if( wdsLicenseChecker!=null ){
            wdsLicenseChecker.onDestroy();
        }
    }
}
Sample code for bouncing to your main Activity:
    private void bounceToMainActivity() {
        /*
        * Make hacker's life a little bit harder here. Add some status checks and hidden key parameters
        * before starting MainAppActivity. In MainAppActivity validate them again.
        * For example to use preferences that are shared across multiple application activities,
        * you can use the Context.getSharedPreferences() method.
        * For the fun:
        */
        ApplicationInfo info = getApplication().getApplicationInfo();
        boolean isDebuggable =  ( 0 != ( info.flags &= ApplicationInfo.FLAG_DEBUGGABLE ) );
        if( isDebuggable ){
            showDialog(0);    // Do not let them use debugger tools
            return;
        }
        startActivity(new Intent(this, MainAppActivity.class));  
        finish();
    }