diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index f748be78bcb..9c5681d0868 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -368,11 +368,13 @@ DeployErrorFlags AndroidDeployQtStep::runDeploy(QPromise &promise) QString packageName; if (m_uninstallPreviousPackageRun) { - packageName = AndroidManager::packageName(m_manifestName); + packageName = AndroidManager::packageName(target()); if (packageName.isEmpty()) { - reportWarningOrError(Tr::tr("Cannot find the package name from the Android Manifest " - "file \"%1\".").arg(m_manifestName.toUserOutput()), - Task::Error); + reportWarningOrError( + Tr::tr("Cannot find the package name from AndroidManifest.xml nor " + "build.gradle files at \"%1\".") + .arg(AndroidManager::androidBuildDirectory(target()).toUserOutput()), + Task::Error); return Failure; } const QString msg = Tr::tr("Uninstalling the previous package \"%1\".").arg(packageName); diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 9e8274d2f45..bacb31c5c26 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -85,18 +85,52 @@ static const ProjectNode *currentProjectNode(const Target *target) QString packageName(const Target *target) { - const auto element = documentElement(AndroidManager::manifestPath(target)); - if (!element) - return {}; - return element->attribute("package"); -} + QString packageName; -QString packageName(const FilePath &manifestFile) -{ - const auto element = documentElement(manifestFile); - if (!element) - return {}; - return element->attribute("package"); + // Check build.gradle + auto isComment = [](const QByteArray &trimmed) { + return trimmed.startsWith("//") || trimmed.startsWith('*') || trimmed.startsWith("/*"); + }; + + const FilePath androidBuildDir = androidBuildDirectory(target); + const expected_str 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(); + } + + break; + } + } + } + + 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) diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index f3b9302d13c..382768e898c 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -39,7 +39,6 @@ namespace AndroidManager constexpr auto firstQtWithAndroidDeployQt = {5, 4, 0}; QString packageName(const ProjectExplorer::Target *target); -QString packageName(const Utils::FilePath &manifestFile); QString activityName(const ProjectExplorer::Target *target); QString deviceSerialNumber(const ProjectExplorer::Target *target);