Phase 4
Publish on Google Play
Signing, AAB, Play Console, testing tracks, rollout
The full Android release path. Work through it in order — the keystore step in particular is irreversible, and getting it wrong means you can never update your app again under the same listing. Once your keys are saved in the build console, the 'Store page' tab does the last part for you: fill in the title, descriptions and pictures, then press 'Send app and store page to Google Play' and the machine builds, signs and sends everything in one go. Google still reviews it, and the account, fees, data safety form and tester rules below remain yours to complete.
| Field | Meaning | Rule |
|---|---|---|
versionName | What users see: 1.0.0 | Any string; semantic versioning is conventional |
versionCode | Internal integer: 1 | Must increase with EVERY upload, forever. Never reuse. |
android {
namespace "com.example.myapp"
compileSdk 35
defaultConfig {
applicationId "com.example.myapp"
minSdk 23
targetSdk 35
versionCode 1
versionName "1.0.0"
}
}Generate your upload keystore — back it up immediately
Run this from your project root. Store the file, the alias my-app-upload and both passwords in a password manager before you do anything else.
keytool -genkey -v \
-keystore my-app-upload.keystore \
-alias my-app-upload \
-keyalg RSA \
-keysize 2048 \
-validity 10000Answer the prompts with real details (name, organisation, city, two-letter country code). Validity of 10000 days is standard — a keystore that expires mid-life is unrecoverable.
storeFile=../../my-app-upload.keystore
storePassword=YOUR_STORE_PASSWORD
keyAlias=my-app-upload
keyPassword=YOUR_KEY_PASSWORDdef keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
signingConfigs {
release {
if (keystorePropertiesFile.exists()) {
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
}
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
}Play requires an AAB (.aab), not an APK. Google generates per-device APKs from it. You still build an APK when you want to sideload for testing.
npm run build
npx cap sync android
cd android
./gradlew clean
./gradlew bundleRelease
# Output:
# android/app/build/outputs/bundle/release/app-release.aabBuild → Generate Signed App Bundle / APK → Android App Bundle
→ choose your keystore → release → Finish./gradlew assembleRelease
adb install -r app/build/outputs/apk/release/app-release.apk- Play Console → Create app.
- App name (30 characters max — this is what shows on the store), default language, App or Game, Free or Paid.
- Accept the developer programme and US export declarations.
- Free vs Paid is permanent. You can make a paid app free, never the reverse.
| Declaration | What it asks | Watch out for |
|---|---|---|
| Privacy policy | Public URL | Must be reachable and actually about this app |
| App access | Do you need login to review? | Provide working demo credentials or review fails |
| Ads | Does the app show ads? | Declaring 'no' while shipping an ad SDK is a suspension |
| Content rating | IARC questionnaire | Answer honestly; a wrong rating gets the app pulled |
| Target audience | Age ranges | Anything under 13 triggers Families policy requirements |
| Data safety | Everything you collect and share | Must match your actual SDKs and permissions |
| Government apps | Are you a government entity? | Usually no |
| Financial features | Loans, payments, crypto? | Extra documentation if yes |
| Health apps | Health-related features? | Extra declarations if yes |
Store listing helper
Write once, copy into both consoles. Counters use the stricter of the two store limits.
Shown above the fold. Lead with the benefit, not the technology.
First two lines matter most. Use short paragraphs and a feature list. No competitor names, no fake claims.
Editable without shipping a new build — good for announcements.
Comma separated, no spaces after commas. Do not repeat words already in your title.
| Store | Asset | Size (px) | Format | Notes |
|---|---|---|---|---|
| Play | App icon | 512 × 512 | PNG, 32-bit | No alpha shown; uploaded in Console |
| Play | Feature graphic | 1024 × 500 | PNG/JPG | Required. Avoid small text |
| Play | Phone screenshots | 1080 × 1920 (min 320px side) | PNG/JPG | 2 minimum, 8 maximum |
| Play | 7" tablet | 1200 × 1920 | PNG/JPG | Needed for tablet featuring |
| Play | 10" tablet | 1600 × 2560 | PNG/JPG | Needed for tablet featuring |
| Play | Promo video | YouTube URL | — | Optional |
| App Store | App icon | 1024 × 1024 | PNG, no alpha | Rejected if transparent |
| App Store | iPhone 6.9" | 1320 × 2868 | PNG/JPG | Required |
| App Store | iPhone 6.5" | 1242 × 2688 | PNG/JPG | Required |
| App Store | iPad 13" | 2064 × 2752 | PNG/JPG | Required if iPad supported |
| Both | Splash source | 2732 × 2732 | PNG | Artwork inside centre 1200px |
- Screenshots must show your actual app — no marketing mock-ups that hide the UI, no device frames that make text unreadable.
- You need at least 2 phone screenshots; supply 4–8 for a credible listing.
- To be featured on tablets and Chromebooks, add 7-inch and 10-inch tablet screenshots.
- The feature graphic is used in the store header and in any promotion — no small text, it gets cropped.
Never upload straight to production. Internal testing is available immediately, accepts up to 100 testers by email, and skips the review queue — it is your smoke test for signing, versioning and the actual store install path.
- Testing → Internal testing → Create new release.
- Upload
app-release.aab. Confirm Play App Signing when prompted. - Write release notes (what changed — users read these).
- Create an email list of testers, save, and copy the opt-in link.
- Open the link on a real phone with a tester account, accept, install from Play, and use the app.
If your Play account is a personal account created after November 2023, this step is mandatory and time-gated: at least 12 testers opted in continuously for 14 days before you can apply for production access.
- Testing → Closed testing → create a track and a tester list of 12+ real Google accounts.
- Send everyone the opt-in link and confirm each one installs the app — an opt-in without an install may not count.
- Tell testers not to leave the programme; the 14 days must be continuous.
- Ship at least one update during the period and collect written feedback.
- After 14 days, Play Console shows an Apply for production button. Answer its questions about what you learned from testing.
- Production → Create new release → upload the AAB (with a higher versionCode than any previous upload).
- Choose countries and regions.
- Set a staged rollout — start at 10–20%. You can halt a staged rollout; you cannot un-publish a 100% release from users who already have it.
- Review the summary, send for review.
- First review usually takes hours to a few days; later updates are typically faster.