Adjusting the Opacity of an Android Bitmap

Posted in Android by Dan on January 12th, 2011

This took me a lot longer to figure out than it should have done. I’m documenting it here in case it’s useful for somebody else searching for a similar solution.

If you’re displaying the Bitmap in an ImageView, you can probably use the ImageView.setAlpha(int) method. However, if the ImageView is accesed via RemoteViews, as is the case when updating a widget, you won’t be able to invoke this method (if you try to call it via RemoteViews.setInt(int, String, int) you’ll get an exception telling you as much).

After much searching I was unable to find a widget-friendly mechanism for adjusting an ImageView‘s transparency, or any obvious way of manipulating a Bitmap‘s alpha channel.

Eventually I stumbled upon Kevin Dion’s excellent answer to a different but related question on StackOverflow. From this I was able to figure out that I needed to use the DST_IN Porter-Duff mode to modify the alpha channel.

/**
 * @param bitmap The source bitmap.
 * @param opacity a value between 0 (completely transparent) and 255 (completely
 * opaque).
 * @return The opacity-adjusted bitmap.  If the source bitmap is mutable it will be
 * adjusted and returned, otherwise a new bitmap is created.
 */
private Bitmap adjustOpacity(Bitmap bitmap, int opacity)
{
    Bitmap mutableBitmap = bitmap.isMutable()
                           ? bitmap
                           : bitmap.copy(Bitmap.Config.ARGB_8888, true);
    Canvas canvas = new Canvas(mutableBitmap);
    int colour = (opacity & 0xFF) << 24;
    canvas.drawColor(colour, PorterDuff.Mode.DST_IN);
    return mutableBitmap;
}

Addendum (13 February 2013): Balazs Balazs e-mailed me to point out the following:

This might not work if the original bitmap is mutable but is not created with a config Bitmap.Config.ARGB_8888.

For example Samsung Galaxy S2 by default returns a mutable bitmap from BitmapFactory.decodeResource with a config of RGB565.

So it would be safer to leave out the bitmap.isMutable() check and always copy the bitmap.

Analysing Android Application Sales

Posted in Android by Dan on October 27th, 2010

One of the reasons that I’ve chosen to get involved in mobile app development in recent months is because I wanted to experiment with the economics of selling software. The new world of mobile app stores provides an ideal opportunity to do just that. For an eye-watering 30% of your revenue, Google and Apple will provide all of the distribution and payment-processing infrastructure so that you can concentrate on making and marketing software. Given that I’m already experienced with Java and that Google puts fewer barriers in the way of developers than Apple, Android was the obvious platform choice (I have since also started exploring iOS development, perhaps I’ll talk about that in a later post).

I have already related details of my initial forays into Android app development, the results of which were my first two (very basic) paid-for applications. The Beep Test app has sold a decent number of units considering its modest functionality and that it was only written as a “my first app” introduction to Android. We’re talking hundreds rather than thousands but that comfortably beats the “one genuine non-refunded sale” target that I set for it. The second app on the other hand has been, by all financial metrics at least, a total failure.

Try again. Fail again. Fail better.

Fortunately I was not banking on getting rich from these simple applications. They were a means to an end, an Android familiarisation exercise, phase 1 in a longer term plan that has more than one possible successful outcome.

Since then I’ve released a couple more apps, though much of my time has been occupied generating real revenue for Rectangular Software through paid development work. Like the vast majority of Android developers, I’m still awaiting the promised riches of the smartphone revolution. I have no sense of entitlement in this respect. I don’t expect to make a year’s salary from an app that took two weeks to write. A more realistic goal is two weeks’ salary for two weeks’ work, acknowledging that an app will not generate all of its revenue in the first month – it may take a year or more to make a decent return. Of course, like most apps, it may never make a decent return.

If you can make a modest amount from one mobile app, you can make 20x a modest amount from twenty mobile apps. Applying the arithmetic of unspecific numbers, 20x a modest amount equals a reasonable amount. The logic is sound but the approach only scales so far. In the absence of a genuine hit among your 20 apps, substantial wealth may not be forthcoming. Adding more unfocused development effort is unlikely to be sufficient.

At this point I’ve written a page of text and not gotten to my point. My point is that, to stand a chance of financial success, the average mobile developer needs to figure out how to maximise the return on their development effort. Marketing, economics, and all the other non-technical stuff. The goal is to make sure that you leave no money on the table. You’ve written the software, sell it.

You can’t control what you can’t measure

I’m not the person to tell you how to increase your sales (maybe you should start with Andy Brice’s series of articles about promoting your software). I’ve already established that I am a very long way from making a sustainable income from mobile development. You should also know, if you haven’t deduced it already, that I am not an economist. As for marketing, I make that up as I go along. I do however have an extensive collection of quotations ready to deploy as the situation demands. Enter Benjamin Disraeli:

“As a general rule, the most successful man in life is the man who has the best information.”

When optimising computer software better information leads to better decisions and better outcomes. The same is true when optimising for financial performance. It’s why insider trading is so profitable (and so illegal).

If you were selling software from your website rather than somebody else’s app store, you would use Google Analytics or similar to record and digest the information that you needed to optimise sales. There are some partial equivalents in the Android world such as in-app analytics, which only tell you what happens to your software after it’s been bought, but a complete picture will not be possible until Google starts revealing more Android Market data to developers. For now we have to work with what we’ve got. What we’ve got is some fairly detailed information hidden away in Google Checkout. Again, it won’t tell you about the people who didn’t buy your apps but it does give some insight into who is buying.

You can download this information in CSV format. When I looked for a tool to process this data, I didn’t find anything. So I wrote my own. This has helped me to identify some interesting trends.

Sales by country

Perhaps most informative is where I’m making sales. The top five countries are all (predominately) English-speaking countries. This is to be expected since my software is currently only available in English. These five countries account for 94.8% of all my Android revenue. Take a close look at the figures for the UK and France. These are two neighbouring Western European countries with almost identical population levels and similar levels of wealth. Assuming similar levels of Android adoption (which seems reasonable but I don’t have any figures to back up this assumption), it should be possible for me to make as much money from France as from the UK. Instead I make over 50 times as much in the UK. This leads to the obvious hypothesis that I am leaving money on the table by not translating my applications into French. Germany, an even bigger market, is similarly under-represented. This is easily remedied – there are online services that will do the necessary translations for somewhere in the region of $20 – $50 per app for a single language.

The second interesting thing about this data is that the figures for the UK and the US are broadly similar despite the latter having five times the population. In this case the discrepancy cannot be due to language. The data is from the last 3 months or so. In the last few weeks I have seen a sustained jump in US sales and a corresponding dip in UK sales. I can only speculate that this is related to the recent Android Market change to display app prices in the user’s local currency. My figures for October to date are 52.5% for the US and only 25.5% for the UK. Australia is also slightly up.

Hour of the Day

There are several other ways to digest the Google Checkout data. The above chart shows how revenue is distributed throughout the day. Here you can see that my most productive period of the day is between 4pm and 6pm UK time. Filtering the orders by country shows that 4pm – 5pm generates more money from UK users than any other time of the day, which I find surprising, whereas 5pm to 6pm (12pm – 1pm Eastern / 9am – 10am Pacific) is peak time for US users.

The point in the article where thinly-veiled product placement becomes blatant advertisement

Still reading? OK, that tool I mentioned for analysing Google Checkout data is my fourth Android application, Appmonger, which is on the Android Market for the bargain introductory price of £1.99. It automatically fetches the Google Checkout CSV data and generates various charts, which you can share via e-mail and social media. You can find out more about it by following the link or by watching the poorly shot video on the right. Appmonger has already been through a couple of iterations to incorporate feedback from early adopters and I hope to extend the functionality in future releases, so feel free to make suggestions.

Android LVL Obfuscation Pitfalls

Posted in Android, Java by Dan on September 13th, 2010

The recently-introduced Android License Verification Library (LVL) survived a disappointingly short time in the wild before somebody figured out how to circumvent its protection. Google responded to this development by stating that it was the lack of obfuscation that had made the crack so straightforward and then followed up with further advice on achieving security through obscurity, effectively acknowledging that there is no robust way of doing licence verification that can’t be bypassed.

Unfortunately, the LVL is pretty much the only option for protecting apps sold via the Android Market (other app stores have their own protection mechanisms). The choice for Android developers is mediocre protection or no protection at all (Google apparently intends to withdraw its previous copy protection mechanism).  You can thwart the most casual Android pirates and make things harder for the determined but that’s about as good as it gets.

Obfuscating LVL-protected Apps with Proguard

Assuming that you choose to add the LVL to your app, you’ll no doubt want to follow Google’s advice and obfuscate your code, probably using Proguard. If you do, you might hit a couple of problems that prevent the LVL from working properly.

I added the LVL source to my application and built it as a single entity but it is also possible to incorporate the LVL as a library project.

Disable Aggressive Overloading

The first problem I encountered was a limitation in the Dalvik VM. Unlike the JVM, it does not (did not?) permit static fields of different types to have the same name.  In normal Java development this situation never arises but Proguard has an option to aggressively overload names to make decompilation more difficult. For Android development this option should not be used otherwise you will get VerifyErrors.

Avoid Renaming the ILicensingService Intent

The checkAccess method of the LVL’s LicenseChecker class binds to the licensing service as follows:

boolean bindResult = mContext.bindService(
    new Intent(ILicensingService.class.getName()),
    this,  // ServiceConnection.
    Context.BIND_AUTO_CREATE);

The problem with calling ILicensingService.class.getName() is that, after obfuscation, the class has a different name and therefore the wrong intent is created. This will show up in the log as an error with the message “Could not bind to service” and the licence check will always fail.

You could fix this by modifying the Proguard configuration to avoid renaming the ILicensingService interface or, even more straightforwardly, you could just modify the code in LicenseChecker and hard-code the appropriate action:

boolean bindResult = mContext.bindService(
    new Intent("com.android.vending.licensing.ILicensingService",
    this,  // ServiceConnection.
    Context.BIND_AUTO_CREATE);

Building Two Versions of the Same Android App

Posted in Android, Ant by Dan on July 19th, 2010

There are good reasons to want to build two versions of the same Android application. The most common scenario is to produce a free demo/reduced-functionality version of a non-free app. You could achieve this by maintaining two separate source trees but the duplication would make most developers wince.  So the question is how to build two differing apps without duplicating the code and resources?

Building Android Apps with Custom Ant Scripts

The answer is Ant. Maybe it’s also possible with Eclipse. I doubt it but I don’t know and I don’t care to find out. As I mentioned previously, the Android Ant build system is fairly painless to use. If you want to customise it though you’ll have to do a fair bit of digging as it doesn’t appear to be documented anywhere. The first place to look is the <sdk_dir>/platforms/<target_dir>/templates/android_rules.xml file that is used by the build.xml that the Android tools generate for you. This will give you a good idea of the various stages of the build but if you want to experiment with the Android Ant tasks you’ll have to look at the source to see what attributes they support (making sure that the version you are looking at is the same as the version you are using). The AaptExecLoopTask is just a simple wrapper around the aapt tool but the ApkBuilderTask is non-trivial.

The outline of a minimal Ant build for an Android app looks something like this:

  1. Generate the R.java file from the resources using the the exec task and the aapt tool with the -J option.
  2. Compile all of the app source, including the class generated in step 1.
  3. Use the dx tool to convert the Java bytecode into a .dex (Dalvik executable) file.
  4. Use the aapt tool (either via the exec task or via the provided AaptExecLoopTask) to package the resources.
  5. Build the .apk package using the ApkBuilderTask.
  6. If you are building a release package rather than a debug package, sign the .apk file using the signjar task.
  7. Use exec to run the zipalign tool on the .apk file.

More advanced applications will involve additional steps, such as running the aidl tool.

Once you have the outline of your build in place, you can start to customise it using your standard issue Ant prowess.

Different Resources for Different Versions

In my scenario I don’t mind shipping all of the code with both versions of the application. The difference is just the initial Activity that each uses. It doesn’t add much bloat to the package and the code is useless without the full set of resources so there is no danger of somebody hacking the demo version into a fully functioning version. In other words, I don’t need to worry about excluding certain classes from one version or the other.

I do however only want to include a subset of the resources in the demo version.  The way I have achieved this is to replace the default res directory with three directories: res-common, res-demo and res-full. I then use the Ant copy task to construct the res directory from the appropriate pair of directories prior to building.

Different Manifests

Because I want to invoke different activities, I need to define the AndroidManifest.xml differently for each version. My first idea was to just have two different files with different names but I discovered that the Android tools get upset if the file is not called AndroidManifest.xml, even if you explicitly specify which file to use. This just means that I have to copy the chosen manifest so that it has the correct name.

The biggest problem with building two versions from the same tree is resolving conflicts in the application package name. Each Android application must have a unique application package. This is specified in the manifest. You can just use the same package name for both versions but users will run into problems if they ever try to install both versions at the same time. They will likely end up not being able to use either. Despite the drawbacks, this method seems to be widely used judging by the number of apps in the Android Market that warn users to uninstall the demo version first.

So we’ll just change the package name in one of the manifests then? Yeah, that would be nice. The problem is that the package name specified in the manifest is the package into which the R class is generated. If the two versions of your application have their R classes in different packages then common classes will not compile for both versions.

Android 2.1 introduces the --custom-package option for the aapt tool which allows you to over-ride where R.java will be generated. So the idea is to set the application package differently in one of the manifests but then to use this option to make sure that R.java is still in the same place as in the other version. I tried this and it resolved my compile problems but there were resource problems at runtime. I didn’t fully investigate what was wrong because I found another approach that appears to work.

The aapt tool also has the --rename-manifest-package option. Leaving the application package the same in both manifests and then using this option at step 4 above, I was able to generate a working demo version and full version from the same source tree and have them both functional when installed at the same time.

The whole custom Ant build exercise was not nearly as straightforward as I would have liked, mostly due to lack of documentation, but it is at least a working solution to the problem. Another, probably more recommended, way of achieving something similar would be to use library projects.

Android Adventures

Posted in Android, Java by Dan on July 17th, 2010

Late to get involved as ever, I’ve been developing with Android for the last couple of weeks. On the whole it has been a positive experience (thanks to Richard for pointing me in the right direction with my queries).

My first impression is “what the hell were Sun doing for the last decade?” Android shows what J2ME/JavaME could have been. A proper Java environment for mobile devices (the fact that it uses Dalvik is largely inconsequential). J2ME may have first arrived when mobile phones were far less capable than they are today but, like Java in general in the last few years, it never really progressed.  Worse still, with its numerous device profiles and JSRs it betrayed the “Write Once, Run Anywhere” philosophy that is so fundamental to Java. With J2ME it’s more like “right once, wrong somewhere else”. You don’t really write Java at all, you write some horribly restricted, out-dated subset of it. That’s not to say that J2ME was not a success of sorts despite its numerous short-comings. I don’t have the figures to hand but I believe it’s true to say there are vastly more J2ME-enabled devices in circulation than iOS and Android devices combined.

Pain-Free Mobile Development

Android is a complete reboot of Java for mobile devices. No longer do you have to worry about which devices support floating-point arithmetic or how to do anything useful with an anaemic UI toolkit. No more making do with Vectors and without generics, or wondering what happened to half the useful classes and methods that you take for granted with JavaSE.

Of course, nothing’s perfect. The API documentation, while generally pretty good, is not quite up to Sun’s high standard, the UI toolkit is either slightly buggy or slightly unintuitive (probably both), and a couple of things I wanted to achieve were less straightforward than I might have hoped. These however are minor gripes. The resources framework seems to do a pretty good job of dealing with the differences in platform versions and screen sizes. As Sun no doubt learned from J2ME, there is a real risk of fragmentation when different manufacturers want to deliver different capabilities. So far it seems under control.

The documentation favours Eclipse throughout but fortunately it’s pretty painless to develop Android code without it. The Ant tools are fine and, if necessary, it seems flexible enough that I could move things around to employ more sophisticated builds. I’m not sure how easy it is to use TestNG in preference to JUnit when using the Android tools. At the very least it would be possible to just bypass the Android test project stuff and test your Java classes the way you normally would. Given that Cedric was heavily involved in Android it’s mildly surprising that TestNG support is not included out-of-the-box.

Android Market

Yesterday, after paying the $25 registration fee, I pushed my first two (pretty basic) apps to the Android Market. This is an area where Google has room for improvement. It’s all a bit simple at the moment. As I’m in the UK my prices are set in pounds. There is no way to specify different prices for different currencies, nor does the market automatically convert prices for users. That means that, as a user, you are presented with application prices in at least four different currencies (US dollars, Euros, Sterling and Yen) and have to do the necessary conversions yourself. I would like to be able to specify that if my application costs £1.99 in the UK, then it should be $2.99 in the US and €2.49 in the Eurozone.

The other thing you can’t do is respond to user comments. Somebody left a comment that my app did not work properly for them. Unfortunately they provided no details to enable me to track down the problem. Worse, they wrongly assumed that the functionality was simply missing and stated as much. As the only comment on the app so far, that will likely dissuade other people from buying.

The good thing about the Market is that you have the freedom to upload pretty much whatever you want and to have it immediately available to users. Unlike the iPhone, you are not subject to the whims of an inconsistently applied approval process.

My First Apps

So what did I make? My first app is a simple utility for performing a multi-stage fitness test (a.k.a “Beep Test” or “Bleep Test”). It’s a one-button UI that emits the necessary beeps at the appropriate intervals and displays status information such as current speed and cumulative distance.

My second app is an educational game called Flagpole. All you have to do is identify flags. You get one point for each correct answer and it’s game over when you get one wrong. It’s divided into challenges of increasing difficulty, so you might start with South America, for which there are only 14 flags to identify. Eventually you’d progress to “The Whole World”, which would require you to correctly identify 232 flags without making any mistakes.

I intend to release further, more sophisticated applications in the coming weeks. These apps are sold via Rectangular Software, which is the new home for my commercial software development activities (contract/freelance development and now applications).  My open source projects remain here at uncommons.org.