To Programmatically Publish a Flutter app to Google Play involves several steps, from preparing your app for release to actually publishing it on the Google Play Store. Here’s a step-by-step guide to help you through the process:
Prepare Your Flutter App for Release
Before publishing, you’ll need to prepare your Flutter app for release by optimizing it and generating a release build.
a. Update App Details
In your android/app/src/main/AndroidManifest.xml
file, update the following details:
- App name: Set the app name in
<application android:label="@string/app_name" ...>
. More about in an article – fully internationalize Flutter App https://programtom.com/dev/2024/05/22/fully-internationalize-flutter-app/ - App version: In
android/app/build.gradle
, update the version code and version name:android { defaultConfig { ... versionCode 1 versionName "1.0.0" } }
- App Icon: Ensure you have set the correct app icon in the
android/app/src/main/res
folder. You can generate app icons using tools like App Icon Generator. I’ve also developed a tool to generate icons based on your input: https://programtom.com/dev/product/app-images-generator-app/
b. Generate a Signing Key
To publish to Google Play, the app must be signed This is the signing configs above. Generate a signing key using the following command:
keytool -genkey -v -keystore ~/android.jks -keyalg RSA -keysize 2048 -validity 10000 -alias keyAlias
You’ll be prompted for details like your name, organization, location, etc. Make sure to store the generated android.
jks
file securely. Alternatively – you could use tool like keystore explorer https://keystore-explorer.org/
c. Configure App Signing in Gradle
Configure the signing configurations in the android/app/build.gradle
file:
android {
...
signingConfigs {
release {
signingConfigs {
release {
keyAlias 'android'
keyPassword 'your_password'
storeFile file('android.key')
storePassword 'your_password2'
}
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true // Use true for release build to shrink the code
shrinkResources true // Enable to shrink unused resources
}
}
}
Replace android
.jks
, keyAlias
, your_key_password
, and your_store_password
with your actual details.
d. Build the Release APK or AAB
To build the release APK or AAB (preferred format for Play Store), run the following command:
flutter build apk --release # For APK
flutter build appbundle --release # For AAB
The generated file will be located in build/app/outputs
.
Prepare for Google Play Store
Here are some manual steps that are necessary to get your app published.
a. Create a Google Play Developer Account
If you don’t have a Google Play Developer account, you need to create one and pay the registration fee.
b. Create a New App in Google Play Console
Once logged in to the Google Play Console:
- Click Create App.
- Choose a Default language, provide an App name, and set the App or game and Free or Paid options.
- Click Create.
c. Set up App Store Listing
In the Play Console:
- App Information: Provide the required information such as app description, screenshots, icon, and more.
- Content Rating: Fill out the questionnaire to rate your app appropriately.
- App Privacy Policy: Provide a link to your privacy policy if needed.
- There will be more forms to fill according to your app category
- If your app is social media, news app, etc
- You are storing sensitive data
- If your app has ads
- etc
d. Upload APK/AAB
- Navigate to the Release > Production section.
- Click Create a new release.
- Upload the signed APK or AAB generated earlier.
- Review any warnings or errors that the Play Console flags during the upload.
e. Set Pricing and Distribution
Choose whether your app will be free or paid, and select the countries where it will be available.
f. Submit for Review
After completing the store listing and uploading your APK or AAB, review the app settings and submit your app for review.
After Publishing
Once your app is submitted, it will go through the review process by Google, which typically takes a few hours to a few days. If your app passes the review, it will be published on the Play Store.
How to publish programmatically the release
To publish a Flutter app release programmatically to the Google Play Store, you can use Google Play Developer API to automate the process. This allows you to automate tasks like uploading APKs/AABs, updating store listing details, and managing releases without manual intervention through the Play Console.
Here’s a step-by-step guide to programmatically publishing a Flutter app release:
Set Up Google Play Developer API Access
a. Create a Google Cloud Project
- Go to the Google Cloud Console.
- Create a new project, or use an existing project.
- Take note of the Project ID for later use.
b. Enable Google Play Developer API
- In the Google Cloud Console, go to the APIs & Services > Library.
- Search for Google Play Developer API.
- Enable the API for your project.
c. Create Service Account
- Go to APIs & Services > Credentials in the Google Cloud Console.
- Click on Create credentials and choose Service account.
- Provide a name and click Create.
- Assign the Owner role to the service account or at least give it Editor or API access rights.
- After the account is created, download the service account’s private key file (
.json
), which will be used for authentication. Store it securely as – this is authentication item against Google.
Install the Google API Client for Python or Java
Since Flutter doesn’t directly interact with the Google Play Developer API, you’ll need to use some app. Google provides a Python client and Java API to interact with the Play Developer API: https://github.com/googleapis/google-api-java-client-services/tree/main/clients/google-api-services-androidpublisher/v3
Java Google Api Client for Play Developer
Here’s an example of using the Google API Client in Java to upload an APK or AAB to Google Play. This process involves the following steps:
Steps to Follow
- Add Dependencies:
Include the necessary dependencies in yourpom.xml
if you are using Maven:<dependencies> <!-- Google API client dependencies -->
<dependency> <groupId>com.google.apis</groupId> <artifactId>google-api-services-androidpublisher</artifactId> <version>v3-rev20241016-2.0.0</version> </dependency>
</dependencies>
- Create a Service Account:
- In your Google Developer Console, create a service account and download the service account key in JSON format.
- Grant the service account access to your Google Play Developer Console.
- Java Code Example:
Here’s a Java example using the Google Play Developer API to upload an APK or AAB file.
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.FileContent;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisherScopes;
import com.google.api.services.androidpublisher.model.AppEdit;
import com.google.api.services.androidpublisher.model.Track;
import com.google.api.services.androidpublisher.model.TrackRelease;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
public class GooglePlayUpload {
private static final String PACKAGE_NAME = "com.yourcompany.yourapp";
private static final String KEY_FILE_PATH = "path/to/your-service-account-key.json"; // Update this path
private static final String AAB_FILE_PATH = "path/to/your-app-bundle.aab"; // Update this path
public static void main(String[] args) throws GeneralSecurityException, IOException {
// Authenticate using the service account credentials
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(KEY_FILE_PATH))
.createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER));
// Create the AndroidPublisher client
AndroidPublisher publisher = new AndroidPublisher.Builder(
credential.getTransport(),
JacksonFactory.getDefaultInstance(),
credential
).setApplicationName("GooglePlayUpload").build();
// Create a new edit
AndroidPublisher.Edits edits = publisher.edits();
AppEdit appEdit = edits.insert(PACKAGE_NAME, null).execute();
String editId = appEdit.getId();
// Upload the AAB file
FileContent fileContent = new FileContent("application/octet-stream", new File(AAB_FILE_PATH));
AndroidPublisher.Edits.Bundles.Upload uploadRequest = edits.bundles().upload(PACKAGE_NAME, editId, fileContent);
uploadRequest.execute();
// Define the track and release
TrackRelease release = new TrackRelease()
.setVersionCodes(Collections.singletonList(Long.valueOf(1))) // You may want to increment this version
.setStatus("completed"); // Marks the release as completed (published)
Track track = new Track()
.setTrack("production") // Could also be "beta", "alpha", etc.
.setReleases(Collections.singletonList(release));
// Update the track with the new release
edits.tracks().update(PACKAGE_NAME, editId, "production", track).execute();
// Commit the changes
edits.commit(PACKAGE_NAME, editId).execute();
System.out.println("App successfully uploaded and published!");
}
}
Build and Run:
Before running the program, make sure:
- You have set up your service account properly and granted it access to your Google Play Developer Console.
- The paths to the AAB and JSON key file are correct.
- You have a valid AAB file ready for upload.
Then, compile and run your program using your preferred method (e.g., from an IDE like IntelliJ or Eclipse, or via command-line tools).
API Scopes and Permissions:
Make sure the service account has the necessary permissions in the Google Play Developer Console. It must be assigned Release Manager or higher permission to upload and publish the app. There are actually two places where you need permissions set
- Google Play
- Google Cloud Console.
Especially when you are a consultant and you don’t have full permissions – you may need to go back and forth until setttings are OK.
Python version
To install the Python client, run:
pip install google-api-python-client google-auth google-auth-oauthlib google-auth-httplib2
Create the Script to Upload the Release
Here’s an example script to upload an APK or AAB to Google Play using the Python API client.
from google.oauth2 import service_account
from googleapiclient.discovery import build
import google.auth
# Path to your service account key file
SERVICE_ACCOUNT_FILE = 'path_to_your_service_account_key.json'
# Your package name (com.example.app)
PACKAGE_NAME = 'your.package.name'
# Authentication and API initialization
credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=['https://www.googleapis.com/auth/androidpublisher'])
service = build('androidpublisher', 'v3', credentials=credentials)
# Step 1: Create an Edit
edit_request = service.edits().insert(body={}, packageName=PACKAGE_NAME).execute()
edit_id = edit_request['id']
print(f"Created edit with ID: {edit_id}")
# Step 2: Upload the APK or AAB
apk_response = service.edits().bundles().upload(
editId=edit_id,
packageName=PACKAGE_NAME,
media_body='path_to_your_release_bundle.aab' # Use .apk if you're uploading APK
).execute()
version_code = apk_response['versionCode']
print(f"Uploaded AAB with version code: {version_code}")
# Step 3: Assign track (e.g., production, beta)
track_response = service.edits().tracks().update(
editId=edit_id,
packageName=PACKAGE_NAME,
track='production',
body={
'track': 'production',
'releases': [{
'name': 'Release name',
'versionCodes': [version_code],
'status': 'completed'
}]
}
).execute()
print(f"Updated track: {track_response}")
# Step 4: Commit the Edit
commit_response = service.edits().commit(
editId=edit_id,
packageName=PACKAGE_NAME
).execute()
print(f"Committed edit for version code: {version_code}")
Automate the Script Execution
You can trigger this script automatically from your CI/CD pipeline (e.g., GitHub Actions, Jenkins, or GitLab CI) after building your Flutter app.
Here’s how you might automate this in GitHub Actions:
name: Deploy to Play Store
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Install dependencies
run: pip install google-api-python-client google-auth google-auth-oauthlib google-auth-httplib2
- name: Upload AAB to Play Store
run: python upload_to_play_store.py
env:
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.SERVICE_ACCOUNT_KEY }}
In this example, the service account key (SERVICE_ACCOUNT_KEY
) would be stored in your GitHub secrets.
Monitor the Publishing Process
Once the release is uploaded and committed, you can monitor the status of the release programmatically by querying the Play Developer API or checking the Play Console.
Handle Error Handling and Retries
To make your script production-ready, you should handle potential errors (like timeouts, invalid APKs, or permission issues) and implement retries as necessary.
And there is another Script Version for uploading apps to the store – and it is using fastlane: