CMake:Android: add property QT_ANDROID_APP_ICON to set app icon

This allows users to set an app icon directly from CMake
without needing to manage a custom AndroidManifest.xml file.

Fixes: QTBUG-92013
Change-Id: Ic2f44978697d0f4833bde7f66630943d3032e982
Reviewed-by:  Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Assam Boudjelthia 2024-09-07 13:40:28 +03:00
parent c768ec64bb
commit fe9c7dcae0
6 changed files with 73 additions and 1 deletions

View File

@ -15,6 +15,7 @@
android:name="org.qtproject.qt.android.bindings.QtApplication" android:name="org.qtproject.qt.android.bindings.QtApplication"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:label="-- %%INSERT_APP_NAME%% --" android:label="-- %%INSERT_APP_NAME%% --"
android:icon="-- %%INSERT_APP_ICON%% --"
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:allowBackup="true" android:allowBackup="true"
android:fullBackupOnly="false"> android:fullBackupOnly="false">

View File

@ -70,7 +70,7 @@ Qt sets the following manifest configuration by default:
default values are \c anyDensity, \c largeScreens, default values are \c anyDensity, \c largeScreens,
\c normalScreens, and \c smallScreens. \c normalScreens, and \c smallScreens.
\row \row
\li {1, 6} \l {Android: App Manifest <application>}{<application>} \li {1, 7} \l {Android: App Manifest <application>}{<application>}
\li android:name \li android:name
\li The application class name. Default value is \li The application class name. Default value is
\c {org.qtproject.qt.android.bindings.QtApplication}. \c {org.qtproject.qt.android.bindings.QtApplication}.
@ -78,6 +78,11 @@ Qt sets the following manifest configuration by default:
\li android:label \li android:label
\li The application name label. Default value is the Qt project's target name. \li The application name label. Default value is the Qt project's target name.
This can be set using \l {QT_ANDROID_APP_NAME}. This can be set using \l {QT_ANDROID_APP_NAME}.
\row
\li android:icon
\li The application icon as a reference to a drawable or mipmap resource. This
tag is not used unless set using \l {QT_ANDROID_APP_ICON} or set manually
in the \c {AndroidManifest.xml}.
\row \row
\li android:hardwareAccelerated \li android:hardwareAccelerated
\li Sets hardware acceleration preference. The default value is \c true. \li Sets hardware acceleration preference. The default value is \c true.

View File

@ -225,6 +225,10 @@ function(qt6_android_generate_deployment_settings target)
_qt_internal_add_android_deployment_property(file_contents "android-app-name" _qt_internal_add_android_deployment_property(file_contents "android-app-name"
${target} "QT_ANDROID_APP_NAME") ${target} "QT_ANDROID_APP_NAME")
# app icon
_qt_internal_add_android_deployment_property(file_contents "android-app-icon"
${target} "QT_ANDROID_APP_ICON")
# version code # version code
_qt_internal_add_android_deployment_property(file_contents "android-version-code" _qt_internal_add_android_deployment_property(file_contents "android-version-code"
${target} "QT_ANDROID_VERSION_CODE") ${target} "QT_ANDROID_VERSION_CODE")

View File

@ -328,6 +328,51 @@ set_target_properties(${target} PROPERTIES
\sa {QT_ANDROID_PACKAGE_NAME} \sa {QT_ANDROID_PACKAGE_NAME}
*/ */
/*!
\page cmake-target-property-qt-android-app-icon.html
\ingroup cmake-properties-qtcore
\ingroup cmake-target-properties-qtcore
\title QT_ANDROID_APP_ICON
\target cmake-target-property-QT_ANDROID_APP_ICON
\ingroup cmake-android-manifest-properties
\summary {The Android app's icon resource name.}
\cmakepropertysince 6.9
\cmakepropertyandroidonly
Specifies the app's icon name as an Android drawable or mipmap reference.
This only works if the \c {AndroidManifest.xml} file contains the placeholder
or when the \c {AndroidManifest.xml} is managed by Qt.
\badcode
<application
...
android:icon="-- %%INSERT_APP_ICON%% --"
...
>
\endcode
You can use this property as follows:
\badcode
set_target_properties(${target} PROPERTIES
QT_ANDROID_APP_ICON "@mipmap/ic_launcher"
)
\endcode
Or using drawables:
\badcode
set_target_properties(${target} PROPERTIES
QT_ANDROID_APP_ICON "@drawable/ic_launcher"
)
\endcode
\sa{qt6_android_generate_deployment_settings}{qt_android_generate_deployment_settings()}
*/
/*! /*!
\page cmake-target-property-qt-android-version-code.html \page cmake-target-property-qt-android-version-code.html
\ingroup cmake-properties-qtcore \ingroup cmake-properties-qtcore

View File

@ -65,6 +65,7 @@ how to accomplish this.
\li \l{cmake-target-property-QT_ANDROID_TARGET_SDK_VERSION}{QT_ANDROID_TARGET_SDK_VERSION} \li \l{cmake-target-property-QT_ANDROID_TARGET_SDK_VERSION}{QT_ANDROID_TARGET_SDK_VERSION}
\li \l{cmake-target-property-QT_ANDROID_PACKAGE_NAME}{QT_ANDROID_PACKAGE_NAME} \li \l{cmake-target-property-QT_ANDROID_PACKAGE_NAME}{QT_ANDROID_PACKAGE_NAME}
\li \l{cmake-target-property-QT_ANDROID_APP_NAME}{QT_ANDROID_APP_NAME} \li \l{cmake-target-property-QT_ANDROID_APP_NAME}{QT_ANDROID_APP_NAME}
\li \l{cmake-target-property-QT_ANDROID_APP_ICON}{QT_ANDROID_APP_ICON}
\li \l{cmake-target-property-QT_ANDROID_VERSION_NAME}{QT_ANDROID_VERSION_NAME} \li \l{cmake-target-property-QT_ANDROID_VERSION_NAME}{QT_ANDROID_VERSION_NAME}
\li \l{cmake-target-property-QT_ANDROID_VERSION_CODE}{QT_ANDROID_VERSION_CODE} \li \l{cmake-target-property-QT_ANDROID_VERSION_CODE}{QT_ANDROID_VERSION_CODE}
\li \l{cmake-target-property-QT_QML_IMPORT_PATH}{QT_QML_IMPORT_PATH} \li \l{cmake-target-property-QT_QML_IMPORT_PATH}{QT_QML_IMPORT_PATH}

View File

@ -192,6 +192,7 @@ struct Options
QString systemLibsPath; QString systemLibsPath;
QString packageName; QString packageName;
QString appName; QString appName;
QString appIcon;
QStringList extraLibs; QStringList extraLibs;
QHash<QString, QStringList> archExtraLibs; QHash<QString, QStringList> archExtraLibs;
QStringList extraPlugins; QStringList extraPlugins;
@ -1380,6 +1381,12 @@ bool readInputFile(Options *options)
options->appName = options->applicationBinary; options->appName = options->applicationBinary;
} }
{
const QJsonValue androidAppIcon = jsonObject.value("android-app-icon"_L1);
if (!androidAppIcon.isUndefined())
options->appIcon = androidAppIcon.toString();
}
{ {
using ItFlag = QDirListing::IteratorFlag; using ItFlag = QDirListing::IteratorFlag;
const QJsonValue deploymentDependencies = jsonObject.value("deployment-dependencies"_L1); const QJsonValue deploymentDependencies = jsonObject.value("deployment-dependencies"_L1);
@ -1701,6 +1708,11 @@ bool updateFile(const QString &fileName, const QHash<QString, QString> &replacem
return false; return false;
} }
// Remove leftover empty lines after replacements, for example,
// in case of setting the app icon.
QRegularExpression emptyLinesRegex("\\n\\s+\\n"_L1);
contents = QString::fromUtf8(contents).replace(emptyLinesRegex, "\n"_L1).toUtf8();
inputFile.write(contents); inputFile.write(contents);
} }
@ -1859,6 +1871,10 @@ bool updateAndroidManifest(Options &options)
replacements[QStringLiteral("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode; replacements[QStringLiteral("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode;
replacements[QStringLiteral("package=\"org.qtproject.example\"")] = "package=\"%1\""_L1.arg(options.packageName); replacements[QStringLiteral("package=\"org.qtproject.example\"")] = "package=\"%1\""_L1.arg(options.packageName);
const QString iconAttribute = "android:icon=\"%1\""_L1;
replacements[iconAttribute.arg("-- %%INSERT_APP_ICON%% --"_L1)] = options.appIcon.isEmpty() ?
""_L1 : iconAttribute.arg(options.appIcon);
const QString androidManifestPath = options.outputDirectory + "/AndroidManifest.xml"_L1; const QString androidManifestPath = options.outputDirectory + "/AndroidManifest.xml"_L1;
QFile androidManifestXml(androidManifestPath); QFile androidManifestXml(androidManifestPath);
// User may have manually defined permissions in the AndroidManifest.xml // User may have manually defined permissions in the AndroidManifest.xml