Android App Development: Kotlin, Jetpack Compose and Google Play

How we build Android apps with Kotlin and Jetpack Compose, handle device fragmentation across the whole device range, and ship reliably through Google Play.

Device outlines from a compact phone to a foldable and a tablet on one baseline, showing the Android device range.

Android app development is mostly about respecting range. Your app will run on flagships and budget handsets, on tablets and foldables, and on phones whose manufacturers tuned memory and battery management their own way, and it has to feel fast and trustworthy on all of them. In many markets, it is also the platform most of your customers carry.

Good looks like a Kotlin codebase built with Jetpack Compose on a clear architecture, tested against the devices your users actually own, and released through Google Play with staged rollouts and healthy vitals. This article covers how we build that, and where the platform’s rough edges are.

What we build on Android

We build Android apps for companies moving a service from offline to online, from desktop to mobile, or from a single channel to several. Typical products:

  • Consumer apps that connect a business with its customers: booking, ordering, account management and support.
  • Marketplaces and service platforms where both sides of the market use Android.
  • Companion apps for IoT hardware, where Android’s Bluetooth and background work APIs do the heavy lifting.
  • Payment and banking apps, including NFC features that Android has long opened to developers.
  • Field and enterprise apps on managed or rugged devices, sometimes with built-in barcode scanners or a locked-down kiosk mode.
  • An Android version of a product that exists only on iOS today.

Kotlin, Jetpack Compose and a clear architecture

New Android work is written in Kotlin, which Google recommends as the primary language for the platform. Its null safety removes a whole class of crashes, and coroutines with Flow make asynchronous code readable. If you have an existing Java codebase, the two languages interoperate, so conversion can happen file by file as code is touched rather than in a risky rewrite.

Three stacked layers for UI, domain and data, linked by a loop of arrows showing one-directional data flow.

For UI we use Jetpack Compose, Android’s declarative toolkit. Screens take less code than the old XML views, previews shorten the design loop, and a custom design system is far easier to build than it was with themes and styles. Compose and Views interoperate in both directions, so an older app can adopt Compose one screen at a time. Two habits matter: watching for unnecessary recomposition, the usual cause of janky Compose screens, and measuring performance only on release builds, because debug builds of Compose are much slower than what users get.

Underneath, we follow the layered architecture Google recommends:

  • A UI layer of composables and ViewModels that expose immutable screen state, with events flowing in one direction.
  • A data layer of repositories that hide whether data comes from the network, a Room database or DataStore.
  • An optional domain layer for business rules that several screens share.

Around that sit Hilt for dependency injection, Retrofit or Ktor for networking, WorkManager for background work that must survive the app being closed or the phone restarting, and a Gradle build split into modules so builds stay fast and features have clear owners. For a small app, some of this is overkill; a single module with manual dependency injection is a legitimate choice, and we will say so. If you also ship on iOS, Kotlin Multiplatform can share the data and domain layers while each platform keeps its own native UI.

Designing for the whole device range

Fragmentation is real, but it is manageable when you treat it as a set of decisions rather than a vague fear.

  • Minimum Android version. Every older version you support adds users and adds compatibility work. We set the minimum from your market and your analytics, not from habit.
  • Screen sizes. Layouts adapt to window size classes, so the same app works on a small phone, a foldable in either posture, a tablet and a ChromeOS laptop. Newer Android versions increasingly ignore orientation and resizability locks on large screens, so a portrait-only phone layout is no longer a safe assumption.
  • System UI. Recent versions draw apps edge to edge and animate predictive back gestures, so handling insets and back navigation correctly is now part of the baseline.
  • Manufacturer behavior. Some manufacturers stop background work aggressively to save battery. Using WorkManager and correctly declared foreground services, and testing on the brands that dominate your market, avoids notifications that never arrive and syncs that never run.
  • Low-end hardware. Limited memory and slower storage expose sloppy startup code. Baseline Profiles precompile the hot paths, R8 shrinks and optimizes the app, and an inexpensive phone is part of every release test.

For testing, emulators cover the spread of Android versions, a small set of physical devices covers manufacturer quirks, and a cloud device lab such as Firebase Test Lab adds breadth before major releases. Screenshot tests catch layouts that break at large font sizes or unusual screen widths long before a user does.

Security, accessibility and performance

Android apps often handle payments, health data or access to physical devices, so security is designed in from the start:

  • Keys and credentials protected by the Android Keystore, with biometric confirmation through BiometricPrompt where it adds real protection.
  • TLS everywhere, a network security configuration that forbids cleartext traffic, and certificate pinning only where you can manage key rotation.
  • No API secrets in the app package, since anything shipped in an APK can be extracted.
  • Exported activities, services and receivers reviewed, because other apps can call them.
  • The Play Integrity API to check for tampered apps and compromised devices when fraud is a real risk.
  • Data handling that meets GDPR and Turkey’s KVKK where they apply, with the OWASP mobile standard (MASVS) as the checklist for sensitive apps.

Accessibility on Android means meaningful semantics in Compose so TalkBack reads screens in a sensible order, text sized in scalable units so it respects the user’s font setting, touch targets of at least 48dp, and contrast that holds up outdoors. We check with TalkBack and Accessibility Scanner during QA, not after launch.

Performance is measured the way Google measures it: startup time, frame rendering, ANRs and crash rate, tracked in release builds and in Play Console after launch. Macrobenchmark tests keep startup and scrolling from quietly regressing between releases.

Shipping on Google Play

Google Play is more forgiving than the App Store in some ways and stricter in others. Here is what we set up for every Android release:

Widening arcs from an app package with a barrier gate, showing a staged Google Play rollout that can be halted.
  • The right account. We publish under your organization’s developer account with Play App Signing enabled. Organization accounts need a D-U-N-S number, and they avoid the closed-testing requirement that newer personal accounts must meet before publishing to production.
  • App bundles and testing tracks. Releases ship as Android App Bundles, so each device downloads only what it needs. Internal testing gives your team every build; closed and open tracks bring in real users before production.
  • Staged rollouts. Production releases reach a small share of users first and widen while crash and ANR rates stay healthy, so a bad release can be halted before most users see it.
  • Policy work. The Data safety form, content rating and declarations for sensitive permissions such as background location are prepared alongside the build, not the night before. Google also raises the required target API level on a regular schedule, so even stable apps need a yearly update.
  • Android vitals. Poor crash and ANR rates can reduce how visible your app is on Google Play, so we treat vitals like product metrics.
  • The listing. A clear title and short description, screenshots that show the product, and the in-app review API to ask satisfied users for a rating at the right moment. Ranking well on Google Play starts with an app that earns good reviews.

How we approach Android app development

Discovery starts with your market: which devices and Android versions your customers use, which manufacturers dominate, and which permissions the product really needs, since some trigger extra review on Google Play. We also agree the analytics events up front, so you can measure what the app achieves rather than guess.

Design adapts your brand to Android’s conventions, including system back, Material components where they help, and large-screen layouts decided explicitly rather than discovered in QA. Engineering runs in short iterations, each ending with an installable build on the internal testing track, and QA tests on the device matrix agreed in discovery.

We take on Android as a dedicated product team (a business analyst, a designer, Android engineers, QA and a backend engineer when needed) or as a focused engagement, such as adding Android to an existing iOS product or modernizing an older Java and XML app. You get the code in your repository, the app in your Play Console, regular demos and written reports.

Native Android is not always the right call. If you need iOS as well and the app is mostly screens over an API, one React Native codebase is often better value. If your product depends on deep device capabilities and you need both platforms, see native mobile app development. And if you mainly need reach, Android is the friendliest platform for installable web apps; HTML5 app development covers that route.

Frequently asked questions

Should we use Jetpack Compose or XML views?

Compose for anything new. For an existing View-based app, adopt Compose screen by screen as features change; rewriting working screens all at once rarely pays for itself.

Our app is written in Java. Do we need to rewrite it?

No. Kotlin and Java work side by side in the same project. New code goes in Kotlin, and older code is converted when it is being changed anyway, with tests around it.

What is the oldest Android version we should support?

The one your data justifies. Check which versions your customers actually run, then weigh the users an older minimum adds against the compatibility work and testing it costs.

How long does Google Play review take?

It varies from hours to several days, and first submissions, new developer accounts and apps requesting sensitive permissions tend to take longer. We plan releases with that buffer instead of promising a date that depends on someone else’s queue.

Can you build the Android version of our iOS app?

Yes. We reuse your backend and product decisions, adapt the design to Android conventions rather than copying iOS screens, and agree a plan for keeping the two apps at feature parity.

If Android is where your customers are, or where your product needs to go next, tell us about your product. We will look at your market, your devices and your goals, and tell you plainly how we would build it.