Preparing Flutter App to Publish on Google Play Store – Adding Launcher Icon & Generating Signed APK

Before we can publish our app on Google Play Store we need to give our app a digital signature by signing it. Also we need to provide a good launcher icon for the app instead of default flutter icon and confirm package name, uses permission or other values are set correctly as we needed.

So, if you are here then I assume you have already completed your app and it is working well. Now what you need is to complete some extra work to make your app to be able to publish on Google Play Store. Here two major steps before publishing an app on Play Store is adding a launcher icon and generating signed APK.

Adding a Launcher Icon

You have developed flutter app and have seen there was a default launcher icon with flutter logo. Launcher icon is the icon that shows up in Android launcher.

Adding launcher icon may be a tedious process but there is a package flutter_launcher_icons for it that makes this process super easy by doing all the work you may need to do. Check out that package for all the guides you need to add a launcher icon. I will also describe important parts here.

First of all, place your launcher icon in your flutter app. It is same as adding assets/images. Let us assume we place icon.png in assets/icon/

Then, add your Flutter Launcher Icons configuration in your pubspec.yaml file.

dev_dependencies:
   flutter_launcher_icons: "^0.8.0"

flutter_icons:
   android: "launcher_icon"
   ios: true
   image_path: "assets/icon/icon.png"

After setting up the configuration run the package.

flutter pub get
flutter pub run flutter_launcher_icons:main

After this all files are generated and configured for your new launcher icon. Next time when you build and install the app you can see default launcher icon will be replaced by new one.

Signing Your Flutter App

Without signing APK, we can not publish it on Google Play Store and even can’t install it on a device. But you have already installed your flutter app while developing, so am I mad? The answer is, your app is already signed with a debug key. That debug key comes with Android SDK and while developing, APK is automatically signed with the debug key by default. By the way the password of the debug keystore is android and you don’t need it now but I told you just for the information or you may need it in future.

If you take a look at <project-root>/android/app/build.gradle. Then you will see something like this;

buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }
    }

But to publish app on Play Store APK should be signed with a private key that represents you and should be kept private. If you want you can take a look at the answers in Stackoverflow – Why should I sign my apk before releasing to PlayStore?

One important thing about app signing is that you need to sign future updates of this app with the same previous private key. If you loose the keystore or forgot the password then you will be unable to publish a new update to that app. However your can recover your key if you lost your keystore in some cases (I have not tried it personally and also don’t want to)I lost my .keystore file?

Then a question arises if it is better to use different key to sign the app when I am working for others or a company, or use the personal key I used to sign my personal apps? The answers is using a different key is always better because in future if I need to leave the company or sell that app to different developer then I do not have to share my private key and password. So why the heck I should share my key? Because other developer needs to update the app I have signed with my private key and without my same key they can not update the app.

So I suggest to create a different key if you are working for others or if you need/planed to sell the app in future and you should really consider having one key per app. Personally I always create a new keystore for a new project and save it inside the same project inside a folder with necessary information. So my folder structure look like this;

This way I will not forget or lost my keystore and password, and I can transfer/sell my published apps easily to another developer. Also we should make sure not to upload this to public places or you can edit .gitignore file to exclude the folder or files from version control.

So I have told all the necessary things you should know before signing a APK. Now we will generate a private key and keystore using keytool and then sing our app.

Create a keystore

To create a keystore in Mac/Linux, you can use following command:

keytool -genkey -v -keystore ~/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key

and for Windows you can use:

keytool -genkey -v -keystore c:\Users\USER_NAME\key.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias key

This command stores the key.jks file in your home directory. If you want to store it elsewhere, change the argument you pass to the -keystore parameter.

If you are creating a separate keystore for the app as I said earlier then you can create a new folder named keys inside root folder of your project and change the -keystore parameter to keys/key.jks use the command from IDE terminal (because IDE opens terminal in the root of the project) as follow;

In Mac/Linux;

keytool -genkey -v -keystore keys/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key

In Windows;

keytool -genkey -v -keystore keys\key.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias key

While creating a keystore you will be asked to enter some details about you and password for keystore and key. For ease we can have same key password as keystore. You will be asked if you want to use key password same as keystore password. A screenshot while creating a keystore for one of my demo app is shown below.

I have just entered my app name everywhere since it is only for learning purpose. However you need to put valid details of yours, like your real name, country etc. And always keeps this key in a safe place, don’t upload it on any public places and don’t forget its password. Saying of uploading it to public places or if your key get stolen, your private key is safe until password is unknown to others. But they can bruteforce or guess so you don’t want to take a risk. Is the RSA private key useless without the password?

Reference the keystore from the app

Create a file named key.properties inside <app_dir>/android/ and add a reference to your keystore:

storePassword=<password from previous step>
keyPassword=<password from previous step>
keyAlias=key
storeFile=<location of the key store file, such as /Users/<user name>/key.jks>

So as of our previous setup my <app_dir>/android/key.properties looks like this:

storePassword=myPassword123
keyPassword=myPassword123
keyAlias=key
storeFile=../../key.jks

Keep the key.properties file private; don’t check it into public source control.

Configure signing in gradle

Configure signing for your app by editing the <app dir>/android/app/build.gradle file.

To load the key.properties file into the keystoreProperties object add following before android block:

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

then it looks like:

Also add signing configurations info before buildTypes block and change signingConfig signingConfigs.debug to signingConfig signingConfigs.release inside buildTypes

signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
            storePassword keystoreProperties['storePassword']
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }

Then is should look like this:

Now your APK will signed with release key automatically.

Reviewing the app manifest

App Manifest file is located at <app dir>/android/app/src/main/AndroidManifest.xml. Before publishing an app we should make sure app has correct name set at android:label in the application tag and has correct package name. By default package name is com.example.<app_name>. So you don’t want that package name to cause problem in future. Here I don’t describe how to change package name. You can see this answer in Stackoverflow – How to change package name in flutter?

Also your app may need internet connectivity or other permissions. In debug mode it is not necessary to add internet permission in Application Manifest for your app to use internet. But in release mode app must have uses permission added in order to function properly. To add internet permission in your app add <uses-permission android:name="android.permission.INTERNET" /> outside application tag. Other permission can be also added in similar way.

Reviewing the build configuration

Review the default Gradle build file file, build.gradle, located in <app dir>/android/app and verify the values are correct as you needed, especially the following values in the defaultConfig block:

  • applicationId – it is the package name as in the AndroidManifest.xml
  • versionCode and verisonName
  • minSdkVersion, compileSdkVersion and targetSdkVersion

Now you can build your APK or App bundle (preferred) which can be uploaded to Play Store Console. You can watch a video about App bundle if you want.

To build App bundle run flutter build appbundle and to build APK run flutter build apk --split-per-abi

For more info about splitting APK, building methods and official documentation about this article you can visit – Build and release an Android app.

After Publishing – App Integrity

So now we have published the app to play store. If you have opted int to Play App Signing then Google will manage your app signing key. It means user will get signed app by Google not you. So what happened to our key we signed before uploading? The key used to sing the apk is only used to upload the apk to Play Console which will identify your identity to Play Console.

Now lets assume you are using some service like Firebase or Facebook authentication then they need sha-1 key or key hash of the app signing key. So these service will stop working in your app because Google signed the final apk. You need to get the sha-1 key from Play Store Console from App Integrity page.

Facebook Developer Console requires key hash in base 64 which can be generated from sha-1.

echo YOUR SHA-1  (Hexadecimal) | xxd -r -p | openssl base64

Here is the original answer in Stack Overflow: https://stackoverflow.com/a/52785464/8880002


More articles for you

Receive New Post by Email

Leave a Reply to Sangam Cancel reply

3 thoughts on “Preparing Flutter App to Publish on Google Play Store – Adding Launcher Icon & Generating Signed APK”

  1. Very helpful. I really want thanks to you for this amazing article. I also inspired by you and create a article How to Publish Flutter app on Apple Store. I hope you will like it.

    Reply