DroidForums.net is the original Verizon Android Forum! Registered Users do not see these ads. Please Register - It's Free!
Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Market License - Easy Implementation to Protect Your Apps

  1. Senior Droid
    neubanks89's Avatar
    Member #
    16335
    Join Date
    Dec 2009
    Posts
    130
    Phone
    Droid
    #1

    Market License - Easy Implementation to Protect Your Apps

    I just finished license protecting all my apps using Google's relatively new license service. I've developed an easy way to manage this in all your applications without having to mess with any of your apps actual source code.

    Before you start, Make you have included the license library in your project as explained here:
    Licensing Your Applications | Android Developers

    1. Make a new Activity in your project called LicenseCheck.java

    2. Paste the following in that activity:

    Code:
    /**
     * @author Nick Eubanks
     * 
     * Copyright (C) 2010 Android Infinity (http://www.androidinfinity.com)
     *
     */
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.app.Dialog;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.Settings.Secure;
    import android.widget.Toast;
    
    import com.android.vending.licensing.AESObfuscator;
    import com.android.vending.licensing.LicenseChecker;
    import com.android.vending.licensing.LicenseCheckerCallback;
    import com.android.vending.licensing.ServerManagedPolicy;
    
    /**
     * NOTES ON USING THIS LICENSE FILE IN YOUR APPLICATION: 
     * 1. Define the package
     * of you application above 
     * 2. Be sure your public key is set properly  @BASE64_PUBLIC_KEY
     * 3. Change your SALT using random digits 
     * 4. Under AllowAccess, Add your previously used MainActivity 
     * 5. Add this activity to
     * your manifest and set intent filters to MAIN and LAUNCHER 
     * 6. Remove Intent Filters from previous main activity
     */
    public class LicenseCheck extends Activity {
    	private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
    		@Override
    		public void allow() {
    			if (isFinishing()) {
    				// Don't update UI if Activity is finishing.
    				return;
    			}
    			// Should allow user access.
    			startMainActivity();
    
    		}
    
    		@Override
    		public void applicationError(ApplicationErrorCode errorCode) {
    			if (isFinishing()) {
    				// Don't update UI if Activity is finishing.
    				return;
    			}
    			// 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.
    			toast("Error: " + errorCode.name());
    			startMainActivity();
    
    		}
    
    		@Override
    		public void dontAllow() {
    			if (isFinishing()) {
    				// Don't update UI if Activity is finishing.
    				return;
    			}
    
    			// 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.
    			showDialog(0);
    		}
    	}
    	private static final String BASE64_PUBLIC_KEY = "PLACE YOUR BASE KEY FROM GOOGLE HERE";
    
    	private static final byte[] SALT = new byte[] { INPUT 20 RANDOM INTEGERS HERE };
    	private LicenseChecker mChecker;
    
    	// A handler on the UI thread.
    
    	private LicenseCheckerCallback mLicenseCheckerCallback;
    
    	private void doCheck() {
    
    		mChecker.checkAccess(mLicenseCheckerCallback);
    	}
    
    	@Override
    	public void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    
    		// Try to use more data here. ANDROID_ID is a single point of attack.
    		String deviceId = Secure.getString(getContentResolver(),
    				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);
    		doCheck();
    
    	}
    
    	@Override
    	protected Dialog onCreateDialog(int id) {
    		// We have only one dialog.
    		return new AlertDialog.Builder(this)
    				.setTitle("Application Not Licensed")
    				.setCancelable(false)
    				.setMessage(
    						"This application is not licensed. Please purchase it from Android Market")
    				.setPositiveButton("Buy App",
    						new DialogInterface.OnClickListener() {
    							@Override
    							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("Exit",
    						new DialogInterface.OnClickListener() {
    							@Override
    							public void onClick(DialogInterface dialog,
    									int which) {
    								finish();
    							}
    						}).create();
    	}
    
    	@Override
    	protected void onDestroy() {
    		super.onDestroy();
    		mChecker.onDestroy();
    	}
    
    	private void startMainActivity() {
    		startActivity(new Intent(this, MainActivity.class));  //REPLACE MainActivity.class WITH YOUR APPS ORIGINAL LAUNCH ACTIVITY
    		finish();
    	}
    
    	public void toast(String string) {
    		Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
    	}
    
    }
    3. Change the Base Key to the one google provided, Place 20 random integers in the SALT, Change MainActivity.class to the Main Activity of your application.

    4. Update your Manifest File with the new activity
    Code:
    <!-- Old Launch Activity Here -->
    <activity android:label="@string/app_name" android:name=".MainActivity" />
    <!-- New License Launch Activity with all intent filters from your previous main activity -->
    <!-- Translucent.NoTitleBar is so that this activity is never shown to the user -->		
    <activity android:label="@string/app_name" android:name=".LicenseCheck"
    			android:theme="@android:style/Theme.Translucent.NoTitleBar">
    			<intent-filter>
    				<action android:name="android.intent.action.MAIN" />
    				<category android:name="android.intent.category.LAUNCHER" />
    			</intent-filter>
    		</activity>
    5. Add Permission In the manifest Tag but not in the application tag
    Code:
        </application>
    	<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
    </manifest>


    You're all done! Make sure you test it out before publishing.
  2. Droid Newbie
    Aidwe's Avatar
    Member #
    140737
    Join Date
    Nov 2010
    Posts
    1
    Phone
    Enter Current Phone Model Here
    #2
    Fantastic implementation thanks.

    One comment though:
    It wouldnt be that hard to hack a way around this. All they'd have to do is launch the MainActivity. There are ways to do this (quite easily) on some alternate homes. I would recommend setting a variable on success.

    But as i said. Great thanks
  3. Senior Droid
    neubanks89's Avatar
    Member #
    16335
    Join Date
    Dec 2009
    Posts
    130
    Phone
    Droid
    #3
    Quote Originally Posted by Aidwe View Post
    Fantastic implementation thanks.

    One comment though:
    It wouldnt be that hard to hack a way around this. All they'd have to do is launch the MainActivity. There are ways to do this (quite easily) on some alternate homes. I would recommend setting a variable on success.

    But as i said. Great thanks
    yeah, that is something I should've mentioned. This is just a quick way to get started. I recommend using the above as your main activity and make any other other activity have a requirement that it is called from that main/license activity (can easily do this via intent bundles). Now that Android 2.3's sdk automatically obfuscates your code for you, hacking apps is going to be quite a bit tougher on Android thankfully. I've already seen pirated versions of my app "Grades: Student Organizer" go down from 65% of all users not being licensed to only 40% in two months of implementing the LVL and all of those 40% are using a very outdated version.
  4. Droid Newbie
    amasson's Avatar
    Member #
    147939
    Join Date
    Dec 2010
    Location
    Montréal, Québec, Canada
    Posts
    3
    Phone
    Nexus One
    #4
    Thanks a lot for sharing this sample. This helped me implementing a protected version of my Android app.

    One thing I noticed and maybe worth to be shared here: if you implement this and just deploy the apk directly onto the phone for testing, you will just receive the error message ERROR_NOT_MARKET_MANAGED inside the applicationError(ApplicationErrorCode errorCode) method. However one your app is uploaded and available through Android Market, then the license check will proceed ok.
  5. Droid
    alostpacket's Avatar
    Member #
    13135
    Join Date
    Dec 2009
    Posts
    68
    Liked
    1 times
    Phone
    Droid
    #5

    Thumbs down

    Quote Originally Posted by amasson View Post
    Thanks a lot for sharing this sample. This helped me implementing a protected version of my Android app.

    One thing I noticed and maybe worth to be shared here: if you implement this and just deploy the apk directly onto the phone for testing, you will just receive the error message ERROR_NOT_MARKET_MANAGED inside the applicationError(ApplicationErrorCode errorCode) method. However one your app is uploaded and available through Android Market, then the license check will proceed ok.
    -edit-
    check this link:

    http://groups.google.com/group/andro...a2ed31e4c11111
    Last edited by alostpacket; 03-18-2011 at 03:24 AM.
    twitter: @alostpacket
  6. Senior Droid
    neubanks89's Avatar
    Member #
    16335
    Join Date
    Dec 2009
    Posts
    130
    Phone
    Droid
    #6
    Quote Originally Posted by amasson View Post
    Thanks a lot for sharing this sample. This helped me implementing a protected version of my Android app.

    One thing I noticed and maybe worth to be shared here: if you implement this and just deploy the apk directly onto the phone for testing, you will just receive the error message ERROR_NOT_MARKET_MANAGED inside the applicationError(ApplicationErrorCode errorCode) method. However one your app is uploaded and available through Android Market, then the license check will proceed ok.
    My development practice regarding this issue is to always device test a new version of an app with the current version number (not the user-identifible number but the incremental one). That way the response is exactly like that of a current user. Then make sure you increment that number when you make your final build. Testing that one on a device will require your publisher account's device or will depend on how you handle the not market managed error.
  7. Droid
    alostpacket's Avatar
    Member #
    13135
    Join Date
    Dec 2009
    Posts
    68
    Liked
    1 times
    Phone
    Droid
    #7
    Also it should be noted this is not a very secure way of using LVL. Google recommends you edit the classes themselves to obfuscate where the calls are made and how the responses are handled. basically changing some of the default values/constants and moving the functions around so it's harder to find where you make the license check.

    The system (as it's posted in tutorials) is circumvented by changing one easy-to-find switch statement in the decompiled bytecode.


    You then will additionally want to use something like proguard to further obfuscate.

    Finally the most secure method would be to then send the response you get from the market app to a server you control in an encrypted and signed format to process the validity of the response.

    This makes more sense if your app has assets it uses from the web.

    Thwarting pirates is no small task. The question becomes, how much do you want to put into it, and how much do you think you can convert those pirates into customers.
    twitter: @alostpacket
  8. Senior Droid
    neubanks89's Avatar
    Member #
    16335
    Join Date
    Dec 2009
    Posts
    130
    Phone
    Droid
    #8
    Quote Originally Posted by alostpacket View Post
    Also it should be noted this is not a very secure way of using LVL. Google recommends you edit the classes themselves to obfuscate where the calls are made and how the responses are handled. basically changing some of the default values/constants and moving the functions around so it's harder to find where you make the license check.

    The system (as it's posted in tutorials) is circumvented by changing one easy-to-find switch statement in the decompiled bytecode.


    You then will additionally want to use something like proguard to further obfuscate.

    Finally the most secure method would be to then send the response you get from the market app to a server you control in an encrypted and signed format to process the validity of the response.

    This makes more sense if your app has assets it uses from the web.

    Thwarting pirates is no small task. The question becomes, how much do you want to put into it, and how much do you think you can convert those pirates into customers.
    from my experimenting with using LVL it is actually better not to use it at all for my sales. About 60% of my users are using unauthorized versions of my app, all having a much more secure version of the licensing that you see above and obfuscated with pro guard. When I used LVL my return rate was about 40% and without it dropped down to around 20% because the app performed faster and never gave the user a failed license check when it actually was valid (which happens too frequently and confuses users that just purchased the app). My piracy rate did not decline no matter what prevention I used so I figured it was better for my paying customers just to not worry with it.
  9. Droid
    alostpacket's Avatar
    Member #
    13135
    Join Date
    Dec 2009
    Posts
    68
    Liked
    1 times
    Phone
    Droid
    #9
    twitter: @alostpacket
  10. Developer
    jeffv2's Avatar
    Member #
    151962
    Join Date
    Dec 2010
    Location
    south jersey
    Posts
    1,241
    Liked
    3 times
    Phone
    galaxy nexus
    DroidForums.net Developer
    #10
    I'm not saying I would do this, I'm just wondering if one could over come this by decompiling the dex file with smali and baksmali?
    I hope not..

    Sent from my Droid using Tapatalk
Page 1 of 2 12 LastLast

Links

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

Similar Threads

  1. password protect separate apps
    By xious in forum Android Applications
    Replies: 25
    Last Post: 05-14-2012, 07:34 PM
  2. Easy Root Pulled from Market
    By bophead in forum Android Hacks and Help
    Replies: 23
    Last Post: 08-13-2010, 02:41 PM
  3. Easy root app on the market?
    By alonsou in forum Android Hacks and Help
    Replies: 2
    Last Post: 08-06-2010, 11:37 AM
  4. Password protect individual apps?
    By velocity92c in forum Android General Discussions
    Replies: 8
    Last Post: 05-15-2010, 08:16 PM
  5. Baseline H.264 Incorrect implementation
    By cchatterj in forum Android Tech Support
    Replies: 0
    Last Post: 01-07-2010, 01:01 PM

Search tags for this page

android licensing example
,

android licensing tutorial

,
com.android.vending. check license
,

com.android.vending.check license

,
copyright my android app
,
do you need to license your app android
,
example implementing youtube in my android app
,
license check activity android
,
licensecheckercallback example
,
this application is not licensed please purchase it from and
Click on a term to search our site for related topics.

Tags for this Thread

Find us on Google+