Using the Android licensing service step by step



Google has deprecated the copy protection on paid apps and is recommending everybody use the new licensing service instead. One of the big benefits you get by removing the copy protection and using the license service is the ability to enable the move to sd card for your application. This is more important if you are developing a game with images and sounds as these files can quickly make your application very large.

I recently modified all our applications to use the licensing server and it was a lot easier than I expected. I have created a Intellij IDEA .iml module for the licensing service and I just need to include this my application that I want to use it in. So here are the steps that I took to add this to my application

1. First you have to use the Android SDK manager and choose ‘Available Packages’ on left, than select the android repository and click refresh. You should see ‘Market Licensing package, revision 1′ . You will need to go ahead with the install of this package. After this is complete you should see it in the list of Installed Packages as shown in the image below

2. Now you will have a new directory called market_licensing in your android SDK folder. Copy this folder to a new location where you will create a module for it.

NOTE: You only have to do this part one time…

3. Open your Android application and from the menu choose File -> New Module. Choose create module from scratch. Choose the location of your market_licensing/library directory you copied from the SDK.  Once you import the new module you will need to go to the properties of your application and add the library module as a dependency.

4. Add these values to your project in res/values/strings.xml


<string name="check_license">Check license</string>
<string name="checking_license">Checking license...</string>
<string name="dont_allow">Don\'t allow the user access</string>
<string name="allow">Allow the user access</string>
<string name="application_error">Application error: %1$s</string>
<!-- Unlicensed dialog messages -->
<string name="unlicensed_dialog_title">Application not licensed</string>
<string name="unlicensed_dialog_body">This application is not licensed. Please purchase it from Android Market.</string>
<string name="buy_button">Buy app</string>
<string name="quit_button">Exit</string>

5. Add the following permission to your AndroidManifest.xml. In addition I have an example here of how you enable the move to sdcard with the android:installLocation. You also have to target at least API level 3 in in the android:minSdkVersion

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="your.package.name"
          android:versionCode="1"
          android:versionName="1.0.0"
        android:installLocation="auto">
 
    <uses-sdk android:minSdkVersion="3"/>
 
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
 
</manifest>

6. Create a new java class in your project called LicenseCheckActivity. Below is the code that will go in that class. This is just a slightly modified version that is provided by the google example

that is provided by the google example

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.TextView;
import com.android.vending.licensing.*;
 
public abstract class LicenseCheckActivity extends Activity {
 
    static boolean licensed = true;
    static boolean didCheck = false;
    static boolean checkingLicense = false;
    static final String BASE64_PUBLIC_KEY = "REPLACE WITH YOUR KEY FROM PUBLISHER CONSOLE";
 
    LicenseCheckerCallback mLicenseCheckerCallback;
    LicenseChecker mChecker;
 
    Handler mHandler;
 
    SharedPreferences prefs;
 
    // REPLACE WITH YOUR OWN SALT , THIS IS FROM EXAMPLE
    private static final byte[] SALT = new byte[]{
            -46, 65, 30, -128, -103, -57, 74, -64, 51, 88, -95, -45, 77, -117, -36, -113, -11, 32, -64,
            89
    };
 
    private void displayResult(final String result) {
        mHandler.post(new Runnable() {
            public void run() {
 
                setProgressBarIndeterminateVisibility(false);
 
            }
        });
    }
 
    protected void doCheck() {
 
        didCheck = false;
        checkingLicense = true;
        setProgressBarIndeterminateVisibility(true);
 
        mChecker.checkAccess(mLicenseCheckerCallback);
    }
 
    protected void checkLicense() {
 
        Log.i("LICENSE", "checkLicense");
        mHandler = new Handler();
 
        // Try to use more data here. ANDROID_ID is a single point of attack.
        String deviceId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
 
        // Library calls this when it's done.
        mLicenseCheckerCallback = new MyLicenseCheckerCallback();
        // Construct the LicenseChecker with a policy.
        mChecker = new LicenseChecker(
                this, new ServerManagedPolicy(this,
                        new AESObfuscator(SALT, getPackageName(), deviceId)),
                BASE64_PUBLIC_KEY);
 
//        mChecker = new LicenseChecker(
//                this, new StrictPolicy(),
//                BASE64_PUBLIC_KEY);
 
        doCheck();
    }
 
    protected class MyLicenseCheckerCallback implements LicenseCheckerCallback {
 
        public void allow() {
            Log.i("LICENSE", "allow");
            if (isFinishing()) {
                // Don't update UI if Activity is finishing.
                return;
            }
            // Should allow user access.
            displayResult(getString(R.string.allow));
            licensed = true;
            checkingLicense = false;
            didCheck = true;
 
        }
 
        public void dontAllow() {
            Log.i("LICENSE", "dontAllow");
            if (isFinishing()) {
                // Don't update UI if Activity is finishing.
                return;
            }
            displayResult(getString(R.string.dont_allow));
            licensed = false;
            // Should not allow access. In most cases, the app should assume
            // the user has access unless it encounters this. If it does,
            // the app should inform the user of their unlicensed ways
            // and then either shut down the app or limit the user to a
            // restricted set of features.
            // In this example, we show a dialog that takes the user to Market.
            checkingLicense = false;
            didCheck = true;
 
            showDialog(0);
        }
 
        public void applicationError(ApplicationErrorCode errorCode) {
            Log.i("LICENSE", "error: " + errorCode);
            if (isFinishing()) {
                // Don't update UI if Activity is finishing.
                return;
            }
            licensed = false;
            // This is a polite way of saying the developer made a mistake
            // while setting up or calling the license checker library.
            // Please examine the error code and fix the error.
            String result = String.format(getString(R.string.application_error), errorCode);
            checkingLicense = false;
            didCheck = true;
 
            //displayResult(result);
            showDialog(0);
        }
    }
 
    protected Dialog onCreateDialog(int id) {
        // We have only one dialog.
        return new AlertDialog.Builder(this)
                .setTitle(R.string.unlicensed_dialog_title)
                .setMessage(R.string.unlicensed_dialog_body)
                .setPositiveButton(R.string.buy_button, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(
                                "http://market.android.com/details?id=" + getPackageName()));
                        startActivity(marketIntent);
                        finish();
                    }
                })
                .setNegativeButton(R.string.quit_button, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                })
 
                .setCancelable(false)
                .setOnKeyListener(new DialogInterface.OnKeyListener(){
                    public boolean onKey(DialogInterface dialogInterface, int i, KeyEvent keyEvent) {
                        Log.i("License", "Key Listener");
                        finish();
                        return true;
                    }
                })
                .create();
 
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mChecker != null) {
            Log.i("LIcense", "distroy checker");
            mChecker.onDestroy();
        }
    }
 
}


7. Now change your starting activity to extend LicenseCheckActivity. Modify  the  onCreate(Bundle savedInstanceState) by adding  the following code after you set the content view.

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
 
            Toast.makeText(this, "Checking Application License", Toast.LENGTH_SHORT).show();
            // Check the license
            checkLicense();
 
.........

Now for any future projects all you will need to do is:
- include the module, which has already created so when you go to File -> New Module you will choose import existing module and point to the IDEA .iml file
- Add the LicenseCheckActivity and extend it
- Add the call to checkLicense() in the onCreate method

Now you can test on your device or emulator


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值