skip to Main Content

I have an Azure pipeline which has been building my MAUI app fine but a few weeks ago a problem occured. After the app is built and deployed for user download (in a custom online location, not the Google Play store), I try to install it manually on my few phones and every time it just says "Application cannot be installed", without any specific error details.

Interestingly enough, when I ‘run dotnet build MyApp.sln -c Release’ on my local machine, in the source folder, it builds the app just fine and I can then install it on all the phones without problems.

I have tried adding a signing step in the Azure pipeline and it seems to be working but the output apk still won’t install on phones.

The YAML code I added for signing the app (which didn’t help):

- task: AndroidSigning@3
  displayName: 'Signing and aligning APK file(s) **/*.apk'
  inputs:
    apkFiles: '**/*.apk'
    apksign: true
    apksignerKeystoreFile: myappkey.keystore
    apksignerKeystorePassword: mypass
    apksignerKeystoreAlias: myappkey
    apksignerKeyPassword: mypass

Any idea what I might be missing?

2

Answers


  1. Chosen as BEST ANSWER

    Turns out I was looking for the solution in the wrong place as it wasn't a problem with the YAML config.

    I installed the app using android-adb to be able to see the logs and the exact error message. It turned out that I was trying to install a build generated by a different source (Azure instead of local machine) and needed to uninstall the old app first for that.

    If I keep installing new versions of the app built on the same machine, I don't get the error anymore.


  2. Based on my testing with the dotnet publish command for my MAUI application, the .apk file generated during pipeline build can be installed manually, regardless of whether it is signed with the app key. I’m not certain if signing the package was a requirement when you built your app on your local machine. For your reference to build a signed app package in a pipeline, I have included a sample YAML definition below:

    parameters:
    - name: DotNetVersion
      default: 8.x
    - name: ApplicationDisplayVersion
      default: 1.0.0
    
    stages:
    - stage: BuildAndroid
      dependsOn: []
      jobs:
      - job: BuildAndroid
        pool:
          vmImage: windows-latest
        steps:
        - task: DownloadSecureFile@1
          inputs:
            secureFile: 'DotNetMauiAppDemo.keystore'
          name: DownloadKeystore
        - task: UseDotNet@2
          displayName: .NET Version
          inputs:
            packageType: 'sdk'
            version: '${{ parameters.DotNetVersion }}'
        - task: Bash@3
          displayName: Install MAUI
          inputs:
            targetType: 'inline'
            script: |
              echo "Downloaded keystore file is $(DownloadKeystore.secureFilePath)"
              dotnet nuget locals all --clear 
              dotnet workload install maui --source https://api.nuget.org/v3/index.json # --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json
        - task: DotNetCoreCLI@2
          displayName: Build Android App
          inputs:
            command: 'publish'
            publishWebProjects: false
            projects: '**/*.sln'
            arguments: >
              -f net8.0-android -c Release
              -p:ApplicationDisplayVersion=${{ parameters.ApplicationDisplayVersion }} -p:ApplicationVersion=$(Build.BuildId)
              -p:AndroidKeyStore=true -p:AndroidSigningKeyStore=$(DownloadKeystore.secureFilePath) -p:AndroidSigningKeyAlias=DotNetMauiAppDemo
              -p:AndroidSigningKeyPass=$(KeyPWD) -p:AndroidSigningStorePass=$(KeystorePWD)
            zipAfterPublish: false
            modifyOutputPath: false
        - task: CopyFiles@2
          inputs:
            SourceFolder: '$(System.DefaultWorkingDirectory)/DotNetMauiAppDemo/bin/Release/net8.0-android/'
            Contents: 'publish/**'
            TargetFolder: '$(Build.ArtifactStagingDirectory)'
        - publish: '$(Build.ArtifactStagingDirectory)'
          artifact: 'dropAndroid$(Build.BuildId)'
        - powershell: |
            tree $(Agent.WorkFolder) /F /A
          displayName: Check Binaries
          condition: always()
    
    - stage: DeployAndroid
      dependsOn: BuildAndroid
      jobs:
      - deployment: DeployAndroid
        pool:
          vmImage: windows-latest
        environment: E-GooglePlay
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: dropAndroid$(Build.BuildId)
              - powershell: |
                  tree $(Agent.WorkFolder) /F /A
                displayName: Check Artifacts
                condition: always()
              - task: GooglePlayRelease@4
                inputs:
                  serviceConnection: 'GooglePlaySvcCnn'
                  applicationId: 'com.domain.dotnetmauiappdemo'
                  action: 'SingleBundle'
                  bundleFile: '$(Pipeline.Workspace)/dropAndroid$(Build.BuildId)/publish/*-Signed.aab'
                  track: 'internal'
                  changesNotSentForReview: true
    
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search