diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index 767ea101b2a..7df51d2f9cc 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -251,10 +251,27 @@ AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::runDeploy(QFutureInter QTC_ASSERT(rc, return DeployErrorCode::Failure); const bool deployQtLive = rc->id().name().startsWith(qmlProjectRunConfigIdName); QString packageName; + int packageVersion = -1; if (deployQtLive) { - AndroidManager::apkInfo(m_apkPath, &packageName); - if (AndroidManager::packageInstalled(m_serialNumber, packageName)) - return DeployErrorCode::NoError; + // Do not install Qt live if apk is already installed or the same version is + // being installed. + AndroidManager::apkInfo(m_apkPath, &packageName, &packageVersion); + if (AndroidManager::packageInstalled(m_serialNumber, packageName)) { + int installedVersion = AndroidManager::packageVersionCode(m_serialNumber, + packageName); + if (installedVersion == packageVersion) { + qCDebug(deployStepLog) << "Qt live APK already installed. APK version:" + << packageVersion << "Installed version:" + << installedVersion; + return DeployErrorCode::NoError; + } else { + qCDebug(deployStepLog) << "Re-installing Qt live APK. Version mismatch." + << "APK version:" << packageVersion + << "Installed version:" << installedVersion; + } + } else { + qCDebug(deployStepLog) << "Installing Qt live APK. APK version:" << packageVersion; + } } if (m_uninstallPreviousPackageRun) { diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 77ad59b8a76..13c6f41ec40 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -70,12 +70,10 @@ namespace { const QLatin1String AndroidDefaultPropertiesName("project.properties"); const QLatin1String AndroidDeviceSn("AndroidDeviceSerialNumber"); const QLatin1String ApiLevelKey("AndroidVersion.ApiLevel"); - const QString packageNameRegEx("(package: name=)\\'(([a-z]{1}[a-z\\d_]*\\." - ")*[a-z][a-z\\d_]*)\\'"); - const QString activityRegEx("(launchable-activity: name=)\\'" - "(([a-z]{1}[a-z\\d_]*\\.)*[a-z][a-z\\d_]*)\\'"); - const QString apkVersionRegEx("package: name=([\\=a-z\\d_\\.\\'\\s]*)" - "\\sversionName='([\\d\\.]*)'"); + const QString packageNameRegEx("(?package: )(.*?)(name=)'(?.*?)'"); + const QString activityRegEx("(?launchable-activity: )(.*?)(name=)'(?.*?)'"); + const QString apkVersionRegEx("(?package: )(.*?)(versionCode=)'(?.*?)'"); + const QString versionCodeRegEx("(?versionCode=)(?\\d*)"); Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager") @@ -85,7 +83,7 @@ namespace { QRegularExpression::MultilineOption); QRegularExpressionMatch match = regRx.match(output); if (match.hasMatch()) - return match.captured(2); + return match.captured("target"); return QString(); }; } // anonymous namespace @@ -161,9 +159,27 @@ bool AndroidManager::packageInstalled(const QString &deviceSerial, return false; } +int AndroidManager::packageVersionCode(const QString &deviceSerial, + const QString &packageName) +{ + if (deviceSerial.isEmpty() || packageName.isEmpty()) + return -1; + + QStringList args = AndroidDeviceInfo::adbSelector(deviceSerial); + args << "shell" << "dumpsys" << "package" << packageName; + const QRegularExpression regRx(versionCodeRegEx, + QRegularExpression::CaseInsensitiveOption | + QRegularExpression::MultilineOption); + QRegularExpressionMatch match = regRx.match(runAdbCommand(args).stdOut()); + if (match.hasMatch()) + return match.captured("version").toInt(); + + return -1; +} + void AndroidManager::apkInfo(const Utils::FileName &apkPath, QString *packageName, - QVersionNumber *version, + int *version, QString *activityPath) { SdkToolResult result; @@ -184,7 +200,7 @@ void AndroidManager::apkInfo(const Utils::FileName &apkPath, if (version) { QString versionStr = parseAaptOutput(result.stdOut(), apkVersionRegEx); - *version = QVersionNumber::fromString(versionStr); + *version = versionStr.toInt(); } } diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index 2bf3bb8458c..6ddd63f7fdd 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -69,11 +69,11 @@ class ANDROID_EXPORT AndroidManager : public QObject public: static QString packageName(ProjectExplorer::Target *target); static QString packageName(const Utils::FileName &manifestFile); - static bool packageInstalled(const QString &deviceSerial, - const QString &packageName); + static bool packageInstalled(const QString &deviceSerial, const QString &packageName); + static int packageVersionCode(const QString &deviceSerial, const QString &packageName); static void apkInfo(const Utils::FileName &apkPath, QString *packageName = nullptr, - QVersionNumber *version = nullptr, + int *version = nullptr, QString *activityPath = nullptr); static QString intentName(ProjectExplorer::Target *target); static QString activityName(ProjectExplorer::Target *target);