Android
Instructions for packaging a Flet app into an Android APK and Android App Bundle (AAB).
See complementary information here.
Prerequisites#
Android SDK#
The build process requires both Java (JDK) and the Android SDK.
If either component is missing or an incompatible version is detected, the required tools will be
automatically installed during the first run of the flet build
command.
- The JDK will be installed in
$HOME/java/{version}
. - If Android Studio is installed, Flet CLI will automatically use the Android SDK bundled with it.
Otherwise, a standalone Android SDK will be installed in:
$HOME/Android/sdk
Android wheels for binary Python packages#
Binary Python packages (in contrast to "pure" Python packages written in Python only) are packages that partially
written in C, Rust or other languages producing native code. Example packages are numpy
, cryptography
, or pydantic-core
.
Make sure all non-pure (binary) packages used in your Flet app have pre-built wheels for Android.
flet build apk
#
Note
This command can be run on a macOS, Linux, or Windows.
Builds a release Android APK.
Release builds are optimized for production, meaning they don’t support debugging and are intended for publishing to app stores such as Google Play.
For Play Store deployment, it’s recommended to:
- Use an Android App Bundle (AAB) for more efficient delivery and smaller install size
- Or split the APK by ABI to reduce the APK size
Split APK per ABI#
Different Android devices use different CPUs, which in turn support different instruction sets. Each combination of CPU and instruction set has its own Application Binary Interface (ABI).
By default, Flet will build a "fat" APK which includes binaries for both
arm64-v8a
and
armeabi-v7a
architectures.
You can split fat APK into smaller APKs for each platform as follows:
Note
Splitting APKs per ABI will generate multiple APK files, each targeting a specific architecture. Make sure to distribute the correct APK to users based on their device's CPU architecture, as installing an incompatible APK will result in installation failure.
Installing APK to a device#
The easiest way to install APK to your device is to use the Android Debug Bridge (adb) tool, a command-line tool that can communicate between your computer and your Android device.
adb
is a part of the Android SDK. On macOS, for example, if the Android SDK was
installed with Android Studio its location will be at ~/Library/Android/sdk/platform-tools/adb
.
Refer to this guide for
more information about installing and using adb
on various platforms.
To install an APK to a device run the following command:
If more than one device is connected to your computer (say, emulator and a physical phone) you can
use -s
option to specify which device you want to install .apk
on:
where <device>
can be found with adb devices
command.
flet build aab
#
Builds a release Android App Bundle (AAB) file.
Release builds are optimized for production, meaning they don’t support debugging and are intended for publishing to app stores such as the Google Play Store.
It is recommended to use this AAB format (instead of APK) for publishing to the Google Play Store due to its optimized app size.
Signing an Android bundle#
Android requires that all APKs be digitally signed with a certificate before they are installed on a device or updated. When releasing using Android App Bundles, you need to sign your app bundle with an upload key before uploading it to the Play Console, and Play App Signing takes care of the rest. For apps distributing using APKs on the Play Store or on other stores, you must manually sign your APKs for upload.
For detailed information, see this guide.
To publish on the Play Store, you need to sign your app with a digital certificate.
Android uses two signing keys: upload and app signing.
- Developers upload an .aab or .apk file signed with an upload key to the Play Store.
- The end-users download the .apk file signed with an app signing key.
To create your app signing key, use Play App Signing as described in the official Play Store documentation.
To sign your app, use the following instructions.
Create an upload keystore#
If you have an existing keystore, skip to the next step. If not, create one using one of the following methods:
- Follow the Android Studio key generation steps.
-
Run the following command at the command line: On macOS or Linux, use the following command:
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA \ -keysize 2048 -validity 10000 -alias upload
On Windows, use the following command in PowerShell:
You will be prompted for several details, such as a keystore password, a key alias, your names and location. Remember the password and alias for use in the configuration step below.keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks ` -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 ` -alias upload
A file named
upload-keystore.jks
will be created in your home directory. If you want to store it elsewhere, change the argument passed to the-keystore
parameter. The location of the keystore file is equally important for the configuration step below.Note
-
The
keytool
command might not be in your path—it's part of Java, which is installed as part of Android Studio. For the concrete path, runflutter doctor -v
and locate the path printed after 'Java binary at:'. Then use that fully qualified path replacingjava
(at the end) withkeytool
. If your path includes space-separated names, such as Program Files, use platform-appropriate notation for the names. For example, on macOS and Linux useProgram\ Files
, and on Windows use"Program Files"
. -
The
-storetype JKS
tag is only required for Java 9 or newer. As of the Java 9 release, the keystore type defaults to PKS12.
-
Important
Keep your keystore
file private; never check it into public source control!
Configuration#
Key alias#
An alias name for the key within the keystore.
Key store#
The path to the keystore file (with extension .jks
).
If you used the cli commands above as-is, this file might be located at /Users/<user name>/upload-keystore.jks
on macOS
or C:\\Users\\<user name>\\upload-keystore.jks
on Windows.
Key store password#
A password to unlock the keystore file (can contain multiple key entries).
If not provided, defaults to the key password
Key password#
A password used to access the private key inside the keystore.
If not provided, defaults to the key store password
Disable splash screen#
The splash screen is enabled/shown by default.
It can be disabled as follows:
Android Manifest#
The Android Manifest describes
essential information about your app to the Android build tools,
the Android operating system, and Google Play. The file in which this information is written
is AndroidManifest.xml
, which gets populated with the information you provide.
Meta-data#
A name-value pair for an item of additional, arbitrary data that can be supplied to the parent component. More information here.
A meta-data item is composed of:
name
: A unique name for the item, usually with a Java-style naming convention, for example"com.sample.project.activity.fred"
.value
: The value of the item. The following types are supported:- String: use double backslashes (
\\
) to escape characters, such as\\n
for a new line and\\uxxxxx
for a Unicode character - Integer: for example
123
- Boolean: either
"true"
or"false"
- Float: for example
1.23
- String: use double backslashes (
You can configure meta-data as follows:
And it will be translated accordingly into this in the AndroidManifest.xml
:
<application>
<meta-data android:name="name_1" android:value="value_1" />
<meta-data android:name="name_2" android:value="value_2" />
</application>
Below are default/pre-configured meta-data:
"io.flutter.embedding.android.EnableImpeller" = false
Features#
A hardware or software feature that is used by the application. More information here.
name
: Specifies a single hardware or software feature used by the application as a descriptor string. Valid attribute values are listed in the Hardware features and Software features sections. These attribute values are case-sensitive.required
: A boolean value (True
orFalse
) that indicates whether the application requires the feature specified by thename
.
You can configure features as follows:
And it will be translated accordingly into this in the AndroidManifest.xml
:
<manifest>
<uses-feature android:name="name_1" android:required="required_1" />
<uses-feature android:name="name_2" android:required="required_2" />
</manifest>
Where the required
value is either true
or false
.
Below are default/pre-configured features:
"android.software.leanback" = False
"android.hardware.touchscreen" = False
Permissions#
Configuring Android permissions and features to be written into AndroidManifest.xml
:
flet build --android-permissions permission=True|False ... --android-features feature_name=True|False
For example:
flet build \
--android-permissions android.permission.READ_EXTERNAL_STORAGE=True \
android.permission.WRITE_EXTERNAL_STORAGE=True \
--android-features android.hardware.location.network=False
Default Android permissions:
android.permission.INTERNET
Default permissions can be disabled with --android-permissions
option and False
value, for example:
Default Android features:
android.software.leanback=False
(False
means it's written in manifest asandroid:required="false"
)android.hardware.touchscreen=False
Configuring permissions and features in pyproject.toml
(notice quotes "
around key names):
[tool.flet.android.permission] # --android-permissions
"android.permission.CAMERA" = true
"android.permission.CAMERA" = true
[tool.flet.android.feature] # --android-features
"android.hardware.camera" = false
ADB Tips#
To run interactive commands inside simulator or device:
To overcome "permissions denied" error while trying to browse file system in interactive Android shell:
To download a file from a device to your local computer: