Telna (formerly KnowRoaming)
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.
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.
Showcase
From development and test builds, mostly with test data. The released app may differ.