Android: support namespace in build.gradle

The use of "package" in AndroidManifest.xml has been deprecated
since AGP 7.4, and has been moved to build.gradle file instead,
set as "namespace". Qt Creator has been relying on the package
name being present in the manifest and projects not having that
will fail to deploy. This change adds support of that to Creator.

Task-number: QTBUG-106907
Change-Id: I04850a11c5840d5167f7a3d09ae76cd51dbe72ca
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Assam Boudjelthia
2024-05-24 10:09:49 +03:00
parent fbb2f70747
commit b82da570cd
3 changed files with 51 additions and 16 deletions

View File

@@ -368,10 +368,12 @@ DeployErrorFlags AndroidDeployQtStep::runDeploy(QPromise<void> &promise)
QString packageName; QString packageName;
if (m_uninstallPreviousPackageRun) { if (m_uninstallPreviousPackageRun) {
packageName = AndroidManager::packageName(m_manifestName); packageName = AndroidManager::packageName(target());
if (packageName.isEmpty()) { if (packageName.isEmpty()) {
reportWarningOrError(Tr::tr("Cannot find the package name from the Android Manifest " reportWarningOrError(
"file \"%1\".").arg(m_manifestName.toUserOutput()), Tr::tr("Cannot find the package name from AndroidManifest.xml nor "
"build.gradle files at \"%1\".")
.arg(AndroidManager::androidBuildDirectory(target()).toUserOutput()),
Task::Error); Task::Error);
return Failure; return Failure;
} }

View File

@@ -85,18 +85,52 @@ static const ProjectNode *currentProjectNode(const Target *target)
QString packageName(const Target *target) QString packageName(const Target *target)
{ {
const auto element = documentElement(AndroidManager::manifestPath(target)); QString packageName;
if (!element)
return {}; // Check build.gradle
return element->attribute("package"); auto isComment = [](const QByteArray &trimmed) {
return trimmed.startsWith("//") || trimmed.startsWith('*') || trimmed.startsWith("/*");
};
const FilePath androidBuildDir = androidBuildDirectory(target);
const expected_str<QByteArray> gradleContents = androidBuildDir.pathAppended("build.gradle")
.fileContents();
if (gradleContents) {
const auto lines = gradleContents->split('\n');
for (const auto &line : lines) {
const QByteArray trimmed = line.trimmed();
if (isComment(trimmed) || !trimmed.contains("namespace"))
continue;
int idx = trimmed.indexOf('=');
if (idx == -1)
idx = trimmed.indexOf(' ');
if (idx > -1) {
packageName = QString::fromUtf8(trimmed.mid(idx + 1).trimmed());
if (packageName == "androidPackageName") {
// Check gradle.properties
const QSettings gradleProperties = QSettings(
androidBuildDir.pathAppended("gradle.properties").toFSPathString(),
QSettings::IniFormat);
packageName = gradleProperties.value("androidPackageName").toString();
} else {
// Remote quotes
packageName = packageName.removeFirst().removeLast();
} }
QString packageName(const FilePath &manifestFile) break;
{ }
const auto element = documentElement(manifestFile); }
if (!element) }
return {};
return element->attribute("package"); if (packageName.isEmpty()) {
// Check AndroidManifest.xml
const auto element = documentElement(AndroidManager::manifestPath(target));
if (element)
packageName = element->attribute("package");
}
return packageName;
} }
QString activityName(const Target *target) QString activityName(const Target *target)

View File

@@ -39,7 +39,6 @@ namespace AndroidManager
constexpr auto firstQtWithAndroidDeployQt = {5, 4, 0}; constexpr auto firstQtWithAndroidDeployQt = {5, 4, 0};
QString packageName(const ProjectExplorer::Target *target); QString packageName(const ProjectExplorer::Target *target);
QString packageName(const Utils::FilePath &manifestFile);
QString activityName(const ProjectExplorer::Target *target); QString activityName(const ProjectExplorer::Target *target);
QString deviceSerialNumber(const ProjectExplorer::Target *target); QString deviceSerialNumber(const ProjectExplorer::Target *target);