Another month is over, it’s time for income facts again.
If you are new to this series, let me explain it to you: Since Android is an open platform, I decided to be open about the income I’m making with my private Android apps too. In the last report I aimed to reach $1,100 for the last month, a goal which I failed to reach the month before. You will see if it worked out this time.
For all income reports, please click here.
Which Apps?
3D Invaders – about 118,000 installs (+11k), 14% active
AL Voice Recorder – about 433,000 installs (+34k), 23% active
AL Voice Recorder Ad Free – 773installs (+26), 41% active
Droid-Blog.net Android App – 302 installs (+77), 22% active
SmsToSpeech full – 698 installs (+12), 43% active
More then 45,000 new downloads, that’s really amazing!
What did I do?
Last month I pushed some updates, this month I did some ASO again. I did this around the 16th. Since then download numbers increased a lot. Let’s see how this changed my advertising statistics.
Advertising Stats
Here are some statistics from the two advertising networks I’m using, AdMob and Madvertise. Please read the second income report for an explanation of the following numbers.
AdMob:
Requests: 473,103 (+125k)
Impressions: 454,031 (+130k)
Fill Rate: 95,07% (+2,97%)
Clicks: 9,302 (+2k)
CTR: 2.05% (-0.23%)
eCPM: $0.96 (-$0.8)
House Ads: 4,976 (-4.7k)
Adjusted Requests: 478,079 (+120k)
Adjusted Fill Rate: 94.97 90,51 (+4,46%)
Madvertise
As I’m not using house ads in Madvertise, no adjusted requests and fill rates are shown here.
Requests: 845,343 (+556k)
Impressions: 121.656 (+68k)
Fill Rate: 18% (+-0%)
Clicks: 4,654 (+2362)
CTR: 3,83% (-0,44%)
eCPM: $9,31 (+$1.12)
Performances of both networks were amazing. Since I added madvertise to the AL Voice Recorder in the end of last month, madvertise’s numbers had been even more amazing than AdMob’s. I also integrated the new madvertise SDK. I didn’t experience any increase in the fillrate since then, but my CTR improved by about 0,58%.
How much?
Madvertise:
3D Invaders: ~$585.04
AL Voice Recorder: ~$548.55
Madvertise Total: ~$1,133.59 (+$692.86)
Goal reached! But since that’s not all at all, here’s what I earned with my other streams:
AdMob:
3D Invaders: $137.71
AL Voice Recorder: $297.25
AdMob Total: $434.95 (+$96.21)
Market sales: ~$87.02 (+$21,70)
In-App purchases: ~$8,19 (+$3.73)
Total: ~$1,663.75 (+$814.50)
I know I used the word amazing a couple of times in this post, but that’s exactly what last month was, especially in the second half. When seeing an income of about $60 every day, this is really motivating and also a lot of fun.
What’s next?
I expect the level of new installs to stay stable in this month. I will put some effort into a new app to finally get another stream soon. I will probably not manage to increase my Android-income by almost 100% again, but I expect it to rise further.
So, for this month, I’m targeting the magic mark of $2,000. A competitive goal, but I’m convinced I will reach it.
Please feel free to share your own experiences and hints in the comments. Please also don’t hesitate to tell me if there is anything else you’d like to get some information about.
Tutorial: How to play animated GIFs in Android – Part 2
Animated GIFs in Android is a difficult topic. It is an issue that has been discussed heavily and still, it is very difficult for developers to bring GIFs to life. There are three ways to animate GIFs on Android, each of them has its pros and cons. Each part of this series will cover one of these approaches.
Getting started
For this example, we will use an image I found on gifs.net, it’s this one:
I will store it in our project’s asset folder and name it ‘piggy.gif’. We will also use an Activity to set the views we define as content views. If you want to know everything about playing GIFs, please start at part one.
Approach 2: Extracting the Bitmaps
For this approach, we will use the GifDecoder class published here on googlecode. It’s Apache licensed, so don’t worry. What this class esentially does is, it extracts the different bitmaps from the given stream so you can use it the way you want.
To get started, download this class first. Place it somewhere in your project, maybe in a util package.
Now, we create a new class which inherits from ImageView:
We create a constructor with a Context and an InputStream, just like in the first part of this series. This time, we call a method playGif(InputStream) and pass it our InputStream:
We give our class five member variables: A boolean which will state whether the thread we will use to play our animation is runningor not, an instance of the GifDecoder-class you just downloaded, a Bitmap which stores the different frames of the animation, a Handler to post our updates to the UI-thread and a Runnable that will arrange that the Bitmap we just defined will be drawn using the Handler:
Let’s take a look at playGif(InputStream). First, we need to initialise mGifDecoder. After that, we let it read our stream and set mIsPlayingGif to true, so that our thread can run:
Now we need to define our thread. We retreive the frame count of our GIF’s frames and the number of repetitions. When GifDecoder.getLoopCount() returns 0, this means the GIF should be played infinitely. Now for every frame, we receive the according Bitmap by calling getFrame() on the GifDecoder. We post our new Bitmap using the Handler and Runnable members we defined and send our thread to sleep until the next Bitmap needs to be drawn.
That’s it. All we have to do now is use our GifDecoderView in an Activity, just like we did in the last part of this tutorial:
Now, what’ the bad thing about this? It’s the memory footprint. Bitmaps on pre-Honeycomb-devices are stored in an native heap, not in the heap the Dalvik VM uses. Still, this heap counts to the maximum of memory your app can use. So when you have a lot of Bitmaps, the garbage collector might not notice that you are running out of memory because it only controls the heap of the Dalvik VM. To avoid this, make sure you call recycle() on every Bitmap you don’t need anymore. If you want to see how much space your native heap allocated, call Debug.getNativeHeapAllocatedSize().
If you want to know another, maybe better way of playing animated GIFs, stay tuned: The next part of this series will come soon.
You can checkout the code of the three parts of this series at http://code.google.com/p/animated-gifs-in-android/.
As always, please feel free to leave your thoughts in the comments.