/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \page deployment-android.html

    \title Deploying an Application on Android

    This article describes the technical steps required to deploy a Qt
    application to an Android device.

    \section1 Android Application Bundle

    Applications on Android can be packaged in two ways; either as Application
    Package (APK) or Android App Bundle (AAB). Both are ZIP files which follow
    a predefined directory structure. The difference between the two is that APK
    files can be deployed and executed on a device, whereas AAB is intended to
    be interpreted by the Google Play store and is used to generate APK files
    for different device architectures.

    For testing the application locally, the APK format is the most appropriate,
    as this can be uploaded directly to the device and run. For distribution to
    the Google Play store, it is recommended to use AAB instead, which has
    a similar layout. The added convenience of AAB is that you can include all
    target ABIs in the same bundle without increasing the size of the actual
    package downloaded by your users. When using AAB, the Google Play store
    generates optimized APK packages for the devices issuing the download request
    and automatically signs them with your publisher key.

    For more information on the AAB format, see
    \l{Android: App Bundles}{the Android App Bundles}.

    In either case, the application bundle is generated from a specific directory
    structure that contains the \c .so file of your code, as well as all Qt's
    dependencies needed by your application. In addition, any \c .jar files,
    Java code, assets, resources and \c .xml files are included.

    \section2 Generating the Application Bundle

    It is recommended to use Qt Creator or the Makefile created by qmake or CMake
    to create the application bundle.

    All the steps described here are automatically handled by the build script
    and the \l {androiddeployqt}{androiddeployqt deployment tool}, which are run
    by Qt Creator by default.

    \note If you prefer building Android packages from the command line, see
    \l{Building the Android Application}.

    \section1 Android Package Templates

    The default templates used by Qt are found in \c {$Qt_install_dir/src/android/templates}.
    The first step of making a custom package is to copy these files into an
    empty directory, for example \c android, under your project. Then, you need
    to define that path in your project's \c .pro file, using the variable
    \l{ANDROID_PACKAGE_SOURCE_DIR}:

    \badcode
    android {
        ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android

        DISTFILES += \
            android/AndroidManifest.xml \
            android/build.gradle \
            android/res/values/libs.xml
    }
    \endcode

    Qt Creator copies the package templates to your Android build directory
    (\e{$ANDROID_BUILD_DIR=$BUILD_DIR/android-build}) into your project build
    directory (\e$BUILD_DIR). If you want to build from the command line, use
    the following after running \c qmake or \c CMake:

    \code
    make -j$(nproc) apk_install_target
    \endcode

    The previous command copies the application's binaries and resources
    into the $ANDROID_BUILD_DIR. The build directory acts now as the packaging directory,
    which the application bundle is created from. The main parts of the package
    templates are described in the following sections.

    \section2 AndroidManifest.xml

    The \c{AndroidManifest.xml} file gives detailed meta-information about your
    application. This information is used to customize your application bundle
    and by the target device to decide which features to enable, the default
    orientation of the application, and so on. In addition, it's used by the
    Google Play Store for information on the version code, device support,
    package name, and lots more.

    For more information about the \c AndroidManifest.xml, see
    \l{Android: App Manifest}{Android Manifest documentation}.

    The default manifest contains some special parameters used by Qt to set up
    the application and load all the necessary libraries for Qt. When you are
    customizing your own Android manifest, make sure that it contains these
    parameters. For that reason, it's recommended to start with the default
    templates, then customize on top of that. The \l androiddeployqt tool replaces
    content in the templates with the correct values. The parts that are filled
    by \l androiddeployqt have the value as \c "-- %%INSERT_VALUE%% --", as in:

    \badcode
    <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
    <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
    <meta-data android:name="android.app.repository" android:value="default"/>
    <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
    <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
    <!-- Deploy Qt libs as part of package -->
    <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>

    <!-- Run with local libs -->
    <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
    <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
    <meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
    <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
    <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
    \endcode

    The Android Manifest is also used to define \l{Android Services}, and custom
    \l{Android: Introduction to Activities}{Android Activities}.

    \section2 Java Code

    Under \c{$Qt_install_dir/src/android/java/src/org/qtproject/qt5/android/bindings/}
    are the files comprising the Java code of the Android application. This Java
    code is compiled under $ANDROID_BUILD_DIR and added to the application bundle. The
    regular Android application launcher is a Java process, so Qt applications
    have a Java-based entry point. The code in here will load the required Qt
    libraries, based on the meta-information given in Manifest file.

    After loading the libraries, the Java code will call into the application's
    native \c{main()} function on a new thread and the application will launch.
    At this point, the Java code in the templates is used to delegate events from
    Android into Qt.

    One thing to note about the files in this directory is that they can contain
    code specific to certain Android versions. Based on the minimum required
    Android API level of your application it might be necessary to remove some
    of this code. This is done automatically by \c androiddeployqt and Qt Creator
    during packaging.

    If your minimum Android API level is 20 or lower, the code below is removed
    before building, since it's not a supported API on Android API level 20.
    However, if your minimum API level is 21 or higher, it is left in:

    \code
//@ANDROID-21
    @Override
    public void onActivityReenter(int resultCode, Intent data)
    {
        // Do something
        return super.onActivityReenter(resultCode, data);
    }
//@ANDROID-21
    \endcode

    \section2 Resources

    Under the \c{$Qt_instal_dir/src/android/templates/res/} folder are Android
    resources that can be accessed from the \c{AndroidManifest.xml} and Java code
    used by all Qt applications.

    \section3 libs.xml

    This file can be found at \c {$Qt_instal_dir/src/android/templates/res/values/libs.xml}.
    One of the files containing meta information about the deployment of the
    application is \c{libs.xml}. It consists of the following values:

    \list
        \li \c{bundled_libs}: Libraries in the package's library folder which
            should be loaded on start-up. Library names should be specified
            without the \c lib prefix and \c{.so} suffix.

        \li \c{qt_libs}: Qt libraries which should be loaded on start-up. When
            bundled deployment is used, these are expected to be found inside
            the \c{APK}'s library folder.
    \endlist

    \note Ministro is no longer maintained.

    \section3 strings.xml

    This file can be found at \c {$Qt_instal_dir/src/android/java/res/values/strings.xml}.
    The \c{strings.xml} file contains strings used by the \c{AndroidManifest.xml}
    and by the deployment mechanisms.

    In particular, the application name and the name of the application binary
    can be specified here. There are also strings that contain additional
    libraries that should be loaded and \c JAR files which should be included
    in the class path.

    \section3 Gradle Files

    The main Gradle build file can be found at \c {$Qt_instal_dir/src/android/templates/build.gradle}.
    This file is required by the Gradle build system used by Android to generate
    the application's APK. For more information, see
    \l{Android: Build Configuration Files}{Android Build Configuration Files}.

    \section1 Customizing the Package Templates

    \section2 Resouces

    Put any resources used by your application under \c{$ANDROID_PACKAGE_SOURCE_DIR/res/}.
    A typical example of resources customization which should be placed here are
    the icons used by the application launcher to show your application.

    \section2 Custom Java Code

    Place any Java code under the path \c{$ANDROID_PACKAGE_SOURCE_DIR/src/}.
    Any code here can be used with your application, for example you can call
    Java methods from within Qt code. For more information, see
    \l{Qt JNI Messenger}{Qt JNI Messenger Example}.

    When using Qt Creator, add the Java files to your project using \l DISTFILES,
    so they are visible under the project files.

    \section2 Assets

    You can place any assets that are intended to be accessed by Java code under
    \c{$ANDROID_PACKAGE_SOURCE_DIR/assets/}. For more information on using assets
    with Qt, see \l{Porting to Android}.

    \note Using \l{The Qt Resource System} entails having \c{.qrc} files bundled
        in the \c{.so} files which must be unpacked first to be loaded by the
        linker, while the Android assets are compressed in the \e{.apk} and can
        be directly used in your application. That means using the Android assets
        can take up less space, but it's not a cross-platform solution with Qt.

    \section2 Android Libraries

    Under \c{$ANDROID_PACKAGE_SOURCE_DIR/libs} in your custom package directory,
    it's possible to place libraries that should be included in the application
    bundle. \c JAR libraries should be placed directly under
    \c{$ANDROID_PACKAGE_SOURCE_DIR/libs/}, while shared libraries should be put
    in a subdirectory named after the target ABI of the libraries. The supported
    ABIs are: armeabi-v7a, arm64-v8a, x86, x86_64.

    For more information, see also \l{Third-party Android Libraries}.

    \section1 Building the Android Application

    Starting from Qt 5.14.0, you may use the \e "aab" or \e "apk" build targets
    from the Makefile directly to build the application bundle. Use the following
    command to generate an AAB:

    \badcode
    make -j$(nproc) aab
    \endcode

    Or to generate the APK:

    \badcode
    make -j$(nproc) apk
    \endcode

    Under the hood, your Qt code is built and copied to the $ANDROID_BUILD_DIR,
    then \l Gradle is used to build the Java code and package the application.
    If an APK intended for release is built, then it should be signed with
    \c jarsigner and aligned with \c zipalign. For more information on signing
    the package with Qt Creator, see \l{Qt Creator: Signing Android Packages}
    {Signing Android packages}.

    \section1 androiddeployqt

    Building an application package is complex, so Qt comes with a tool which
    handles the work for you. The steps described in this document so far are
    handled automatically by this tool. This section describes some of the steps
    that this tool facilitates.

    \section2 Prerequisites Before Running androiddeployqt

    Before running the tool manually, you need to run \c qmake or \c CMake
    on your project to generate \c Makefiles and a \c JSON file (i.e.
    \c{android-project-deployment-settings.json}) containing important settings
    used by \c androiddeployqt.

    \note It is not recommended to modify the androiddeployqt JSON file.

    To prepare the build for androiddeployqt, it is recommended to build your
    project in a separate directory. Run the following commands:

    \badcode
    mkdir build-project
    cd build-project
    ~/Qt/5.15.0/android/bin/qmake ../project/project.pro
    make -j$(nproc)
    make -j$(nproc) apk_install_target
    \endcode

    \section2 Command Line Arguments

    The only required command line argument when running the tool is \c{--output}.
    Other command line arguments are optional but useful. Here's a quick overview.
    More information is available by passing the \c{--help} argument to androiddeployqt.

    \table
        \header
            \li Argument
            \li Brief Description
        \row
            \li \c{--output <destination>}
            \li Specifies the destination of the final package. Set this to
                \c{$ANDROID_BUILD_DIR}, that is the build directory where you installed
                your application binaries.
        \row
            \li \c{--input <file name>}
            \li This allows you to specify the generated \c JSON settings file.
                \c androiddeployqt will try to guess the file name based on the
                current working directory.
        \row
            \li \c{--aab}
            \li Generate an Android Application Bundle, rather than an APK. Note
                that this invalidates some of the other arguments, such as \c{--install}.
        \row
            \li \c{--deployment <mechanism>}
            \li Specify this to pick a different deployment mechanism than the
                default.
        \row
            \li \c{--install}
            \li Specify this to install the finished package on the target device
                or emulator. Note that if a previous version of the package is
                already installed, it will be uninstalled first, removing any
                data it might have stored locally.
        \row
            \li \c{--device <ID>}
            \li Specify the ID of the target device or emulator as reported by
                the \c adb tool. If an ID is specified, it will be passed to all
                calls to \c adb. If it is unspecified, no particular device or
                emulator will be requested by \c adb, causing it to pick a default
                instead.
        \row
            \li \c{--android-platform <platform>}
            \li The SDK platform used for building the Java code of the application.
                By default, the latest available platform is used.
        \row
            \li \c{--release}
            \li Specify this to create a release package instead of a debug package.
                With no other arguments, release packages are unsigned and cannot
                be installed to any device before they have been signed by a private
                key.
        \row
            \li \c{--sign <url> <alias>}
            \li Sign the resulting package. Specifying this also implies
                \c{--release}. The URL of the keystore file and the alias of the
                key have to be specified. In addition, there are a number of
                options that can be specified which are passed through to the
                \c jarsigner tool. Pass \c{--help} to \c androiddeployqt for
                more information.
        \row
            \li \c{--jdk <path>}
            \li Specify the path to the Java Development Kit. This is only
                required for signing packages, as it is only used for finding
                the \c jarsigner tool. If it is unspecified, then \c androiddeployqt
                will attempt to detect \c jarsigner, either using the \c{JAVA_HOME}
                environment variable, or on the \c PATH.
        \row
            \li \c{--verbose}
            \li Specify this to output more information about what \c androiddeployqt is
                doing.
        \row
            \li \c{--help}
            \li Prints the help for the tool.
    \endtable

    With a project named \c project, to directly build the application package
    with androiddeployqt without deploying it the device, run the following:

    \badcode
    ~/Qt/5.15.0/android/bin/androiddeployqt --input $BUILD_DIR/android-project-deployment-settings.json --output $ANDROID_BUILD_DIR --android-platform android-29 --jdk /usr/lib/jvm/java-8-openjdk-amd64 --gradle
    \endcode

    To deploy the built package to the device:

    \badcode
    ~/Qt/5.15.0/android/bin/androiddeployqt --verbose --output $ANDROID_BUILD_DIR --no-build --input $BUILD_DIR/android-project-deployment-settings.json --gradle --reinstall --device <adb_device_id>
    \endcode

    \section2 Dependencies Detection

    Qt comes with a number of plugins which are loaded at run-time when they are
    needed. These can handle anything from connecting to SQL databases to loading
    specific image formats. Detecting plugin dependencies is impossible as the
    plugins are loaded at run-time, but androiddeployqt tries to guess such
    dependencies based on the Qt dependencies of your application. If the plugin
    has any Qt dependencies which are not also dependencies of your application,
    it will not be included by default. For instance, in order to ensure that
    the SVG image format plugin is included, you will need to add \l{Qt SVG}
    module to your project for it to become a dependency of your application:

    \badcode
    QT += svg
    \endcode

    If you are wondering why a particular plugin is not included automatically,
    you can run androiddeployqt with the \c{--verbose} option to get the list of
    missing dependencies for each excluded plugin. You can achieve the same in
    Qt Creator by ticking the \uicontrol {Verbose output} check box in the
    \uicontrol {Projects} > \uicontrol {Build Steps} > \uicontrol {Build Android APK} >
    \uicontrol {Advanced Actions}.

    It's also possible to manually specify the dependencies of your application.
    For more information, see \l{ANDROID_DEPLOYMENT_DEPENDENCIES} qmake variable.

    \section1 Android-specific qmake Variables

    Unless the project has special requirements such as third party libraries,
    it should be possible to run \l androiddeployqt on it with no modifications
    and get a working Qt for Android application.

    There are two important environment variables used by Qt:

    \list
        \li \c{ANDROID_SDK_ROOT}: specifies the path to the Android SDK used for
            building the application. The Android SDK contains the build-tools,
            Android NDK, and Android toolchains.
        \li \c{ANDROID_NDK_ROOT}: specifies the path to the Android NDK used to
            build the application. It is not recommended to hard-code this path,
            since different Qt for Android versions can depend on different
            Android NDK versions.
    \endlist

    \note Qt Creator sets these variables by default.

    There are a set of \c qmake variables that can be used to tailor
    your package. At some point during development, you will most likely want
    to look into these variables to customize your application.

    Here is a list of some variables that are particularly interesting when
    making Android applications:

    \list
        \li \l{ANDROID_PACKAGE_SOURCE_DIR}
        \li \l{ANDROID_VERSION_CODE}
        \li \l{ANDROID_VERSION_NAME}
        \li \l{ANDROID_EXTRA_LIBS}
        \li \l{ANDROID_EXTRA_PLUGINS}
        \li \l{ANDROID_ABIS}
        \li \l{ANDROID_API_VERSION}
        \li \l{ANDROID_DEPLOYMENT_DEPENDENCIES}
        \li \l{ANDROID_MIN_SDK_VERSION}
        \li \l{ANDROID_TARGET_SDK_VERSION}
        \li \l{JAVA_HOME}
    \endlist

    Also, the following \c qmake variables are primarily useful when writing a Qt module, and not
    normal applications:

    \list
        \li \l{ANDROID_BUNDLED_JAR_DEPENDENCIES}
        \li \l{ANDROID_LIB_DEPENDENCIES}
        \li \l{ANDROID_PERMISSIONS}
        \li \l{ANDROID_FEATURES}
    \endlist

    \note This list of variables can also be used with CMake.

    \section1 Deployment in Qt Creator

    Qt Creator runs the \l androiddeployqt tool by default, and provides easy
    and intuitive user interfaces to specify many of the options. For more
    information, see \l{Qt Creator: Deploying Applications to Android Devices}.
*/
