skip to Main Content

This is specifically for Android. I have a flutter application that goes through DevOps pipelines to build an apk and then publish it to App Center for internal use. I’ve been having issues getting an effortless update process on my apk when downloading a new one through app center and selecting update. Every time I get the message "App not installed as package conflicts with an existing package".

I know about the solution to just uninstall your old app and then install the new one, but is there not any other way for me to just get my update in a working condition? Is there any potential places where my packages would conflict that I can just match to get an effortless update process?

I tried looking everywhere in my project and pipelines for any identifiers or processes that might make it seem like it is a different package with the same name with the help of forums such as:

  • The Android namespace
  • The keystore that I sign my app with in the pipelines

But the namespace stayed the same between the two versions and my keystore definitely did not change since it is stored in a secure file on DevOps and that has not been touched at all.

There are some things however that did change that could be considered major that I do not know if it would consider it a different package altogether such as:

  • Updating my flutter, gradle, and all other packages to the latest version
  • Adding flavors
  • The majority of the image assets were replaced
  • My apk name changed from app-release.apk to app-prod-release.apk due to flavors
  • And updating the pipelines with new tasks and a new way of building my apk with flavors and config files as seen below:

Old pipeline:

trigger:
  branches:
    include:
      - dev
      - main
      - release/*

stages:
- stage: AndroidStage
  pool:
    vmImage: 'ubuntu-latest'
  dependsOn: []
  displayName: Android
  jobs:

  - job: AndroidJob
    displayName: Android
    steps: 

    - task: FlutterInstall@0
      displayName: "Install Flutter SDK"
      inputs:
        mode: 'auto'
        channel: 'stable'
        version: 'latest'

    - task: FlutterCommand@0
      displayName: "Run Flutter diagnostics"
      inputs:
        projectDirectory: '.'
        arguments: 'doctor -v'

    - task: FlutterBuild@0
      displayName: "Build application"
      inputs:
        target: 'apk'
        projectDirectory: '$(Build.SourcesDirectory)'

    - task: AndroidSigning@3
      displayName: 'Signing and aligning APK file(s) **/*.apk'
      inputs:
        apkFiles: '**/*.apk'
        apksign: true
        apksignerKeystoreFile: pinnies-v2-release.keystore
        apksignerKeystorePassword: $(keystorePass)
        apksignerKeystoreAlias: $(keystoreAlias)
        apksignerKeyPassword: $(keystorePass)

    - task: CopyFiles@2
      inputs:
        contents: '**/*.apk'
        targetFolder: '$(build.artifactStagingDirectory)'
        OverWrite: true

    - task: PublishBuildArtifacts@1
      condition: ne(variables['Build.Reason'], 'PullRequest')
      inputs:
        artifactName: 'drop'
    
    - script: |
        version=$(grep "version:" pubspec.yaml | awk '{print $2}' | cut -d'+' -f1)
        echo "##vso[task.setvariable variable=AppVersion]$version"
      displayName: 'Extract App Version'

    - script: |   
        if [ "$(Build.SourceBranch)" == "refs/heads/main" ]; then
          echo '$url = "$(teamsUrl)"' > $(Build.ArtifactStagingDirectory)/send_teams.ps1
        else
          echo '$url = "$(teamsGradUrl)"' > $(Build.ArtifactStagingDirectory)/send_teams.ps1
        fi
        echo '$jsonPayload = @{' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        echo '    "version" = "$(AppVersion)"' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        if [ "$(Build.SourceBranch)" == "refs/heads/main" ]; then
          echo '    "url" = "https://install.appcenter.ms/orgs/agilebridge/apps/pinnies-android/distribution_groups/public"' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        else
          echo '    "url" = "https://install.appcenter.ms/orgs/AgileBridge/apps/Pinnies-Test-Android/releases/latest"' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        fi
        echo '}' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        echo '$jsonBody = $jsonPayload | ConvertTo-Json' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        echo '$headers = @{ "Content-Type" = "application/json" }' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        echo '$response = Invoke-RestMethod -Uri $url -Method Post -Body $jsonBody -Headers $headers' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        echo '$response' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
      displayName: 'Generate PowerShell Script'
    
    - publish: $(Build.ArtifactStagingDirectory)/send_teams.ps1
      artifact: SendTeams

New pipeline:

trigger:
  branches:
    include:
      - dev
      - main
      - release/*

stages:
- stage: AndroidStage
  pool:
    vmImage: 'ubuntu-latest'
  dependsOn: []
  displayName: Android
  jobs:

  - job: AndroidJob
    displayName: Android
    steps:
    - bash: 'wget --no-check-certificate -c --header "Cookie: oraclelicense=accept-securebackup-cookie" https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.tar.gz '
      displayName: 'Bash Script'

    - task: JavaToolInstaller@0
      displayName: 'Use Java 21'
      inputs:
        versionSpec: 21
        jdkArchitectureOption: x64
        jdkSourceOption: LocalDirectory
        jdkFile: '$(build.sourcesdirectory)/jdk-21_linux-x64_bin.tar.gz'
        jdkDestinationDirectory: '$(agent.toolsDirectory)/jdk21'

    - task: FlutterInstall@0
      displayName: "Install Flutter SDK"
      inputs:
        mode: 'auto'
        channel: 'stable'
        version: 'latest'

    - task: FlutterCommand@0
      displayName: "Run Flutter diagnostics"
      inputs:
        projectDirectory: '.'
        arguments: 'doctor -v'

    - task: FlutterCommand@0
      displayName: "Clean application"
      inputs:
        projectDirectory: '.'
        flutterDirectory: '$(Build.SourcesDirectory)'
        arguments: 'clean'

    - script: |
        if [[ "$(Build.SourceBranch)" == "refs/heads/dev" ]]; then
          flavor="dev"
        elif [[ "$(Build.SourceBranch)" == "refs/heads/main" ]]; then
          flavor="prod"
        else
          flavor="uat"
        fi
        echo "Building with flavor: $flavor"
        flutter build apk --flavor $flavor --dart-define-from-file=config/app_config_$flavor.json
      displayName: "Build application with flavor"

    - task: AndroidSigning@3
      displayName: 'Signing and aligning APK file(s) **/*.apk'
      inputs:
        apkFiles: '**/*.apk'
        apksign: true
        apksignerKeystoreFile: pinnies-v2-release.keystore
        apksignerKeystorePassword: $(keystorePass)
        apksignerKeystoreAlias: $(keystoreAlias)
        apksignerKeyPassword: $(keystorePass)

    - task: CopyFiles@2
      inputs:
        contents: '**/*.apk'
        targetFolder: '$(build.artifactStagingDirectory)'
        OverWrite: true

    - task: PublishBuildArtifacts@1
      condition: ne(variables['Build.Reason'], 'PullRequest')
      inputs:
        artifactName: 'drop'
    
    - script: |
        version=$(grep "version:" pubspec.yaml | awk '{print $2}' | cut -d'+' -f1)
        echo "##vso[task.setvariable variable=AppVersion]$version"
      displayName: 'Extract App Version'

    - script: |   
        if [ "$(Build.SourceBranch)" == "refs/heads/main" ]; then
          echo '$url = "$(teamsUrl)"' > $(Build.ArtifactStagingDirectory)/send_teams.ps1
        else
          echo '$url = "$(teamsGradUrl)"' > $(Build.ArtifactStagingDirectory)/send_teams.ps1
        fi
        echo '$jsonPayload = @{' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        echo '    "version" = "$(AppVersion)"' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        if [ "$(Build.SourceBranch)" == "refs/heads/main" ]; then
          echo '    "url" = "https://install.appcenter.ms/orgs/agilebridge/apps/pinnies-android/distribution_groups/public"' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        else
          echo '    "url" = "https://install.appcenter.ms/orgs/AgileBridge/apps/Pinnies-Test-Android/releases/latest"' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        fi
        echo '}' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        echo '$jsonBody = $jsonPayload | ConvertTo-Json' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        echo '$headers = @{ "Content-Type" = "application/json" }' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        echo '$response = Invoke-RestMethod -Uri $url -Method Post -Body $jsonBody -Headers $headers' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
        echo '$response' >> $(Build.ArtifactStagingDirectory)/send_teams.ps1
      displayName: 'Generate PowerShell Script'
    
    - publish: $(Build.ArtifactStagingDirectory)/send_teams.ps1
      artifact: SendTeams

I’m really at a loss here. I don’t think app center would cause this issue because that also has not changed. I’m relatively new to mobile dev so any advice that could point me in the right direction would be appreciated

2

Answers


  1. Are you upping the version code of the app each time? Specifically, I’m referring to the versionCode in the Apps build.gradle.

    Login or Signup to reply.
  2. As far as I know, this issue might be caused by any of the following things:

    1. As @John Wiese mentioned, a same versionCode of the APK. You may need to check the versionCode and ensure it is a new one.

    2. The outdated version of Android. You can try to check for software updates and upgrade your device to the latest version of Android.

    3. The problem with the APK file itself. Make sure that the APK file is not corrupted or incomplete, and try downloading it again from a reputable source.

    4. The problem with the firmware on the device. If you suspect that this is the case, you can try to check the possible security settings on the device, and if required, you also can try to contact the manufacturer for further assistance.

    5. The lack of storage space on the device. You can try to free up some space by deleting unnecessary files or moving them to an external storage device.

    6. The problem with the Google Play Store. you can try to clear the cache and data for the Google Play Store app, and make sure that you have a stable internet connection.

    7. The potential malware or virus on the device. You can try to run a full scan on the device using a reliable antivirus software.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search