So .. License Server came out about a week ago. When I heard about that I was all, “eh, more DRM, why bother, the users won’t see any benefit, so it’s not worth my time.” Turns out I got that wrong! There are actually several concrete benefits to the user by using the License Server (which I found within a day of releasing Galcon due to the quantity of emails from users explaining my failure to care about them!) If you use the “Copy Protection” feature of the Android Marketplace publisher, you do two things to the user:
- The app will take up twice as much room.
- The app cannot be stored on the user’s SD card.
I covered some of this in a previous blog, but the users memory is very limited, so over utilizing it is a “bad thing”!
The documentation for the Licensing Server is really really long looking, but there isn’t that much you have to do, actually. You’ll probably want to read it, but if you want the synopsis of what you actually end up having to do, here it is:
Step 1: Install the LVL SDK.
You just power up the SDK installer software and find the “Market Licensing package” and install that.
Step 2: Copying the LVL SDK into your project.
Just copy path/to/android/market_licensing/library/src/* into your local src/ folder. The SDK isn’t part of the Android platform, so you have to include it in your own codebase.
Step 3: Get your app to check the license using a Policy.
You can do some complicated things, but the documentation says, “… don’t do that. Just use the included ServerManagedPolicy or StrictPolicy.” I’m going to use the ServerManagedPolicy because that doesn’t require the user to ALWAYS be on-line to use your App. The StrictPolicy only works when the user is on-line and checks the license every time.
At this point, you’ll want to just go find path/to/android/market_licensing/sample and check out the source there. It includes an example that will pop up a dialog to send the users off to buy your app if they don’t have it licensed properly. This seems to be pretty much what I want, so I’ll just copy-n-paste from that.
- To grab your public key go to http://market.android.com/publish/ and click on “Edit Profile” and your key is at the bottom of the page.
- You’ll (maybe) want to grab the example res/values/strings.xml and paste the Licensing related strings into your own strings.xml
- applicationError(ApplicationErrorCode errorCode) should call dontAllow()
- add finish() after the app goes to the market Intent. This way, they can’t go back to the app and get pestered about buying it again. They will have to restart the app and the license will check out fine.
Step 4: Testing it out
You can test out your app by again going to http://market.android.com/publish/ and clicking on “Edit Profile” .. at the bottom you can add market user emails that are being tested and you can change what license response you want to force out to the user.
Tip: be careful not to hit the licensing server too often, or you’ll start getting 503 errors which indicate overuse of resources. These take a while to reset.
Step 5: Adding a demo mode
You may want to add a demo mode to your game if licensing fails. Or somehow stop the game entirely, because the AlertDialog seems to be full of “holes”. That dialog will disappear and reveal your game under a number of scenarios. So don’t count on it blocking the user.
I just recall showDialog(0); in onTouchEvent if the game is in demo mode to keep bringing up the dialog again. I suppose a less annoying way to do it would be to respawn the dialog every minute or something. But maybe I’ll do that later!
Step 6: Applying ProGuard code obfuscation
This step is highly recommended by the Android developer guide. It would be nice if this were built into the Android toolchain, but it isn’t. Here’s a blog post that tells you how to do this.
However, I found that the binary that got build crashed. I’m not sure what is going on, but I’m guessing the NDK and ProGuard just aren’t getting along somehow. I’m going to leave out ProGuard for the time being. (I gave this a few hours effort. Again, this is where having support as part of the Android developer’s kit would be great!)
Update: this blog post explains what you need to do. Beyond that, you also need to handle your native methods and callbacks properly.
Step 7: Enabling Install on SD Card!!
This step is basically the whole point of this entire blog post. This gets the app out of the main memory on the device and onto the SD card for the user’s improved happiness.
To do this, add android:installLocation=”preferExternal” to the manifest tag in AndroidManifest.xml
Also change target=android-8 in default.properties.
And that’s that!