Friday, March 1, 2013

Encrypting string resources when using Android library projects.


When you're using an Android library project as the base code for multiple projects, it's handy to rely on resource overrides for configuration parameters.  For example, you could use a strings resource file that points to different URLS, etc.  While doing this is quite handy, you must also consider that resource files are very easy to extract using apktool, so if you are concerned about keeping any of this configuration data secure, you're going to have to take some extra precautions.

For a very basic obfuscation method you can just base64 the content and put it in a string resource.   I wouldn't recommend this alone, as any reasonably competent person can decode the string.  The nice thing about base64 is that it's output charset doesn't contain apostrophes or double-quotes (by design).  Because of this, base64 encoded data does not need to be escaped when used in a string resource.

For a better real-world scenario, let's assume that we have an application where we want to enable in-app billing, and to do so we need to be able to store the license key from our application in a reasonably secure fashion.  At the same time, we'd still like to leverage the convenience of resource overrides to store the license keys in our sub-projects that rely on a core android library project.

Our high level strategy will be to do the following.
  1. Encrypt our application license key (obtained via the Google Developer Console) using a hardcoded encryption key (think password).
  2. Base64 the encrypted 'cipher' text.
  3. Use this encrypted/base64 encoded value in our strings resource file.
Here's some sample code to help accomplish these tasks, just note that we will only use this code to generate our encrypted and base64 encoded license key before storing it in a resources file.  This is a one time activity.  And this should go without saying, but REMEMBER TO CHANGE THE VALUES IN keyBytes


Once you have the string encrypted/encoded as such and placed in your strings file, you simply need to decrypt it when needed.  Here's some example code :


Making it even more secure.

Since it's hard to get around hardcoding your secret key (the keyBytes in our sample code) using this strategy, it would be naive to assume this is 100% foolproof.  A persistent minded individual could still decompile your app, discover the byte array you used for encryption, and then reverse the entire process.  Your job is to make this as difficult as you can reasonably make it. You could store your key in multiple byte arrays and combine them when needed, for instance.  I won't go into specific methods here, but the point is to be creative. Using a code obfuscation tool such as proguard will help, or at the very least use non-obvious/misleading method names to perform these operations.




Wednesday, February 13, 2013

Guest blogger for Velti

I wrote a guest post for the Velti blog on a new idea I had for maximizing ad revenue.  It can be found here  and it's titled 'One simple metric to increase your app's  revenue - and it's not CTR'.

Monday, November 5, 2012

Mobclix vs Admob results and more

I'll now conclusively state that Mobclix pays out more than AdMob (for my apps).  After collecting several months of data, Mobclix has consistently outperformed AdMob during every single week I've measured.  10:1 higher eCPM's at the best and 2:1 at the worst.

Seasonally, I was very surprised to see Mobclix's eCPM's fall quite a bit near the end of September and they still haven't recovered.   I'm expecting that advertisers will start increasing their campaign spends as we move closer to Christmas, but getting into the heads of the ad-buyers isn't easy.  Everyone I've talked to repeats the same CTR mantra:  "The higher your CTR, the more money your app will make".  I'm doing my best to put that theory to the test.

I've just started another experiment which I'm hoping will at least double, perhaps triple my CTR rate on Android, more to come on this later, data collection is in progress.  If it works, I promise to reveal all.

I'd also like to do another Mobclix vs comparison, but this time against another ad-network rather than a single provider.  One thing at a time however.

Sunday, August 12, 2012

Admob vs Mobclix update




The test is on-going, but the eCPM rates for mobclix have really picked up in the last three weeks.  Over the last seven days Mobclix's eCPM is beating adMob by a 4:1 ratio.  I'll keep the test going, but with that kind of price differential, I've obviously tuned my impressions to favor mobclix.

The only problem with mobclix is their net-90 terms.  I'll definitely be expecting some kind of payout this month, as I haven't had one since May (when they switched back to net-90 terms).

Sunday, July 22, 2012

Using Mobclix's Open Allocation features

I've been using mobclix for over a year now, and other than their very slow rate of payouts (on net 90 terms), I've generally had no complaints.   In recent months however, I've noticed that both my eCPM and eCPC rates have been halved.  Usage has continued to steadily increased for all my branded podcasts apps (based on DroidCatcher), but my revenues are simultaneously declining since March.  Perhaps this is seasonal, I'm not really sure.  There doesn't seem to be any good data available.

Even if you do a search for "Admob vs Mobclix", it's really hard to find any current information, most  of the data I see is from 2010.  So I'm going to conduct yet another test.


Mobclix offers an "open allocation" feature, which allows you to easily allocate any percentage of your impressions to AdMob.  In theory all you need to do is include the Admob SDK, add the AdMob publisher id and the AdActivity to your application Manifest, and you're good to go.

The fact that Mobclix makes it this easy to display ads from a competing SDK hints to me that Mobclix will have better looking numbers.  I'll be releasing an updated version of The Complete Alex Jones and I'll publish my findings.

Wednesday, March 2, 2011

Google, please stop giving away hardware at your events!

I just read via engadget that Google is giving away Xoom tablets to attendees at the GDC. Originally, giving away free hardware was a great way to get devs to play around and build cool apps, but this cute gimmick has run it's course.  People now expect to get free hardware from Google, and since the value of the hardware tends to exceed the ticket price of the conference, everyone and their mother are signing up.

I had planned on going to Google IO this year, and was patiently waiting for registration to open.  I made the mistake of walking across the street to Panera for lunch with some co-workers, and by the time I got back registration had already opened and closed.  Who cares you say? Maybe I'm just bitter because I wasn't one of the lucky few that made it.

Sorry, but there is more too it than that, dev conferences are supposed to be for developers. It's a chance to learn new stuff and get some important networking done. The job I have now at TuneWiki, in fact, came from a random encounter I had during a lunch break at a previous Google IO.  Signing up for a Google IO event, should not be the online equivalent of going to Walmart on Black Friday.



   Yes, I'm also aware of the Google IO Pre-Sale VIP list, which supposedly was to give deserving developers a guaranteed spot at the conference.  Except that it failed, miserably, imo.  Using myself as an example, I attended the very first Android event on the Google campus.  I worked on two android projects that won top 10 placement in the first ADC (find someone else who can claim that).  I attended the first device readiness event before the G1 was released.  I sat front row at the G1 announcement press-conference as a special guest of T-mobile.  My current work efforts not only include TuneWiki, but also the media player that's baked into every motorola device (before US carriers replace it with their crapware).  Despite all this, I did not receive a VIP pre-sale invite.  And if I didn't get an invite, you can bet your ass there are plenty of other deserving developers who didn't either.

In short, Google, I am disappoint.

UPDATE: For the record, I already have stacks of android devices on my desk, including unreleased evaluation devices, so anyone who thinks that I'm butthurt over not getting a tablet is only re-enforcing my point. People are now assuming getting a device is the reason I want to go to these events.

Sunday, May 30, 2010

The limitations of AsyncTask

AsyncTask is a fine API, it's been said that it "holds your hand", and makes performing background operations painless. It pulls this off so well in fact, that I see people overusing it in situations where it's not really appropriate.

It's particularly unsuited for situations when you have a multiple tasks to perform concurrently. Imagine an Activity that needs to download about 30 small images from a remote server, and update the UI as these become available. AsyncTask uses a static internal work queue with a hard-coded limit of 10 elements. That means if you were to create an AsyncTask instance for each image, the work queue would quickly overflow and many of your tasks would get rejected. The best solution in this case is to create your own ThreadPoolExecutor instance that uses a queue that's large enough to hold all your tasks, if you need an unbounded queue, a LinkedBlockingQueue will work just fine.

Another severe limitation is that an AsyncTask can't survive your Activity being torn down and recreated on the other side.  Even if you pass it to the new instance via onRetainNonConfigurationState, the internal Handler inside the AsyncTask is still going to be stale and it's not going to behave correctly.  This is important to consider, and the Android documentation makes no mention of it all.  I've already blogged this scenario in detail, so I won't flog a dead horse here.

There are a few other minor issues, such as the fact that you can't change the background threads execution priority. It's hard-coded to a low priority, which granted, is the sensible default.  Also, exception handling is not very well supported.

So just to reiterate, AsyncTask is a nice API, but you should understand it's limitations and apply it appropriately.  If you're serious about writing mobile apps, then you're going to need a few more tools in the toolbox to get the job done.