Testing Mobile Application Compatibility Across Devices
Designer drew mockup for iPhone 14 Pro with 6.1'' screen and Dynamic Island. Developer checked on same device. Release shipped, turned out: on Samsung Galaxy A03 with 720×1600 screen Confirm button goes off-screen because layout done for safe area which old Samsung doesn't have. On iPad Mini bottom navigation takes third of screen because nobody tested on tablet.
Devices too different. No single solution — methodical testing exists.
How Devices Differ
Not just by screen size. Here's what actually impacts app behavior:
Resolution and pixel density. ldpi (120 dpi), mdpi (160), hdpi (240), xhdpi (320), xxhdpi (480), xxxhdpi (640). Icons without adapted variants look blurry or huge. On Redmi 720p and Samsung 1080p at same diagonal — different density, different dp→px conversions.
Aspect ratio. 16:9 (720×1280) standard outdated. Current: 20:9 (Samsung S-series), 19.5:9 (iPhone), 21:9 (Sony Xperia), foldables with variable ratio. Layout hardcoding element heights breaks on non-standard proportions.
Safe Area and cutouts. Dynamic Island (iPhone 14 Pro+), notch-hole (Samsung), punch-hole camera (most modern Android). On Android — WindowInsets and displayCutout. Content goes under camera without cutout handling.
Hardware performance. Qualcomm Snapdragon 8 Gen 3 in flagship vs MediaTek Helio G85 in budget device — different performance levels. 120 fps animations smooth on flagship stutter on mid-range. Complex Compose layouts with multiple recompositions feel this.
Hardware capabilities. No NFC (budget devices), no barometer, no LiDAR, no Face ID. Without checking PackageManager.hasSystemFeature() attempt to use unavailable hardware — crash or silent fail.
Device Matrix
Compile based on analytics (Firebase, Mixpanel by device_model), general market stats, and business requirements:
| Category | Examples | Why Include |
|---|---|---|
| Flagship iOS | iPhone 15 Pro, iPhone 14 | Target audience, Dynamic Island |
| Compact iOS | iPhone SE 3rd gen | Small screen, no notch |
| Tablet iOS | iPad (10th gen), iPad Pro | Wide screen, Split View |
| Flagship Android | Google Pixel 8, Samsung S24 | Current Android, OLED |
| Mid-range Android | Samsung A54, Xiaomi Redmi Note 12 | Largest market share |
| Budget Android | Samsung A03, Redmi 10 | Low performance, 720p |
| Tablet Android | Samsung Galaxy Tab S9 | Adaptive layout |
| Foldable | Samsung Z Fold 5 | If form-factor supported |
Minimum matrix for most projects: 5–7 devices. More — via BrowserStack or Firebase Test Lab (real devices without purchase).
Testing Adaptive Layout
On Android — WindowSizeClass from Jetpack Compose:
val windowSizeClass = calculateWindowSizeClass(this)
when (windowSizeClass.widthSizeClass) {
WindowWidthSizeClass.Compact -> PhoneLayout() // < 600dp
WindowWidthSizeClass.Medium -> TabletLayout() // 600–840dp
WindowWidthSizeClass.Expanded -> DesktopLayout() // > 840dp
}
Test all three classes: Compact (phone portrait), Medium (tablet portrait or phone landscape), Expanded (tablet landscape).
On iOS — horizontalSizeClass in SwiftUI:
@Environment(\.horizontalSizeClass) var sizeClass
var body: some View {
if sizeClass == .compact {
VStack { ... }
} else {
HStack { ... } // iPad, landscape iPhone Plus
}
}
Foldable Specifics
Samsung Galaxy Z Fold — two modes: folded (compact, 22:9) and unfolded (large screen, ~4:3). App correctly transitions between modes without state loss. onConfigurationChanged called on fold/unfold. If Activity recreates — all unsaved form data lost.
Check: focus in TextField preserved, scroll position restored, modals don't jump.
Hardware Capability Check
// Android: check before use
val hasBluetooth = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)
val hasNfc = packageManager.hasSystemFeature(PackageManager.FEATURE_NFC)
val hasCamera = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
If feature unavailable — hide UI element or show explanation. Don't crash, don't show unavailable button.
Timeline
2–3 days — compiling device matrix from analytics, testing on priority devices (emulators + cloud farm), report with incompatibility matrix and screenshots. Cost is calculated individually.







