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:hardwareAccelerated="true"
android:label="-- %%INSERT_APP_NAME%% --"
android:icon="-- %%INSERT_APP_ICON%% --"
android:requestLegacyExternalStorage="true"
android:allowBackup="true"
android:fullBackupOnly="false">

View File

@ -70,7 +70,7 @@ Qt sets the following manifest configuration by default:
default values are \c anyDensity, \c largeScreens,
\c normalScreens, and \c smallScreens.
\row
\li {1, 6} \l {Android: App Manifest <application>}{<application>}
\li {1, 7} \l {Android: App Manifest <application>}{<application>}
\li android:name
\li The application class name. Default value is
\c {org.qtproject.qt.android.bindings.QtApplication}.
@ -78,6 +78,11 @@ Qt sets the following manifest configuration by default:
\li android:label
\li The application name label. Default value is the Qt project's target 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
\li android:hardwareAccelerated
\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"
${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
_qt_internal_add_android_deployment_property(file_contents "android-version-code"
${target} "QT_ANDROID_VERSION_CODE")

View File

@ -328,6 +328,51 @@ set_target_properties(${target} PROPERTIES
\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
\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_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_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_CODE}{QT_ANDROID_VERSION_CODE}
\li \l{cmake-target-property-QT_QML_IMPORT_PATH}{QT_QML_IMPORT_PATH}

View File

@ -192,6 +192,7 @@ struct Options
QString systemLibsPath;
QString packageName;
QString appName;
QString appIcon;
QStringList extraLibs;
QHash<QString, QStringList> archExtraLibs;
QStringList extraPlugins;
@ -1380,6 +1381,12 @@ bool readInputFile(Options *options)
options->appName = options->applicationBinary;
}
{
const QJsonValue androidAppIcon = jsonObject.value("android-app-icon"_L1);
if (!androidAppIcon.isUndefined())
options->appIcon = androidAppIcon.toString();
}
{
using ItFlag = QDirListing::IteratorFlag;
const QJsonValue deploymentDependencies = jsonObject.value("deployment-dependencies"_L1);
@ -1701,6 +1708,11 @@ bool updateFile(const QString &fileName, const QHash<QString, QString> &replacem
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);
}
@ -1859,6 +1871,10 @@ bool updateAndroidManifest(Options &options)
replacements[QStringLiteral("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode;
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;
QFile androidManifestXml(androidManifestPath);
// User may have manually defined permissions in the AndroidManifest.xml