Android, Linux, FLOSS etc.

My code

Subscribe to a syndicated RSS feed of my blog.


Tue, 01 Mar 2016

Releasing an Android app on Google Play

Summary: I started releasing Android apps in 2011, this is about my recent release of a simple app I wrote in two weeks which I have hopes of commensurate (or better) financial reward from. I walk through my whole process.

I released my first Android app on Google Play back in 2011. Since then I have released (and sometimes unreleased) a number of apps.

For the past few months I have been working on a yet-to-be-released spreadsheet, which will take a while to write. While it has made some progress, and I have had fairly realistic expectations of how long it would take to write, I miss the ebb and flow of a more agile release-update-release cycle. So I spun an app out of the framework written thus far. But that didn't really do it for me.

Since I'm in the midst of a long project, I don't want to get enmeshed in another long project. I wanted to write an app in a short time frame, which might potentially make me some money and be useful to people. So the two parts of this is it would be an app of a type that is popular, but which I could write quickly. Of course, this means other people can write it quickly as well, and since it is of a popular type, there will be a lot of competition. This is OK though - there are problems of some type no matter what I do. Another reason potential competition is OK - this app will be finished quickly, so even if it is a total waste of time, it is not much of a waste. So I wrote the app. It is not going to be a total waste of time in any matter, because even if it has no commercial success, I learned some things while doing it, which I can bring to other apps.

February 14
So the idea of doing this in general I had been mulling for a few days. On February 14th, I decided to do a Stopwatch. It is something I could do quickly enough, and lots of people want one. Since it's popular and easy to write, of course there is a lot of competition. But I can knock one off quick so even if it's a waste of time, I'm not wasting much time. I started off looking at what stopwatch apps were popular on Google Play, what their quality rankings are, how many downloads they had, when they were first released, when they were last updated, what their features were, how they monetized, and that sort of thing. I also read what people said about the apps in their Play comments section, both pros and cons.

February 16
Then on February 16th I went on F-droid to see what FLOSS Android stopwatch apps have been released. I looked at two, one with an Apache v2 license, one with the Perl Artistic License. I took a look at how they ran, and then how they laid out their classes etc.

I saw that apps with stopwatches often include not just a stopwatch (time starts at 0 and increases) but a countdown timer (time starts at a point and decreases to 0) as well. However, my app is going to be a minimal viable product that I want to do quickly. So I decided to do it in the Unix spirit of an app that does one thing and does it well. I can always tack on a countdown timer later.

I saw that some of the apps had notifications and lockscreen features, which I hadn't thought of. Actually, this app is scratch my own itch of a sort, since last summer I went jogging using someone else's app, and was not happy with the result. I wanted a stopwatch with laps that could survive a long jog. So I resolved to put this in the way I wanted - a resilient stopwatch.

Some of the apps had hundredths and thousandths of the seconds displayed, but it goes by so quickly on the display that it's pointless. Although one app managed to display hundredths of a second decently. I display only tenths of a second on the clock, but put hundredths of a second on lap times. If people really want milliseconds I'll put that - I just don't want too much stuff filling the UI.

So with this in mind, I begin programming. I'm using the stable version of Android Studio on a System76 laptop running Ubuntu 15.10.

One thing I want right away is as big a clock as possible. I decide to start with a TextView. I want it to fill the width of the screen. I'm not exactly sure how to fill the width of the screen with a TextView, and don't find a satisfactory solution until February 23rd.

Most of the other Stopwatch apps have two buttons, and I use two buttons as well.

I also look for a nice icon to use for the app. There is an icon available from https://github.com/alecive/FlatWoken . The license is CC BY-SA 4.0. They say "the iconset is free to use, including commercially, but please consider that if you do convey any monetary income from its use I kindly ask that we arrange for a fair compensation." I've paid for app icons before, and if this app winds up in the black, I will send them money commensurate with what I paid those who required I paid for commercial use. This icon is easy to understand, looks nice, and is available in everything from 512px to 16px sizes. Perfect for my needs.

I then give some preliminary consideration to what my app blurb on Google Play might say for the English language listing.

February 17
I want the stopwatch to be resilient, so I create a Service to run it. On Android, Services are sort of like Unix background processes. I set the service to be destroyed (Activity onDestroy method) if the stopwatch is not running, and if it has no state (no stopped or lap information, whether it was never started or reset). All of the boilerplate to connect an Activity and Service - ServiceConnection, Binder and so forth - I had in my inchoate Spreadsheet app code, so I just copied it over. I also do a little work on the two buttons.

February 18
I add a Constants class which shares final constants between the Service and Activity classes. I begin implementing some of the stop and start functionality in the Service, as well as on the button which handles that.

February 19
So, this is a stopwatch, which means I need a timer running. The Android Timer class docs say ScheduleThreadPoolExecutor is the preferred way to do this, not Timer. But what are the parameters etc. of ScheduleThreadPoolExecutor? I read the class docs, and also look at Google's Android sample code to see which apps use this. I get an idea of how it works, experiment a little, and put it into the Service. With every tick, I send out a broadcast, which is received by the activity, which updates the clock.

February 20
I make the display of the current time more resilient, lasting through pushes of the home screen button, back button, screen rotation and so forth. I also add turn on reset functionality if that should be called.

February 22
Busy through the weekend, I get back to work on Monday. I write a satisfactory method of fitting the TextView text size to the maximum allowed. While the app is running, I run a test - I create an off-screen test staticlayout and textpaint on it, and keep increasing its text size until the text won't fully fit on the staticlayout's width any more. Then I use my last good test size on the real TextView. I can probably improve this algorithm but it works for now.

I also put some very initial lap functionality in.

February 23
I add more lap functionality. I save lap info through screen rotations and other Activity changed.

February 24
I show my friend, who regularly exercises, what I have so far. He likes the app's simplicity. He also would prefer hundredth of a second and even millisecond accuracy. I have millisecond accuracy but don't display it yet, or even hundredth second accuracy.

I set it so that the last added lap always appears on-screen, and older laps begin fading off-screen.

I want the lap ListView views to be more flexible, so I create a custom ArrayAdapter for the ListView, which generates the views I want.

I stick in an ad that links to one of my other apps when closing. This is the first attempt towards monetization.

At this point, we do have a minimally viable product I think. The app is now minimally useful. But there's a few more things I want to try before release, so I will take a stab at those.

February 25
I add a notification widget to the app. The notification widget exists in the lockscreen as well. It is updated every second with the new time. I pull one of Google's CC-BY licensed clock icons from the web to use in the notification.

February 26
I begin playing around with a behavior where clicking on the notification goes to the app activity. While testing this out, I notice an unrelated problem. The app had been exiting in some circumstances even with state. The notification testing I have been doing flushed this unrelated error out. So I fix that bug.

February 27
Pressing notification now goes to the app. I could put action buttons here, but will postpone that beyond this minimally viable product.

I change from AppCompatActivity to Activity and change the style to Holo. It makes things easier...

I decreased the size of lap numbers and increase the size of lap/total time spent. I also add hundredths of a second accuracy to these lap times.

I add lap time sharing. So people can e-mail their lap times, send it to a notepad, or what have you.

I also put in Google Analytics. I tried it a while ago on an app and not much happened. I try again. Hey, it works OK! Either they made it simpler or I finally figured it out.

February 28
I QA the app on a variety of phones and tablets, and some AVD emulators. Then I push it to Google Play alpha testing. I send screenshots to Google Play, fill out the blurb there etc. I look at the Google Analytics console - wow, this really works. Wasn't sure what to track, so I am doing button presses and that sort of thing. There are a few things I'd like to know, including what frustrations people may be having and that sort of thing.

February 29
I push from Google Play alpha to production. Then I set up an Adwords campaign. My ad is approved! I run a few ads, many see the ads, a few click, and a percentage of those install the app and show up as a blip on Google Analytics - currently 4 people. Let's see - none of them are using laps. They tend to check the app out for a few seconds and then leave. Although some use it for longer.

So I will probably run Adwords ads for this, see what feedback is, see if it crashes and so forth. Then I may pay to translate it into other languages, once I get a sense English language users are happy.

Many of these apps also have countdown timers. If it is heavily requested and seems necessary I may add one. Doing this was also about agile, pulling the trigger, minimally viable product etc. so I passed on that feature for now as this has most of the desired stopwatch features.

As Analytics is working and I'm tracking ad conversions more closely, some time down the road I may run some Facebook ads for this. Or run ads wherever - I have some grasp of Analytics now and want to explore the different promotion avenues. If Google Analytics doesn't have what I want I can even roll my own. But I will use their backend for now in terms of conversion tracking.

So I'll continue pushing this forward and see how that goes. I'll probably do another app of this manner. I don't want to do something like the many months long spreadsheet app I am in the midst of. Two weeks for this was good. I could even do a longer one. Although not that long - releasing this app was just a break from my spreadsheet app, which I have been working on for months. Years really, although I put the project aside for many years and picked it back up last year (2015). I don't need another long project like that, just some quick apps which might help people and may make a little money like this Stopwatch app.

[/android] permanent link