#91 How to fix the ominous Android Status Bar Issue

Remember Capacitor + Android Status Bar = 🤯? 🪲 This bug has haunted me for months—stalling the Android release of poketto.me and draining way too much mental energy. It’s one of those dreaded dev problems: no obvious solution, hard to debug, and endless rabbit holes. Eventually, I had to bite the bullet and dig in. Here’s what I found: 💣 Issue #1: The Capacitor status bar plugin only half-works. There’s a StatusBar.setOverlaysWebView(true/false) API, but on modern Android versions it doesn’t behave as advertised. Why? ...

September 29, 2025

#89 Google’s Play Store review process is pure torture

In TIL #14, I called getting an Android app into the Play Store “byzantine.” Turns out, I was being too generous to Google and too strict on the ancient kingdom of Byzantium. Here’s what really gave me headaches over the last few months: 🤕 Headache #1: The forms Before Google even looks at your app, you’re drowning in bureaucracy: ticking the “my app doesn’t process health data” box 12 times, pasting links to T&Cs and privacy policies, verifying your name, intentions, identity, blood type, shoe size, the maiden name of your mom’s dog, … ...

September 27, 2025

#84 You can customize the text selection menu in your Android app

As I mentioned in In-place DOM manipulation: Thorny as ever, text selection in browsers can get tricky fast. For poketto.me, the challenge was even bigger: the web app runs inside a hosted WebView in an Android app. Mobile text selection already behaves differently from desktop, and the embedding scenario didn’t make things easier. After wrestling with a few awkward bugs, though, I found an elegant solution. On the web, when a user finishes selecting text, poketto.me immediately converts the selection into a highlight (default color). On Android, however, a tiny system context menu pops up with entries like Copy, Select All, Web Search, etc. At first this got in the way—but it turns out you can customize this menu on a per-activity basis! ...

September 22, 2025

#74 Firefox extensions (mostly) work on Firefox on Android as well

A poketto.me Firefox user recently pointed out that Firefox on Android also supports browser extensions– but that the poketto.me extension didn’t appear on Mozilla’s Add-Ons page there. Turns out: Any modern browser extension built on the standard APIs (Chrome, Firefox, Edge) can also run in Firefox on Android. But when publishing, you have to explicitly test and target Android. Technically, the extension “just works”—as long as you’re not doing anything exotic with the APIs. But aesthetically, there’s one big caveat. ...

September 12, 2025

#37 Google Requires a New versionCode for Every App Bundle You Publish

When publishing a new version of your Android app through the Google Play Console, you must increment the versionCode in your app’s build.gradle file. This is required even if the versionName (the human-readable version string) stays the same. I found this a bit confusing at first — but the rule is simple: Before you build the bundle you upload to Google Play, make sure you’ve updated the versionCode. If you don’t, your upload will be rejected immediately. ...

August 6, 2025

#28 Capacitor + Android Status Bar = 🤯

The Android status bar (that is, the small bar on top of the screen that shows the current time, the batter status, and notification icons) is really, really weird. It turns out, Capacitor will, by default, make your app a “fullscreen” app: It’ll render your MainActivity (the one that hosts the WebView which in turn hosts your web app) in such a way that the status bar isn’t there at all–on most devices. On some devices, however, the status bar will be visible, but transparently overlay your app 🤨And, to add insult to injury: It’ll change the font color of the status bar to white, so that if you rapp comes with a white background, all the user sees are some weird optical artifacts at the top of their screen. ...

July 28, 2025

#14 The process to get an app into Google Play is… byzantine

🏗️First, of course, you actually got to build your app. Then you register at the Google Play Console (and fork over $25). Then you provide your name, contact details, etc. and then the fun starts: You need official ID (drivers license, passport), proof of residence (“Meldezettel” in Austria), proof that you own an Android device, install the Google Play Console App on that device, and verify your contact phone number. ...

July 14, 2025

#12 WebView ↔ Native app communication is easier than you think.

Even without relying on the utilities provided by Capacitor, you can easily pass data back and forth between your web app and its native counterpart: ➡️In JavaScript / TypeScript you can register global functions on the window object. The native code can call these via executeJavaScript() on the WebView. ➡️In the other direction, the native code can register a JavaScript interface on the WebView: webView.addJavascriptInterface(new Object() { @JavascriptInterface public void onSessionId(String value) { SaveUrlHandler.instance.setSessionId(value); } @JavascriptInterface public void closeApp() { MainActivity.this.finish(); } }, "Android"); which the JavaScript / TypeScript code can call whenever it wants: ...

July 12, 2025

#1 Hybrid apps & social logins: tread carefully.

Remember when I talked about “Sign in with Google?” That works really well on the web, but: Once you’re wrapping your web app into a native mobile app, things turn very ugly very soon. In a hosted WebView, Google won’t let you render the sign in button to begin with – unless you override the WebView’s user agent string. After that, you’re still screwed if you rely on the default sign in workflow as this would open a popup window from which the user then can’t navigate back into your app. ...

July 1, 2025