android-development/SKILL.md
Android development standards for AI agent implementation. Kotlin-first, Jetpack Compose UI, MVVM + Clean Architecture, Hilt DI, comprehensive security, testing, and performance patterns. Use when building or reviewing Android applications...
npx skillsauth add peterbamuhigire/skills-web-dev android-developmentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
android-development or would be better handled by a more specific companion skill.references only as needed.SKILL.md first, then load only the referenced deep-dive files that are necessary for the task.references/ directory for deep detail after reading the core workflow below.world-class-engineering for shared production gates.system-architecture-design when the Android app is part of a larger backend or multi-module system.vibe-security-skill and feature-specific skills as needed.Production-grade Android development standards for AI-assisted implementation. Kotlin-first with Jetpack Compose, following modern Android best practices.
Core Stack: Kotlin 100% | Jetpack Compose (default UI toolkit) | MVVM + Clean Architecture | Hilt DI Min SDK: 29 (Android 10) | Target SDK: 35 (Android 15) Compatibility: Must run flawlessly on BOTH the minSdk (oldest supported) AND the latest stable Android release Reference App: Now in Android - Google's official sample demonstrating these standards in a production-quality codebase
Android apps connect to a PHP/MySQL backend deployed across three environments:
| Environment | Base URL Pattern | Database | Notes |
|---|---|---|---|
| Development | http://{LAN_IP}:{port}/DMS_web/api/ | MySQL 8.4.7 (Windows WAMP) | Use host machine's LAN IP, not localhost |
| Staging | https://staging.{domain}/api/ | MySQL 8.x (Ubuntu VPS) | For QA and testing |
| Production | https://{domain}/api/ | MySQL 8.x (Debian VPS) | Live users |
Configure base URLs using build flavors (dev, staging, prod) so the app targets the correct backend per build variant. All backends use utf8mb4_unicode_ci collation and MySQL 8.x.
| Topic | Reference File | Covers |
| --------------------------- | ------------------------------------- | ----------------------------------------------- |
| Project Structure | references/project-structure.md | Directory layout, module organization |
| Kotlin Conventions | references/kotlin-conventions.md | Coding style, Compose patterns |
| Architecture | references/architecture-patterns.md | MVVM, Clean Architecture layers |
| Dependency Injection | references/dependency-injection.md | Hilt modules, scoping, ViewModel injection |
| Security | references/security.md | Encrypted storage, biometrics, network security |
| UI Design System | references/ui-design-system.md | Tokens, components, Material 3 |
| Screen Patterns | references/screen-patterns.md | Complete screen templates, state handling |
| Testing | references/testing.md | Unit, UI, instrumentation tests |
| Build Configuration | references/build-configuration.md | Gradle KTS, dependencies, build types |
| API Integration | references/api-integration.md | Retrofit, error handling, repository pattern |
| Analytics & Performance | references/analytics-performance.md | Firebase, monitoring, optimization |
| AI Agent Guidelines | references/ai-agent-guidelines.md | Prompt templates, quality checklists |
Presentation Layer (Compose + ViewModels)
|
Domain Layer (Use Cases + Repository Interfaces)
|
Data Layer (Repository Impl + API + Room)
com.company.app/
core/ # Shared: DI, models, repositories, utils
data/ # Room DB, API services, data sources
presentation/ # Screens, ViewModels, components, navigation
theme/ # Design system tokens
LaunchedEffect for side effects, never in compositioncollectAsStateWithLifecycle() for Flow collectionLazyColumn/LazyRow itemsWindowSizeClass for phone/tablet/foldableandroidx.compose.material3.adaptive:adaptivepainterResource(R.drawable.<name>) or @drawable/<name>PROJECT_ICONS.md in the project rootFollow the android-custom-icons skill for naming, directory rules, and tracking.
android-report-tables skill for table-first patternsEvery Android app MUST have exactly 3 build variants. This is non-negotiable.
| Variant | Purpose | APK Name | Minified | Install Target |
|---------|---------|----------|----------|----------------|
| debug (dev) | Local development | {AppName}-dev-{version}.apk | No | Emulator (default) |
| staging | QA / pre-production | {AppName}-staging-{version}.apk | Yes (R8) | Emulator (on request) |
| release (prod) | Production / Play Store | {AppName}-prod-{version}.apk | Yes (R8) | Device (manual) |
Rules:
http://10.0.2.2/... for emulator or the host LAN IP)../gradlew assembleDebug assembleStaging assembleRelease./gradlew installDebug./gradlew installStagingDMS-dev-1.0.0.apk, DMS-staging-1.0.0.apk, DMS-prod-1.0.0.apk). Configure via applicationVariants.all in build.gradle.kts.Log.v, Log.d, Log.i, and println from staging and release builds.BuildConfig.API_BASE_URL (or similar) set per build type.See references/build-configuration.md for the complete Gradle setup.
Our apps MUST work for the few people still holding older devices, but MUST ALSO WORK for those with newer/latest devices. Never test only on one Android version.
Mandatory rules:
enableEdgeToEdge() is REQUIRED — Call it in MainActivity.onCreate() before super.onCreate(). Android 15 (API 35) enforces edge-to-edge for apps targeting SDK 35. Without it, the app crashes immediately on Android 15 devices. This is non-negotiable.window.statusBarColor directly — It is deprecated and conflicts with edge-to-edge. Let enableEdgeToEdge() handle system bar colors. Only control light/dark icon appearance via WindowCompat.getInsetsController().isAppearanceLightStatusBars.if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.X) checks.AppCompatActivity when locale switching is needed (AppCompatDelegate.setApplicationLocales()). Otherwise prefer ComponentActivity for pure Compose apps.Correct MainActivity pattern:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen() // Before super
enableEdgeToEdge() // Before super — MANDATORY for targetSdk 35
super.onCreate(savedInstanceState)
setContent { ... }
}
}
EncryptedSharedPreferences for sensitive dataSSLPeerUnverifiedException). Extract real SHA-256 pins from servers using openssl before enabling. See references/security.md for the extraction command.ENABLE_CERT_PINNING BuildConfig flag: false for dev, true for staging/prodBuildConfig fieldsderivedStateOf for expensive calculationsBefore calling an Android feature production-ready:
localhost.BASE_URL in the Android dev build.Every Android app MUST include a theme appearance selector in its Tools/Settings section. This is a non-negotiable standard — users must be able to control the app's visual theme.
Requirements:
Implementation pattern:
// 1. ThemePreferences.kt (data/local/prefs/)
enum class ThemeMode(val key: String, val label: String) {
SYSTEM("system", "System default"),
LIGHT("light", "Light"),
DARK("dark", "Dark");
companion object {
fun fromKey(key: String): ThemeMode =
entries.firstOrNull { it.key == key } ?: SYSTEM
}
}
@Singleton
class ThemePreferences @Inject constructor(
@ApplicationContext context: Context
) {
private val prefs = context.getSharedPreferences("theme_prefs", Context.MODE_PRIVATE)
private val _themeMode = MutableStateFlow(loadThemeMode())
val themeMode: StateFlow<ThemeMode> = _themeMode.asStateFlow()
private fun loadThemeMode(): ThemeMode =
ThemeMode.fromKey(prefs.getString("theme_mode", "system") ?: "system")
fun setThemeMode(mode: ThemeMode) {
prefs.edit().putString("theme_mode", mode.key).apply()
_themeMode.value = mode
}
}
// 2. MainActivity.kt — resolve ThemeMode to darkTheme boolean
val themeMode by themePreferences.themeMode.collectAsState()
val darkTheme = when (themeMode) {
ThemeMode.SYSTEM -> isSystemInDarkTheme()
ThemeMode.LIGHT -> false
ThemeMode.DARK -> true
}
AppTheme(darkTheme = darkTheme) { /* content */ }
// 3. Tools/Settings screen — FilterChip row for selection
ThemeMode.entries.forEach { mode ->
FilterChip(
selected = selected == mode,
onClick = { viewModel.setThemeMode(mode) },
label = { Text(mode.label) },
leadingIcon = if (selected == mode) { { Icon(Icons.Default.Check, null) } } else null
)
}
When building a native Android app for an existing SaaS backend, always implement Phase 1 first: Login + Dashboard + Empty Tabs. This is the mandatory starting point before any business features.
See android-saas-planning skill for the complete Phase 1 plan template.
If this is a Kotlin Multiplatform project, this skill governs the
composeApp/ module (Android UI and platform integration). The shared/
module is governed by the kmp-development skill. Use Hilt for DI in
composeApp/ and Koin in shared/. Use kmp-tdd for shared module tests.
mutableStateOf in ViewModels instead of StateFlowkey parameter in LazyColumn itemscollectAsStateWithLifecycle)isTablet() checks instead of WindowSizeClass breakpointsenableEdgeToEdge() — causes immediate crash on Android 15 deviceswindow.statusBarColor directly — deprecated, conflicts with edge-to-edgefeature-planning -> spec + implementation strategy
|
android-development -> Kotlin/Compose implementation
|
google-play-store-review -> Play policy and submission readiness
|
api-error-handling -> Backend API error patterns
|
mysql-best-practices -> Database schema (backend)
|
vibe-security-skill -> Security review
Always apply vibe-security-skill alongside this skill for web-connected Android apps.
Use google-play-store-review when preparing Play Console submissions.
Google maintains three official reference repos. Use them as canonical examples:
Full production-quality app. Use for: multi-module architecture, convention plugins, offline-first (Room + network sync), Hilt across modules, version catalogs, Gradle KTS build config.
Layered architecture TODO app. Use for: MVVM pattern clarity, Repository pattern with dual data sources, single-activity navigation with Compose, product flavors (mock/prod), comprehensive test suite (unit + integration + E2E), clean separation of concerns.
Collection of focused Compose apps. Use for specific UI patterns:
| Sample | Use For | | ------------- | ----------------------------------------------------------- | | JetNews | Material app structure, theming, Compose testing | | Jetchat | Material 3, dynamic colors, navigation, state management | | Jetsnack | Custom design systems, layouts, animations | | Jetcaster | Redux-style architecture, dynamic theming, Room, coroutines | | Reply | Adaptive UI (phone/tablet/foldable), Material 3 | | JetLagged | Custom layouts, graphics, Canvas/Path drawing |
When in doubt about how to implement something, check these repos first.
data-ai
Use when adding AI-powered analytics to a SaaS platform — semantic search over business data, natural language queries, trend detection, anomaly alerts, and AI-generated insights for dashboards. Covers embeddings, NL2SQL, and per-tenant analytics...
data-ai
Design AI-powered analytics dashboards — what metrics to show, how to display AI predictions and confidence, drill-down patterns, KPI cards, trend visualisation, AI Insights panels, export design, and role-based dashboard variants. Invoke when...
development
Use when designing, building, reviewing, or upgrading production software systems that must be secure, performant, maintainable, scalable, and user-centered. Apply before writing specs, code, architecture, APIs, databases, mobile apps, SaaS platforms, or ERP systems.
development
Professional web app UI using commercial templates (Tabler/Bootstrap 5) with strong frontend design direction when needed. Use for CRUD interfaces, dashboards, admin panels with SweetAlert2, DataTables, Flatpickr. Clone seeder-page.php, use...