Menu

Activate your Knox License

Your app activates your Knox license to authenticate API access. For more, see Knox licenses.

Use a key-value pair to define your license

With Knox 3.7.1, Independent Software Vendors (ISVs) no longer need to activate a Knox license on company-owned devices. License activation is needed only on BYOD deployments.

To activate a Knox license in Knox 3.7.1, use Android content providers as follows:

Item Description
Uri content://com.samsung.android.knox.sdk/license
ContentValues Stores values that ContentResolver can process.
put Adds a key-value pair to a data set.
key key
value (your Knox license)

Use the URI to identify the Knox license setting, define the key-value pair, and use the put method to invoke the license:

Uri uri = Uri.parse("content://com.samsung.android.knox.sdk/license");
ContentValues contentValues = new ContentValues();
contentValues.put("key", "YOUR_KNOX_LICENSE");
String selection = "key=?";
String[] selectionArgs = new String[] {""};
mContext.getContentResolver().update(uri, contentValues, selection, selectionArgs);

For more examples, see the Knox API class KnoxContract.License.

Create the License Receiver class

In your app, create a new class called SampleLicenseReceiver.java that contains a license receiver for your KPE key.

package com.samsung.knox.example.knoxworkspace;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

import com.samsung.android.knox.license.KnoxEnterpriseLicenseManager;

public class SampleLicenseReceiver extends BroadcastReceiver {

    private static final int DEFAULT_ERROR_CODE = -1;

    private void showToast(Context context, String msg) {
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent == null) {
            // No intent action is available
            showToast(context, context.getResources().getString(R.string.no_intent));
        } else {
            String action = intent.getAction();
            if (action == null) {
                // No intent action is available
                showToast(context, context.getResources().getString(R.string.no_intent_action));
            } else if (action.equals(KnoxEnterpriseLicenseManager.ACTION_LICENSE_STATUS)) {
                // ELM activation result Intent is obtained
                int errorCode = intent.getIntExtra(
                        KnoxEnterpriseLicenseManager.EXTRA_LICENSE_ERROR_CODE, DEFAULT_ERROR_CODE);

                if (errorCode == KnoxEnterpriseLicenseManager.ERROR_NONE) {
                    // ELM activated successfully
                    showToast(context, context.getResources().getString(R.string.kpe_activated_succesfully));
                    Log.d("SampleLicenseReceiver", context.getString(R.string.kpe_activated_succesfully));
                } else {
                    // KPE activation failed
                    // Display KPE error message
                    String errorMessage = getKPEErrorMessage(context, intent, errorCode);
                    showToast(context, errorMessage);
                    Log.d("SampleLicenseReceiver", errorMessage);
                }
            }
        }
    }

    private String getKPEErrorMessage(Context context, Intent intent, int errorCode) {
        String message;
        switch (errorCode) {
            case KnoxEnterpriseLicenseManager.ERROR_INTERNAL:
                message = context.getResources().getString(R.string.err_kpe_internal);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_INTERNAL_SERVER:
                message = context.getResources().getString(R.string.err_kpe_internal_server);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_INVALID_LICENSE:
                message = context.getResources().getString(R.string.err_kpe_licence_invalid_license);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_INVALID_PACKAGE_NAME:
                message = context.getResources().getString(R.string.err_kpe_invalid_package_name);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_TERMINATED:
                message = context.getResources().getString(R.string.err_kpe_licence_terminated);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_NETWORK_DISCONNECTED:
                message = context.getResources().getString(R.string.err_kpe_network_disconnected);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_NETWORK_GENERAL:
                message = context.getResources().getString(R.string.err_kpe_network_general);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_NOT_CURRENT_DATE:
                message = context.getResources().getString(R.string.err_kpe_not_current_date);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_NULL_PARAMS:
                message = context.getResources().getString(R.string.err_kpe_null_params);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_UNKNOWN:
                message = context.getResources().getString(R.string.err_kpe_unknown);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_USER_DISAGREES_LICENSE_AGREEMENT:
                message = context.getResources().getString(R.string.err_kpe_user_disagrees_license_agreement);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_DEACTIVATED:
                message = context.getResources().getString(R.string.err_kpe_license_deactivated);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_EXPIRED:
                message = context.getResources().getString(R.string.err_kpe_license_expired);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_QUANTITY_EXHAUSTED:
                message = context.getResources().getString(R.string.err_kpe_license_quantity_exhausted);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_ACTIVATION_NOT_FOUND:
                message = context.getResources().getString(R.string.err_kpe_license_activation_not_found);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_QUANTITY_EXHAUSTED_ON_AUTO_RELEASE:
                message = context.getResources().getString(R.string.err_kpe_license_quantity_exhausted_on_auto_release);
                break;

            default:
                // Unknown error code
                String errorStatus = intent.getStringExtra(
                        KnoxEnterpriseLicenseManager.EXTRA_LICENSE_STATUS);
                message = context.getResources()
                                .getString(R.string.err_kpe_code_unknown, Integer.toString(errorCode), errorStatus);
        }
        return message;
    }
}

Register the License Receiver class

When the KPE license is validated, the com.samsung.android.knox.intent.action.KNOX_LICENSE_STATUS intent is emitted. The app uses the SampleLicenseReceiver class to intercept this intent.

Paste this code in AndroidManifest.xml to define the receiver for com.samsung.android.knox.intent.action.KNOX_LICENSE_STATUS intents:

<receiver android:name=".SampleLicenseReceiver" >
    <intent-filter>
        <action android:name="com.samsung.android.knox.intent.action.KNOX_LICENSE_STATUS" />
    </intent-filter>
</receiver>

When your app receives a com.samsung.android.knox.intent.action.KNOX_LICENSE_STATUS intent, it passes the intent to SampleLicenseReceiver.onReceive(). Use this method to have your app respond to the license activation.

Activate the license

Use this method in your MainActivity to activate the license.

private void activateLicense() {
    // Instantiate the KnoxEnterpriseLicenseManager class to use the activateLicense method
    KnoxEnterpriseLicenseManager licenseManager = KnoxEnterpriseLicenseManager.getInstance(this);
    // License Activation TODO Add license key to Constants.java
    licenseManager.activateLicense(Constants.KPE_LICENSE_KEY);
    mUtils.log(getResources().getString(R.string.license_progress));
}

When you launch the app for the first time and activate the license, you will see a Samsung confirmation dialog. This only appears once per license activation. Agree to the terms and conditions and tap CONFIRM.

There are three terms that are important when it comes to licenses that you can receive in the KnoxEnterpriseLicenseManager.ACTION_LICENSE_STATUS broadcast:

  1. Activation - Initial license activation (Constant is integer 800)
  2. Deactivation - License deactivation (Constant is integer 802)
  3. Validation - Once or twice a day, the license agent checks to see if the license is still valid. For example, if it expires before a validation check is made, the license agent returns a value that indicates license expiration. (Constant is integer 801)

Below is the block of code from the Broadcast receiver that catches the license activation:

if (action.equals(KnoxEnterpriseLicenseManager.ACTION_LICENSE_STATUS)) {
    String status = intent.getStringExtra(KnoxEnterpriseLicenseManager.EXTRA_LICENSE_STATUS);
    int errorCode = intent.getIntExtra(KnoxEnterpriseLicenseManager.EXTRA_LICENSE_ERROR_CODE, 1);
    int extraResult = intent.getIntExtra(KnoxEnterpriseLicenseManager.EXTRA_LICENSE_RESULT_TYPE, 1);
    toast.setText("KLM Status = " + status + ",  " + "Error Code= " + errorCode + ",  " + "Extra Result Type= " + extraResult);
    toast.show();
    Log.d(TAG, "KLM Status = " + status + ",  " + "Error Code= " + errorCode + ",  " + "Extra Result Type= " + extraResult);
}

For example, if a validation request is made and passes, the following toast appears:

KLM Status = Success, Error Code = 0, Extra Result Type = 801

Create the License Receiver class

In your app, create a new class called SampleLicenseReceiver.java, which contains a license receiver for your KPE and backwards-compatible keys.

The KnoxEnterpriseLicenseManager class is used to receive the KPE key, while the EnterpriseLicenseManager class is used to receive the backwards-compatible key.

package com.samsung.knox.example.gettingstarted;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

import com.samsung.android.knox.license.KnoxEnterpriseLicenseManager;
import com.samsung.android.knox.license.EnterpriseLicenseManager;

public class SampleLicenseReceiver extends BroadcastReceiver {

    private static final int DEFAULT_ERROR_CODE = -1;

    private void showToast(Context context, String msg) {
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent == null) {
            // No intent action is available
            showToast(context, context.getResources().getString(R.string.no_intent));
        } else {
            String action = intent.getAction();
            if (action == null) {
                // No intent action is available
                showToast(context, context.getResources().getString(R.string.no_intent_action));
            } else if (action.equals(KnoxEnterpriseLicenseManager.ACTION_LICENSE_STATUS)) {
                // ELM activation result Intent is obtained
                int errorCode = intent.getIntExtra(
                        KnoxEnterpriseLicenseManager.EXTRA_LICENSE_ERROR_CODE, DEFAULT_ERROR_CODE);

                if (errorCode == KnoxEnterpriseLicenseManager.ERROR_NONE) {
                    // ELM activated successfully
                    showToast(context, context.getResources().getString(R.string.kpe_activated_succesfully));
                    Log.d("SampleLicenseReceiver", context.getString(R.string.kpe_activated_succesfully));
                } else {
                    // KPE activation failed
                    // Display KPE error message
                    String errorMessage = getKPEErrorMessage(context, intent, errorCode);
                    showToast(context, errorMessage);
                    Log.d("SampleLicenseReceiver", errorMessage);
                }
            } else if (action.equals(EnterpriseLicenseManager.ACTION_LICENSE_STATUS)) {
                // Backwards-compatible key activation result Intent is obtained
                int errorCode = intent.getIntExtra(
                        EnterpriseLicenseManager.EXTRA_LICENSE_ERROR_CODE, DEFAULT_ERROR_CODE);

                if (errorCode == EnterpriseLicenseManager.ERROR_NONE) {
                    // Backwards-compatible key activated successfully
                    showToast(context, context.getResources().getString(R.string.elm_action_successful));
                    Log.d("SampleLicenseReceiver", context.getString(R.string.elm_action_successful));
                } else {
                    // Backwards-compatible key activation failed
                    // Display backwards-compatible key error message
                    String errorMessage = getELMErrorMessage(context, intent, errorCode);
                    showToast(context, errorMessage);
                    Log.d("SampleLicenseReceiver", errorMessage);
                }
            }
        }
    }

    private String getELMErrorMessage(Context context, Intent intent, int errorCode) {
        String message;
        switch (errorCode) {
            case EnterpriseLicenseManager.ERROR_INTERNAL:
                message = context.getResources().getString(R.string.err_elm_internal);
                break;
            case EnterpriseLicenseManager.ERROR_INTERNAL_SERVER:
                message = context.getResources().getString(R.string.err_elm_internal_server);
                break;
            case EnterpriseLicenseManager.ERROR_INVALID_LICENSE:
                message = context.getResources().getString(R.string.err_elm_licence_invalid_license);
                break;
            case EnterpriseLicenseManager.ERROR_INVALID_PACKAGE_NAME:
                message = context.getResources().getString(R.string.err_elm_invalid_package_name);
                break;
            case EnterpriseLicenseManager.ERROR_LICENSE_TERMINATED:
                message = context.getResources().getString(R.string.err_elm_licence_terminated);
                break;
            case EnterpriseLicenseManager.ERROR_NETWORK_DISCONNECTED:
                message = context.getResources().getString(R.string.err_elm_network_disconnected);
                break;
            case EnterpriseLicenseManager.ERROR_NETWORK_GENERAL:
                message = context.getResources().getString(R.string.err_elm_network_general);
                break;
            case EnterpriseLicenseManager.ERROR_NOT_CURRENT_DATE:
                message = context.getResources().getString(R.string.err_elm_not_current_date);
                break;
            case EnterpriseLicenseManager.ERROR_NULL_PARAMS:
                message = context.getResources().getString(R.string.err_elm_null_params);
                break;
            case EnterpriseLicenseManager.ERROR_SIGNATURE_MISMATCH:
                message = context.getResources().getString(R.string.err_elm_sig_mismatch);
                break;
            case EnterpriseLicenseManager.ERROR_UNKNOWN:
                message = context.getResources().getString(R.string.err_elm_unknown);
                break;
            case EnterpriseLicenseManager.ERROR_USER_DISAGREES_LICENSE_AGREEMENT:
                message = context.getResources().getString(R.string.err_elm_user_disagrees_license_agreement);
                break;
            case EnterpriseLicenseManager.ERROR_VERSION_CODE_MISMATCH:
                message = context.getResources().getString(R.string.err_elm_ver_code_mismatch);
                break;

            default:
                // Unknown error code
                String errorStatus = intent.getStringExtra(
                        EnterpriseLicenseManager.EXTRA_LICENSE_STATUS);
                message = context.getResources()
                        .getString(R.string.err_elm_code_unknown, Integer.toString(errorCode), errorStatus);
        }
        return message;
    }

    private String getKPEErrorMessage(Context context, Intent intent, int errorCode) {
        String message;
        switch (errorCode) {
            case KnoxEnterpriseLicenseManager.ERROR_INTERNAL:
                message = context.getResources().getString(R.string.err_kpe_internal);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_INTERNAL_SERVER:
                message = context.getResources().getString(R.string.err_kpe_internal_server);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_INVALID_LICENSE:
                message = context.getResources().getString(R.string.err_kpe_licence_invalid_license);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_INVALID_PACKAGE_NAME:
                message = context.getResources().getString(R.string.err_kpe_invalid_package_name);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_TERMINATED:
                message = context.getResources().getString(R.string.err_kpe_licence_terminated);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_NETWORK_DISCONNECTED:
                message = context.getResources().getString(R.string.err_kpe_network_disconnected);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_NETWORK_GENERAL:
                message = context.getResources().getString(R.string.err_kpe_network_general);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_NOT_CURRENT_DATE:
                message = context.getResources().getString(R.string.err_kpe_not_current_date);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_NULL_PARAMS:
                message = context.getResources().getString(R.string.err_kpe_null_params);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_UNKNOWN:
                message = context.getResources().getString(R.string.err_kpe_unknown);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_USER_DISAGREES_LICENSE_AGREEMENT:
                message = context.getResources().getString(R.string.err_kpe_user_disagrees_license_agreement);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_DEACTIVATED:
                message = context.getResources().getString(R.string.err_kpe_license_deactivated);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_EXPIRED:
                message = context.getResources().getString(R.string.err_kpe_license_expired);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_QUANTITY_EXHAUSTED:
                message = context.getResources().getString(R.string.err_kpe_license_quantity_exhausted);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_ACTIVATION_NOT_FOUND:
                message = context.getResources().getString(R.string.err_kpe_license_activation_not_found);
                break;
            case KnoxEnterpriseLicenseManager.ERROR_LICENSE_QUANTITY_EXHAUSTED_ON_AUTO_RELEASE:
                message = context.getResources().getString(R.string.err_kpe_license_quantity_exhausted_on_auto_release);
                break;

            default:
                // Unknown error code
                String errorStatus = intent.getStringExtra(
                        KnoxEnterpriseLicenseManager.EXTRA_LICENSE_STATUS);
                message = context.getResources()
                        .getString(R.string.err_kpe_code_unknown, Integer.toString(errorCode), errorStatus);
        }
        return message;
    }
}

Register the License Receiver class

Devices running Knox versions 2.5 to 2.7.1 / Knox API 17 to 21 will need to activate a backwards-compatible license key in addition to the KPE license key. When the KPE key is validated, the com.samsung.android.knox.intent.action.KNOX_LICENSE_STATUS intent is emitted. Upon validation of the backwards-compatible key, the com.samsung.android.knox.intent.action.LICENSE_STATUS intent is emitted. The app uses the SampleLicenseReceiver class to intercept this intent.

Paste this code in AndroidManifest.xml to define the receiver for com.samsung.android.knox.intent.action.LICENSE_STATUS intents:

<receiver android:name=".SampleLicenseReceiver" >
    <intent-filter>
        <action android:name="com.samsung.android.knox.intent.action.KNOX_LICENSE_STATUS" />
		<action android:name="com.samsung.android.knox.intent.action.LICENSE_STATUS" />
    </intent-filter>
</receiver>

When your app receives the com.samsung.android.knox.intent.action.KNOX_LICENSE_STATUS and the com.samsung.android.knox.intent.action.LICENSE_STATUS intents, it passes the intents to SampleLicenseReceiver.onReceive(). Use this method to have your app respond to the license activation.

Activate the license

Use this method in your MainActivity to activate the license.

private void activateLicense() {
    // Instantiate the KnoxEnterpriseLicenseManager class to use the activateLicense method
    KnoxEnterpriseLicenseManager licenseManager = KnoxEnterpriseLicenseManager.getInstance(this);
    // License Activation TODO Add license key to Constants.java
    licenseManager.activateLicense(Constants.KPE_LICENSE_KEY);
    mUtils.log(getResources().getString(R.string.license_progress));
}

// call backwards-compatible key activation
private void activateBackwardsCompatibleKey() {
    // Get an instance of the License Manager
    EnterpriseLicenseManager backwardsCompatibleKeyManager = EnterpriseLicenseManager.getInstance(this);
    // Activate the backwards-compatible license key
    backwardsCompatibleKeyManager.activateLicense(Constants.BACKWARDS_COMPATIBLE_KEY);
    mUtils.log(getResources().getString(R.string.backwards_compatible_key_activation));
}

When you launch the app for the first time and activate the license, you will see a Samsung confirmation dialog. This only appears once per license activation. Agree to the terms and conditions and tap CONFIRM.

There are three terms that are important when it comes to licenses that you can receive in the KnoxEnterpriseLicenseManager.ACTION_LICENSE_STATUS broadcast:

  1. Activation - Initial license activation (Constant is integer 800)
  2. Deactivation - License deactivation (Constant is integer 802)
  3. Validation - Once or twice a day, the license agent checks to see if the license is still valid. For example, if it expires before a validation check is made, the license agent returns a value that indicates license expiration. (Constant is integer 801)

Below is the block of code from the Broadcast receiver that catches the license activation:

if (action.equals(KnoxEnterpriseLicenseManager.ACTION_LICENSE_STATUS)) {
    String status = intent.getStringExtra(KnoxEnterpriseLicenseManager.EXTRA_LICENSE_STATUS);
    int errorCode = intent.getIntExtra(KnoxEnterpriseLicenseManager.EXTRA_LICENSE_ERROR_CODE, 1);
    int extraResult = intent.getIntExtra(KnoxEnterpriseLicenseManager.EXTRA_LICENSE_RESULT_TYPE, 1);
    toast.setText("KLM Status = " + status + ",  " + "Error Code= " + errorCode + ",  " + "Extra Result Type= " + extraResult);
    toast.show();
    Log.d(TAG, "KLM Status = " + status + ",  " + "Error Code= " + errorCode + ",  " + "Extra Result Type= " + extraResult);
}

For example, if a validation request is made and passes, the following toast appears:

KLM Status = Success, Error Code = 0, Extra Result Type = 801

See also: