visual-studioxamarin.formsmsbuildkeytooljarsigner

Xamarin.Forms android application built from command line doesn't work


I have a Xamarin.Forms Android application, developed using Visual Studio 2017. If I run/debug the application from Visual studio, with a USB device, it works well (both debug and release configurations).

I then create the .apk using the archive command in visual studio. To test it I simply upload it from my dev. computer to google drive and then download it from the same device and install it. This works as well.

The problem comes out when I try to create the .apk from the command line. The file obtained in this way is recognized by the device, which installs it correctly, but when I start the app, it seems to start but after a second it closes abruptly. I don't even get the familiar popup "unofortunately the app stopped" that I got during the development phase when there were exceptions.

These are the commands I use:

msbuild /t:Clean /p:Configuration=Release

msbuild /t:PackageForAndroid /p:Configuration=Release

keytool -genkey -v -keystore SymCheck.keystore -alias SimCheck -keyalg RSA -keysize 2048 -validity 10000

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore SymCheck.keystore my_application.apk SimCheck

According to https://learn.microsoft.com/en-gb/xamarin/android/deploy-test/signing/manually-signing-the-apk

I also tried this sequence

msbuild /t:Clean /p:Configuration=Release

msbuild /t:PackageForAndroid /p:Configuration=Release

keytool -genkey -v -keystore SymCheck.keystore -alias SimCheck -keyalg RSA -keysize 2048 -validity 10000

zipalign.exe -f -v 4 my_application.apk my_application_aligned.apk

apksigner.bat sign --ks SymCheck.keystore --ks-key-alias SimCheck my_application_aligned.apk

with the same outcome.


Solution

  • I found the issue.

    For some reasons the project option indicated below was set also in the release configuration.

    When debugging, visual studio did transfer all the needed resources to the device, so everything worked fine in that case.

    However, msbuild /t:PackageForAndroid was embedding in the .apk only part of the resources needed to run the application.

    Removing that check did fix the problem; the .apk went from 3.6MB to 16MB.

    enter image description here

    So, here the full sequence of operations:

    # clean step
    msbuild /t:Clean /p:Configuration=Release
    
    # build step
    msbuild /t:PackageForAndroid /p:Configuration=Release
    
    # keytool step
    "[c:\Program Files (x86)\Java\jdk1.8.0_161\bin\\]keytool.exe" -genkey -v -keystore <a filename for keystore> -alias {a string} -keyalg RSA -keysize 2048 -validity 10000
    
    # jarsigner step
    "[c:\Program Files (x86)\Android\android-sdk\build-tools\\{version e.g. 27.0.1}\\]zipalign.exe" -f -v 4 bin\Release\\{file apk created by msbuild in step build step} bin\Release\\{output apk filename}
    
    # apksigner step
    "[c:\Program Files (x86)\Android\android-sdk\build-tools\\{version e.g. 27.0.1}\\]apksigner.bat" sign --ks {filename for keystore chosen in step c.} --ks-key-alias {alias string chosen in keytool step.} bin\Release\\{output apk filename from zipalign step.}
    

    The apk generated with last step (apksigner step) is the good one.

    Paths in [] are platform specific and can be avoided changing the machine's PATH environment variable.

    Parts in {} are names to be chosen by the user.