Kurt CapatanMobile Dev
← All work

Telna (formerly KnowRoaming)

KnowRoaming app icon

KnowRoaming App

Sole Android developer on a travel-SIM companion app.

Role
Android Developer (sole Android dev)
When
Mar 2018 – Jan 2021
Platforms
Android
Industry
Telecom, Travel
Release
Released on Google Play; that app is no longer available. In April 2024, Telna sold the KnowRoaming brand to eSimplified, which now publishes a different KnowRoaming eSIM app that I didn't work on.
  • Java → Kotlin
  • MVVM
  • LiveData
  • Data Binding
  • RxJava
  • Coroutines
  • Dagger 2
  • Room
  • WorkManager
  • Gradle product flavors
Onboarding page 2: Roam Smarter for Less, with SMS, voice and data packages
Onboarding from the redesign I built on Android, shown with Android system bars.

About the app

KnowRoaming sold SIM cards and SIM stickers that cut the cost of data, calls and texts abroad. Frequent travellers used the app to buy data plans by country, top up their balance, track their usage and buy a phone number in another country.

What I built

  • Migrated the app from Java to Kotlin, MVVM and Clean Architecture (the deep dive below).
  • Set up Gradle product flavors and restructured the project so the same code could build a branded variant — a client’s white-label version shipped on Google Play.
  • Built airport notifications with WorkManager: a periodic background job checked the device’s location against a worldwide airport list and sent a context-aware reminder — a promotion at a home-country airport, a welcome abroad, or a welcome home.
  • Moved the app’s look into a shared Material theme. Colors, fonts and widget styles live in the theme and style resources, so one change to a button style or a font updates every screen.
  • Routed Crashlytics alerts to a Slack channel with phone notifications, so I saw new crashes quickly, even on weekends.

Deep dive: migrating a legacy codebase while shipping

When I joined, the app was 100% Java with no architecture pattern — business logic lived in Activities and Fragments, and network calls used AsyncTask and HttpURLConnection. That is hard to test and leaks the screen on rotation.

I refactored it feature by feature, so it could keep shipping: I moved business logic into repositories, injected them with Dagger 2, rewrote the code in Kotlin with RxJava and Retrofit, then moved the screens to MVVM with ViewModel and LiveData. Later I added a domain layer with use cases and started using coroutines in new code. I tested throughout with our QA engineer, and made sure every feature worked before each app update.

Technical notes
  • Why RxJava, not coroutines, at first: in 2018 RxJava was the standard for async on Android; coroutines became stable later that year, and I adopted them in new code.
  • Java and Kotlin side by side let me convert one feature at a time. The main risk is nullability where Kotlin calls Java — I checked those values at the boundary.
  • A few older screens were still Java when I left, such as the rates list and the SIM-sticker guide.