Deploy Android App
Prerequisites
-
Enable App Check for Android (see App Check setup)
-
Install Java Development Kit (JDK)
App Signing
-
Generate a keystore:
Terminal window keytool -genkey -v -keystore upload-keystore.jks \-keyalg RSA \-keysize 2048 \-validity 10000 \-alias upload -
Create
android/key.properties
:storePassword=<password from previous step>keyPassword=<password from previous step>keyAlias=uploadstoreFile=../upload-keystore.jks -
Update
android/app/build.gradle
:def keystoreProperties = new Properties()def keystorePropertiesFile = rootProject.file('key.properties')if (keystorePropertiesFile.exists()) {keystoreProperties.load(new FileInputStream(keystorePropertiesFile))}android {signingConfigs {release {keyAlias keystoreProperties['keyAlias']keyPassword keystoreProperties['keyPassword']storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : nullstorePassword keystoreProperties['storePassword']}}buildTypes {release {signingConfig signingConfigs.release}}}
Build for Release
-
Review
android/app/src/main/AndroidManifest.xml
:- Check permissions
- Verify package name
- Update app label and icon
-
Update version in
pubspec.yaml
:version: 1.0.0+1 # version_name+version_code -
Build app bundle:
Terminal window flutter build appbundle --releaseThe bundle will be at:
build/app/outputs/bundle/release/app-release.aab
Play Store Setup
-
Create app in Google Play Console
-
Complete store listing:
- App name and description
- Screenshots and videos
- Graphics assets
- Content rating
- Privacy policy
-
Set up pricing and distribution:
- Choose countries
- Set price (if not free)
- Select content rating
- Accept developer agreement
Release Process
-
Create new release:
- Go to Production > Create new release
- Upload your app bundle
- Add release notes
-
Run pre-launch report:
- Check for crashes
- Verify on different devices
- Review performance metrics
-
Submit for review:
- Review all details
- Submit to Google Play
- Monitor review status
CI/CD Setup
Add this to your GitHub Actions workflow:
name: Deploy to Play Storeon: push: tags: [ 'v*' ]
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
- uses: subosito/flutter-action@v2 with: channel: 'stable'
- name: Create key.properties run: | echo "storePassword=${{ secrets.KEY_STORE_PASSWORD }}" >> android/key.properties echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> android/key.properties echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> android/key.properties echo "storeFile=../upload-keystore.jks" >> android/key.properties
- name: Decode Keystore run: | echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > upload-keystore.jks
- name: Build & Deploy run: | flutter build appbundle --release
- uses: r0adkll/upload-google-play@v1 with: serviceAccountJson: ${{ secrets.PLAY_STORE_ACCOUNT_KEY }} packageName: com.yourdomain.app releaseFiles: build/app/outputs/bundle/release/app-release.aab track: production
Internal Testing
Before public release:
-
Create internal testing track:
- Upload your app bundle
- Add test users by email
- Share opt-in URL
-
Test thoroughly:
- Installation process
- All core features
- Performance and crashes
- In-app purchases (if any)
-
Monitor analytics:
- Crash reports
- User feedback
- Performance metrics