Sunday, April 21, 2024

Elevation profile app for Android, touching the base

Google is forcing me to update my Android apps, so after about three years of not even looking at it, I am returning to Elevation and Sea Depth. I've decided to "touch the base" and review the app history before preparing it for the next, 33rd release.

The app was initially launched on May 1, 2010, and it was the third Android app that I developed. I still consider it the most interesting one that I made. Believe it or not, the APK had a size of 57.8KB. I even kept some screenshots from that time.

Currently, the Play Store is reporting over 50,000 cumulative downloads. I am unable to access more detailed statistics for the period before July 25, 2019, as the Play Store does not display it, and Flurry Analytics, that app once used, has been sunset. But here is what I have.

Elevation and Sea Depth targets a very specific group of people in particular circumstances, so I can't really expect mind-blowing usage. However, 188 active installation out of those 50,000+ downloads is a bit ... disappointing? I believe the app probably peaked around Jul 2017, at least judging by the number of AdMob requests.

The total all-time revenue from ads was more than a whopping $1,080. You can't imagine how I spoiled myself with that money. I say "more than" because AdMob doesn't show statistics for the first 4 years of the app's lifetime.

According to the data, the golden era of AdMob revenue, at least for this app, was from March to June 2017.

The first license for the full app version was sold for $5 USD on August 7, 2010. At that time, merchant accounts from my country were not supported by the Google Play Store (then called Android Market), so I had to find an e-commerce provider and implement my own license server.

Overall, during that period, 186 licenses were sold. The sales stopped in September 2011 and started again in January 2012 when I dropped the price to $0.99 USD. In May, I completely switched to another e-commerce provider and stayed with them until 2019 when they stopped supporting Android. I managed to sell the first 34 licenses for $5 USD and the remaining 152 for $0.99 USD, totaling $320.48 before deducting all the fees.

In 2019, the Play Store started supporting my country as well, so I had to switch to their monetization platform and drop all third-party e-commerce providers. Three licenses were sold for $0.99 each. Next year, I decided not to sell the app at such a low price any more, so I switched to subscription payments, just like with the rest of my apps, with a yearly price of $15.99 USD. So far, two subscriptions have been sold.

To sum it all up, this app has made me less than $1,500 USD in the last 14 years. Far from what more successful apps of mine made, but still four times more than what I made with Weather Forecast USA.

The question is: can I squeeze more juice out of it? I definitely don't want to kill my baby, but obviously it's been in a kind of zombie state forever. Well, I guess we'll se if it picks up after the update.


Saturday, April 20, 2024

Mindfulness Meditation Android app redesign

The (free, no ads) app is available here: Mindfulness Meditation for Android.

Moodboard

First time using a moodboard for one of my apps!
 

Feature graphic

Before
After

Launch icon

Before
After

Screenshots

Before

After


Before


After


Before


After


Before


After

Sunday, April 14, 2024

Updating Healthy Battery Charging to Android API level 34

To prolong your Li-ion battery life, reduce e-waste, conserve rare minerals, prevent child labor, i.e. contribute saving the planet - or to save own money if it rings more with you, keep it charged between 40% and 80%, all the time. 

(Technical details about Li-ion batteries are available at the following link: BU-808: How to Prolong Lithium-based Batteries.)

I discovered these facts in 2017, and that's when I published a small Android app that alerts me when it's the right time to connect/disconnect the charger. Healthy Battery Charging was just a minimum viable product, a tool for my own use. I never planed to monetize it, so I released it as a free app, without ads, and I never updated it since.

Fast forward to the year 2024, I have decided to revisit the app, just for the sake of refreshing my knowledge about the way Android handles notifications. A lot of things changed over the years, and I ended up almost rewriting the complete app. And redesigning it, since I am already investing my time.

I've decided to utilize this blog post to track my own design updates and organize my thoughts around notification handling on android. So here we go ...

UI Updates

Launch icon before
Launch icon after
Feature graphic before


Feature graphic after


Screenshot before

Screenshot after

Not sure about you, but I can notice the difference in my own design skills after taking a UX/UI course. 😉

Technicalities

The app schedules a background repeating alarm to check battery and power connection status. The alarm repeats every 15 minutes, though all alarms on android are now inexact and the alarm can be batched with other alarms and triggered later, for example when the device wakes up from the sleep. But for this use case, an exact alarm isn't necessary.

There are situations where pausing the repeating alarm would make sense - once the notification is displayed to the user, it's not necessary to check the status again until the charger is connected/disconnected. The previous app version used to work this way - it had a receiver registered for android.intent.action.ACTION_POWER_CONNECTED and android.intent.action.ACTION_POWER_DISCONNECTED. However, starting from API level 26, these events are not broadcasted to receivers running in the background [docs, exceptions]. They are still broadcasted to foreground services.

When targeting API level 34 or higher, all foreground services must be declared with their service types using android:foregroundServiceType. Currently, the specialUse type seems most suitable for this use case. Additionally, you need to request FOREGROUND_SERVICE permission

Furthermore, apps targeting API level 31 or higher can't start foreground services while running in the background, except for a few special cases.

To maintain the same functionality, a foreground service needs to be started from the boot receiver. The service would need to permanently display a notification. It would not be possible to dismiss it (no notification = no service running), so perhaps it would just change it's text from "Monitoring the battery" to "Connect/Disconnect the charger". I find a permanent notification a bit too much for an app that is supposed to silently run in the background and be invisible most of the time. 

For this reason, at the moment I am preferring the simple approach:

  • Do not pause any alarms and keep them running every 15 minutes. 
  • Do not display notification if it hasn't been previously dismissed. 
  • Dismiss the notification on the next alarm run if the charger has been connected/disconnected. As previously described, notifications can not be dismissed automatically.

Other relevant questions and answers on StackOverflow:
How to listen for power connected Android > 8
How to check which notifications are active in status bar in Android Dev?
Android - AlarmManager is not working after app is closed


https://developer.android.com/reference/android/content/pm/ServiceInfo?hl=en#FOREGROUND_SERVICE_TYPE_SPECIAL_USE
https://developer.android.com/reference/android/content/pm/ServiceInfo?hl=en#FOREGROUND_SERVICE_TYPE_SPECIAL_USE

Source code syntax highlighting in WordPress

I was using SyntaxHighlighter Evolved, but after I updated the Enfold theme, it's not working anymore. At least not in the classic editor.

I have tried Code Block Pro, I haven't figured out how to make it work with classic editor either. Enlighter doesn't seem to have been updated for a year or so, so in the end, I chose Prismatic.

Friday, April 12, 2024

How to make nice gradients

  • Do not make gradients with white or black color
  • Keep the saturation the same for gradient colors
  • Change hue 15 - 30%
 

Sunday, April 7, 2024

How to hide __pycache__ directory in Visual Studio Code

File -> Preferences -> Settings (or Ctrl+,)
Search for term: files.exclude
Click on Add Pattern
Add: **/__pycache__
Click on OK

Done!