mirror of
https://github.com/magnus919/agent-skills.git
synced 2026-09-14 13:06:30 +03:00
f68721873e
ONE family skill covering iOS, Android, Flutter, and React Native with per-framework references (ios.md, android.md, flutter.md, react-native.md), shared scaffold/build/sign/test/ship workflow, mobile lifecycle, offline and sync guidance, and mobile-specific testing. Ships a 5-heading human README and a schema-v1 eval manifest with 6 cases covering build/sign, testing, and store-readiness. Adds the README index entry and regenerates catalogs. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
177 lines
8.3 KiB
Markdown
177 lines
8.3 KiB
Markdown
# Android Reference — Kotlin, Gradle, Google Play
|
|
|
|
> **Last Updated:** 2026-08-03
|
|
|
|
Load this reference when the target platform is **Android** — native Kotlin
|
|
apps built with Gradle, or an Android target inside a Flutter or React Native
|
|
project (tooling for those is in [flutter.md](flutter.md) and
|
|
[react-native.md](react-native.md); this file is the platform layer under
|
|
them). It complements the shared workflow in `SKILL.md`; this file is the
|
|
Android-specific detail for scaffolding, building and signing, emulator and
|
|
device testing, and Play Store submission.
|
|
|
|
## Android fundamentals
|
|
|
|
An Android app is a compiled, signed package built by Gradle:
|
|
|
|
- **Gradle project** — a project root with `settings.gradle(.kts)`, an `app`
|
|
module with `build.gradle(.kts)`, and `gradle/libs.versions.toml` for version
|
|
catalog dependency management. Kotlin DSL (`.kts`) is the current default.
|
|
- **Manifest** — `AndroidManifest.xml` declares the application, activities,
|
|
services, receivers, permissions, and the minimum/target SDK.
|
|
- **Build outputs** — `assembleDebug`/`assembleRelease` produce APKs;
|
|
`bundleRelease` produces an **Android App Bundle (AAB)**, the required
|
|
submission format for new apps on Google Play (since 2021, and still the
|
|
rule). Google Play derives per-device APKs from the AAB via **Play App
|
|
Signing**.
|
|
- **Gradle wrapper** — commit `gradlew` and `gradle/wrapper/` so builds use a
|
|
pinned Gradle version on every machine and CI runner.
|
|
|
|
Keep the version name (`versionName`) and version code (`versionCode`, a
|
|
monotonic integer) in `build.gradle.kts` — Play rejects a build whose version
|
|
code is lower than a previous upload.
|
|
|
|
## Scaffolding
|
|
|
|
- **New native app** — create the project in Android Studio or with the Gradle
|
|
template (`gradle init`); choose Kotlin and Jetpack Compose for new UI.
|
|
- **Minimum and target SDK** — set `minSdk` to the oldest Android version in
|
|
scope and keep `targetSdk` current; Play enforces minimum target API levels
|
|
for new and updated submissions, and raised target levels are announced
|
|
annually.
|
|
- **Dependencies** — prefer version catalogs (`libs.versions.toml`) and commit
|
|
the lockfile (`gradle.lockfile` or dependency locking) for reproducibility.
|
|
- **App structure** — a single-activity app with Compose navigation for new
|
|
work; keep the manifest minimal and declare only the permissions the app
|
|
actually uses.
|
|
|
|
## Builds and signing
|
|
|
|
### Signing model
|
|
|
|
- **Local signing** — a Java keystore (`.jks`/`.keystore`) with an alias,
|
|
configured via `signingConfigs` in `build.gradle.kts`. Signing configs must
|
|
never be committed with their passwords; read them from environment
|
|
variables or a secrets store at build time.
|
|
- **Play App Signing** — Google holds the app signing key; the **upload key**
|
|
you sign with is only used to upload the AAB to Play. Upload keys can be
|
|
rotated without user-visible changes; losing the upload key requires Play
|
|
Console support intervention.
|
|
- **Keystore custody** — the release keystore is a production secret: back it
|
|
up, store it outside the repository, and restrict access. Losing it means
|
|
the app can no longer be updated under the same identity.
|
|
|
|
### Signing practices
|
|
|
|
- **Debug builds sign automatically** with the debug keystore — never ship
|
|
them.
|
|
- **Release builds in CI** — inject keystore path, passwords, and aliases via
|
|
CI secrets; keep `keystore.properties` (or equivalent) out of version
|
|
control. Use `signingConfig` referenced from a file that CI can generate.
|
|
- **Two build types** — `debug` and `release` differ in signing, shrinking
|
|
(R8/ProGuard), and manifest merging. Smoke-test the signed release artifact,
|
|
not just the debug build.
|
|
|
|
### Build commands
|
|
|
|
```sh
|
|
# Debug APK (fast iteration)
|
|
./gradlew assembleDebug
|
|
|
|
# Release APK (signed, shrunk)
|
|
./gradlew assembleRelease
|
|
|
|
# Release App Bundle (required for Play Store submission)
|
|
./gradlew bundleRelease
|
|
```
|
|
|
|
The AAB lives in `app/build/outputs/bundle/release/`; the signed APK in
|
|
`app/build/outputs/apk/release/`. Verify the APK signature with
|
|
`apksigner verify --print-certs app-release.apk` before distribution.
|
|
|
|
## Emulators and devices
|
|
|
|
- **Emulators (AVD)** — Android Studio AVD Manager creates virtual devices;
|
|
headless emulators are scriptable for CI:
|
|
|
|
```sh
|
|
emulator -avd Pixel_8 -no-window -no-audio -no-boot-anim &
|
|
adb wait-for-device
|
|
adb install app/build/outputs/apk/debug/app-debug.apk
|
|
adb shell am start -n com.example.app/.MainActivity
|
|
```
|
|
|
|
- **Physical devices** — enable USB debugging and use `adb devices` to verify
|
|
the connection; real devices reveal networking, battery, and sensor
|
|
behavior the emulator hides.
|
|
- **Debugging** — `adb logcat` for logs, `adb shell dumpsys` for system
|
|
state, and Android Studio Profiler for CPU/memory/network. `adb reverse`
|
|
maps device ports to the host for local API servers.
|
|
- **Device matrix** — cover the min SDK, the current SDK, and a mid-range
|
|
device; use Firebase Test Lab (or a farm) for broad matrix coverage without
|
|
local hardware.
|
|
|
|
## Lifecycle and backgrounding
|
|
|
|
- **Component lifecycle** — Activities/Fragments move through
|
|
started/paused/stopped states; ViewModels survive configuration changes and
|
|
should own UI state. `Process death` can destroy everything else.
|
|
- **State persistence** — save and restore instance state (`SavedStateHandle`,
|
|
`rememberSaveable` in Compose) for process death; persist anything important
|
|
to a durable store.
|
|
- **Background work is restricted** — Android restricts background execution
|
|
and network. Use `WorkManager` for deferrable, guaranteed work, and
|
|
foreground services (with a visible notification) only for user-visible
|
|
tasks. `AlarmManager` is for alarms, not general scheduling.
|
|
- **Doze and app standby** — the system batches background work when idle;
|
|
test offline sync and push handling under Doze, not just with the screen on.
|
|
|
|
## Offline and sync
|
|
|
|
- **Local persistence** — Room (SQLite ORM) for structured data, DataStore
|
|
(Preferences/Proto) for settings, and file storage under the app's
|
|
internal/external storage. Keep the database schema versioned with
|
|
migrations tested.
|
|
- **Sync pattern** — write locally, then sync: queue writes, replay them with
|
|
retry and backoff when connectivity returns, and resolve conflicts
|
|
explicitly. `WorkManager` with network constraints is the idiomatic sync
|
|
trigger.
|
|
- **Connectivity** — use `ConnectivityManager`/NetworkCallback to observe
|
|
connectivity, but design for a lost network degrading gracefully.
|
|
|
|
## Testing
|
|
|
|
- **Unit tests** — JUnit + MockK/mockito for logic; Robolectric runs
|
|
Android-framework code on the JVM for fast local tests.
|
|
- **Instrumented/UI tests** — Espresso (Views) or Compose UI tests
|
|
(`createAndroidComposeRule`) drive the real app on an emulator/device.
|
|
- **Snapshot tests** — Compose Preview-based snapshot testing (e.g.,
|
|
Roborazzi, Paparazzi) catches UI regressions without a device.
|
|
- **Device farms** — run the instrumentation suite on Firebase Test Lab
|
|
across the device matrix; a test passing on one API level is not a
|
|
guarantee across them.
|
|
|
|
## Store submission
|
|
|
|
1. **Play Console setup** — the $25 developer account, app record, and
|
|
developer verification (new developers complete identity verification and
|
|
a closed-test requirement with at least 12 testers for 14 days before
|
|
production access).
|
|
2. **Upload the AAB** — upload `app-release.aab` to an internal, closed, or
|
|
open testing track first; run internal testing with your own devices before
|
|
production. Play generates and signs per-device APKs via Play App Signing.
|
|
3. **Store listing and policies** — screenshots, feature graphic, privacy
|
|
policy URL, and a **data safety** declaration matching what the app
|
|
collects. Play policy review rejects apps for undeclared data collection,
|
|
broken core functionality, and misleading metadata.
|
|
4. **Staged rollout** — use phased rollouts (e.g., 10% → 50% → 100%) and
|
|
monitor crash and ANR rates in Play Console before full release. Pause the
|
|
rollout immediately if a serious regression appears.
|
|
|
|
## Key references
|
|
|
|
- Google Play Console help and policy center (support.google.com/googleplay)
|
|
— current data-safety and testing-track requirements.
|
|
- Android developer documentation (developer.android.com) — target API
|
|
level deadlines and app bundle guidance change annually.
|