SUBSCRIPTIONS CODING RECOMMENDATIONS

***This page has been removed from the VDC due to the Verizon Apps shutdown. Feel free to browse our other development areasdevicesAPIs and Tools.***

VERIZON APPS SUNSET

***NOTE: Effective November 1st, 2012, the VDC no longer accepts new Verizon App submissions. Additionally, beginning December 2012, final billing to customers for all existing Subscriptions and In-App Purchase apps will occur, and all paid Subscriptions and In-App Purchase API apps will be removed from the catalog on November 1st, 2012. Customers will receive a final full month of use & access, before Verizon Apps begins its complete shutdown in January 2013.

For additional details, please review the Verizon Apps Notice and Verizon Apps Transition Timeline.***

SUBSCRIPTIONS API

The following sections detail usage of the Subscriptions API.  Note that if you’ve incorporated the previous API in your app the checkLicense method has been deprecated and replaced with the checkContentLicense method.  The new method returns an object that has the same result codes as checkLicense but additional capability to grab the returned license as a string that can be manipulated as developers see fit.

ANDROID MANIFEST PERMISSIONS

In order for the application to access Verizon Apps to perform the license check, permissions must be set in the manifest file.  Simply paste the following permissions into the AndroidManifest.xml file before the closing manifest tag:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.START_BACKGROUND_SERVICE"/>
<uses-permission android:name="com.verizon.vcast.apps.VCAST_APPS_LICENSE_SERVICE"/>

USING THE LICENSEAUTHENTICATOR CLASS

Verizon Wireless designed the Subscriptions API to be simple and lightweight.  Once you've configured Eclipse with the SDK as explained in the "Setting Up Eclipse IDE" section, there are only two lines of code you need to add to your app that do all the heavy lifting of license validation behind the scenes.  Add these lines and spawn a thread during app startup in onCreate:

 

LicenseAuthenticator licenseAuthenticator = new LicenseAuthenticator();

LicenseAuthenticator.CheckLicenseResult = licenseAuthenticator.checkContentLicense(keyword);

 

Depending on the return value of this method call, the app should either continue with regular startup or message the end user that the license isn’t valid and exit.  Using this functionality, developers can ensure their apps have been legitimately purchased from Verizon Apps.

The API has one additional method named checkTestContentLicense that can be used to hardcode the return value you want to see in your application for testing purposes. Just make sure to change all test calls back to checkContentLicense(<your_app_keyword_value>) before submission.

The only remaining consideration is how to handle the return codes provided by the API. A detailed list of all the API return codes and what they signify is contained in the Field summary of the LicenseAuthenticator javadocs in the SDK download.

HOW LICENSES WORK AND WHEN TO CALL CHECKLICENSE

Licenses are tied to end users by the associated user phone number and are stored on the device. The license will expire on an interval that depends on the purchase type made by the end user and are refreshed over the network when expired. As a result, don't expect the checkContentLicense method call to always return immediately and design your application around this accordingly.

Regardless of how you incorporate the API in your code you should always call checkContentLicense in a thread and process the return value of the method call before allowing the end user to use all the functionality of your application. If you don’t call checkContentLicense in a thread it is possible that your app may fail testing.

For example, on the Android platform if you call checkLicense in the onCreate method as a standard method call and the license service needs to access the network to acquire a new license, the process could take a significant amount of time and could cause the OS to force close your app since it is holding the main UI thread. Refer to the sample apps in the SDK as well as the Android threading recommendations in below.

CHECKCONTENTLICENSE vs CHECKTESTCONTENTLICENSE METHODS

The checkContentLicense method call interacts with the Verizon Apps client to contact the Verizon Apps server infrastructure and process the license check. Thus, the only time you should call checkContentLicense is within code that will be installed on an actual device with a Subscriptions API enabled Verizon Apps client. For applications that are still being tested on simulators or devices that do not have the Subscriptions API enabled Verizon Apps client, you should only use the checkTestContentLicense method.

The point must be stressed that you should always make sure that calls to checkTestContentLicense are replaced with calls to checkContentLicense before compiling and submitting applications with the embedded Subscriptions code

HANDLING LICENSE STATUS CODES

There are a total of twelve possible License Status Codes returned by the Subscriptions API however developers should focus on the following three codes that will be returned most often and are core to permitting or denying access to your app:

  • LICENSE_OK: license has been checked and is valid - proceed with normal launch
  • LICENSE_TRIAL_OK: license has been checked, is both valid and a trial license.
  • LICENSE_NOT_FOUND: license has been checked and is not valid. - Verizon Apps is invoked to your display app for repurchase automatically and you should exit your app gracefully.

The remaining codes are errors and can be handled in a variety of ways by developers but as a rule, receiving an error code should ultimately result in the application exiting gracefully after displaying a detailed message to the end user in the form of a pop-up, Dialog box, etc.

For example, if you are concerned your end users' license might expire when they are in an area where they won't have Verizon coverage, such as an airplane or remote area, then handle the error return code ERROR_UNABLE_TO_CONNECT_TO_CDS and display a specific message to them that service is unavailable and they should attempt to use the app again later.

Any codes that are returned other than LICENSE_OK, LICENSE_NOT_FOUND, and LICENSE_TRIAL_OK are errors and you should display a detailed message to the end user then quit the application. You should be as descriptive as possible to the end user if you receive one of these error codes - use the javadocs as guidance for possible messages.

Additionally, you should make sure that the end user acknowledges the message otherwise they might not understand why your application stopped running.

Refer to the javadocs for specific recommendations and details of these error codes.

TRIAL APPLICATIONS

Trial and full applications should be contained in a single binary that is submitted to the store. Your app should look for the return value ‘LICENSE_TRIAL_OK’ from the checkContentLicense method which is an indicator that the end user has a valid license and that it is a trial license.

If you have submitted a single application to the store that has the trial version and full version in a single binary then the application code should look for this return value and it should be used to make decisions within your application. For example, a developer application that streams video might display only limited trial content unless the end user has purchased the full version:

LicenseAuthenticator licenseAuthenticator = new LicenseAuthenticator();

LicenseAuthenticator.CheckLicenseResult = licenseAuthenticator.checkContentLicense(keyword);

int licenseStatus = LicenseAuthenticator.CheckLicenseResult.getResult();

 switch(licenseStatus)

{

    // Full license was validated

    case LicenseAuthenticator.LICENSE_OK:

    // Proceed with displaying full video content

    // Trial license validated

    case LicenseAuthenticator.TRIAL_LICENSE_OK:

    // Proceed with displaying trial video content ….

}

ANDROID THREADING

It is required to call checkLicense in a thread on the Android platform otherwise in certain situations the OS will force close your application and you won’t successfully pass testing.   Refer to the sample code below (and in the sample app in the SDK) from an onCreate method and model your application code accordingly:

@Override

        public void onCreate(Bundle savedInstanceState)

        {

            super.onCreate(savedInstanceState);

            LinearLayout mainLayout = new LinearLayout(this);

            mainLayout.setOrientation(1);

 

            String licText = "Checking license: " + keyword;

            tView1 = new TextView( this);

            tView1.setText( licText);

            mainLayout.addView( tView1);

            setContentView( mainLayout);

 

            // Because checkLicense() is a potentially long-running synchronous operation,

            // we must perform it on its own thread instead of the main UI thread.

            new Thread() {

                public void run() {

                    licValidator = new LicenseAuthenticator( HelloSubscription.this);

                    final int isLicValid = licValidator.checkLicense( keyword);

                    String licText = "Not a recognized licText code: " + isLicValid;

                    switch (isLicValid) {

                        case LicenseAuthenticator.LICENSE_OK:

                            licText = "LICENSE_OK!";

                            break;

                        case LicenseAuthenticator.LICENSE_VALIDATION_FAILED:

                            licText = "LICENSE_VALIDATION_FAILED";

                            break;

                    ……..

SHOWING ERROR MESSAGES

Using AlertDialog boxes is suggested over Toast since the Dialogs are persistent until the user acknowledges the message.  First, define the onCreateDialog(int) callback method using a switch statement that uses the License Status Code to determine the message to pass to the end user (refer to the Android Sample App for more details):

protected Dialog onCreateDialog(int id) {
AlertDialog.Builder msg = new AlertDialog.Builder(this);

switch (id) {

    case LicenseAuthenticator.ITEM_NOT_FOUND:

        msg.setMessage("This item is not available for your device\n
        or no longer available in the Verizon Apps catalog. Application will now exit ");
        break;//exit gracefully

    case LicenseAuthenticator.LICENSE_VALIDATION_FAILED:

        msg.setMessage("You have not purchased this application\n
    or purchase period has expired. Launch Verizon Apps client to purchase. Application will       now exit ");
        break; //exit gracefully

Next, set a PositiveButton on the Builder so the user can acknowledge the message, then call the Builder create() method to instantiate the box and return the AlertDialog from the onCreateDialog method:

msg.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {

}
});

AlertDialog dialog =msg.create();
return dialog;

Create a Runnable that will be used to call the showDialog() method and a Handler for the Runnable so the Dialog box will be shown in the main UI thread:

private Runnable dialogRun = new Runnable() {
public void run() {
    showDialog(retVal);
}
};

private Handler licHandler = new Handler();

Finally, from the background Thread, call the checkLicense method with the keyword and pass the Runnable you created to the Handler through the post method:

licenseLib = new LicenseAuthenticator( this );

new Thread() {
    public void run() {
        try {

            retVal = licenseLib.checkLicense( "keyword" );
            licHandler.post(dialogRun);

        } catch (Throwable e) {
        e.printStackTrace();
        }
    }
}.start();

Any further questions please email us at VCast-apps@verizonwireless.com