Within my Android app that is available via Google Play, I want to offer additional items that can be bought via in-app billing.
The kind of items I want to offer is media content such as graphics and sounds, which would normally go into the res folder of the app.
The problem is that these resources must be protected, of course. In its documentation, Google suggests not to store the content inside of the application package but to obtain a key after the item was bought and then send the key to a remote server where the key is checked and, if successful, the graphics/sounds offered for download to the app.
This sounds good, from the security perspective. But if I do this, I can’t use the content as easily as resources can be accessed normally. If the user can get additional background PNGs, for example, I can’t use R.drawable.new_background but have to decode the bitmap programatically, right?
So are there any alternatives or best practices for downloading additional media content via in-app billing?
I would say, as everyone who is determined enough can reverse-engineer the code, anyway, why not just store the content inside of the app but do strong checks if the user might use that content at all.
One of obvious reasons for not storing additional content in the app is your app’s app download size. If you are offering audio as additional content it can drammatically increase the size of your application. And users care about it. Besides it makes it easier to publish additional content, since you can do it via your server side/developer console without the need to publish app update. Moreover, if you want to provide high quality graphics, you will be able to serve appropriate version of the image directly to the device without the need of storing all density/screen size versions.
If you are concerned about security you can always use encryption and signatures to access resources and make attackers life much harder by properly obfuscating your code (or even moving security/decryption related code to native side, which will make it faster as well).
Yes, that would create a drawback that you will have to decode them programmatically and there is nothing to do about it. I honestly don’t see why it is so big of a deal, on contrary, I think it’s quite convenient that you will have more data driven access to resources.
As a summary I dont really think there are any standards for doing this and it depends on your app and content type. If you offer a fixed amout of 5-10 images, then there it is perfectly fine to keep them locally, if it is richer content, more items, heavier resources, then client-server would suit you more.