iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Android Build

Building an Ionic app for Android goes through Capacitor and Gradle / Android Studio. The pipeline: build the web bundle, copy it into the Android project, generate signed APKs / AABs, and upload to Google Play. Beyond the first signing setup, the rest is one or two commands per release.

End-to-end Android build, signing, and Play upload

EXAMPLE
# 1) Prerequisites
# - Java 17 (or whatever your Gradle wrapper requires)
# - Android SDK + the matching command-line tools
# - Node, Ionic CLI: 'npm i -g @ionic/cli'

# 2) Add the Android platform once per project
ionic capacitor add android

# 3) Build the web bundle for production AND sync into the native project
ionic build --prod
ionic capacitor sync android

# 4) Bump the version (android/app/build.gradle)
# defaultConfig {
#   versionCode 142
#   versionName "1.4.0"
#   minSdkVersion 24
#   targetSdkVersion 34
# }

# 5) Generate a signing key ONCE per app (keep this safe — losing it is fatal)
keytool -genkey -v \
  -keystore ~/keys/shop.jks \
  -alias shop-release \
  -keyalg RSA -keysize 2048 -validity 36500

# 6) Configure signing in android/key.properties (NOT committed)
# storeFile=/Users/you/keys/shop.jks
# storePassword=<store-password>
# keyAlias=shop-release
# keyPassword=<key-password>

# In android/app/build.gradle:
# signingConfigs {
#     release {
#         storeFile     file("${rootProject.projectDir}/key.properties".readKeyProp('storeFile'))
#         storePassword 'env-or-property'
#         keyAlias      'shop-release'
#         keyPassword   'env-or-property'
#     }
# }
# buildTypes { release { signingConfig signingConfigs.release; minifyEnabled true } }

# 7) Build a release AAB (Android App Bundle — what Play wants)
cd android
./gradlew bundleRelease
# Output: android/app/build/outputs/bundle/release/app-release.aab

# 8) Build a release APK (for sideloading or internal QA)
./gradlew assembleRelease

# 9) Upload to Google Play
#  Manually:    Play Console -> Internal testing -> Create release -> upload .aab
#  Via fastlane (CI-friendly):
# Fastfile (android/)
# lane :internal do
#   gradle(task: 'bundleRelease')
#   upload_to_play_store(track: 'internal',
#                        aab: '../app/build/outputs/bundle/release/app-release.aab',
#                        json_key: ENV['PLAY_JSON_KEY'])
# end
# Run: cd android && bundle exec fastlane internal

# 10) Privacy + permissions in AndroidManifest.xml
# Declare every permission a plugin uses; Play rejects mismatches.
# <uses-permission android:name="android.permission.CAMERA"/>
# <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

# 11) Common gotchas
# - 'BUILD FAILED: AAPT': resource conflict between a plugin and your code; rename one.
# - 'Resource not found': missing 'ionic capacitor sync' before the Gradle build.
# - 'Missing 64-bit native code': set abiFilters to include arm64-v8a + x86_64.
# - Play rejection because target SDK is too old: bump targetSdkVersion to the current floor.

# 12) Open the project in Android Studio when you need GUI debugging
ionic capacitor open android

Why it matters

Treat the signing keystore like a production secret — back it up to two locations, store the passwords in your team vault, and never check it into git. Losing the keystore means you can never push an update to the same app on Play; you have to publish a new package id and start the install base from zero.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
ionic build
npx cap sync android
npx cap open android   # → Build → Generate Signed Bundle (.aab)
Try it Yourself »

Discussion

Loading…