With the introduction of Xamarin.Android v7.2, two new MSBuild properties were also introduced in order to make maintaining Android VersionCode for Android apps even easier:
- AndroidVersionCodePattern
- AndroidVersionCodeProperties
Advanced Android VersionCode
Typically, to change the version number on an Android application you need to edit the AndroidManifest.xml
file and update the android:versionCode
. Alternatively, you could implement your own system for generating the code and updating the XML file. With these two properties in place, you will be able to define the versionCode
within your MSBuild project. All this is built right into the build system.
AndroidVersionCodePattern
This property allows you to define the pattern desired for your versionCode
and inputs in a similar way to string.Format
work. You provide a number of {token} values which are replaced at build time. Out of the box we support of a number of default {tokens}:
- ABI – Inserts the targeted ABI for the app
- armeabi
- armeabi-v7a
- x86
- arm64-v8a
- x86_64
- MinSDK – Inserts the minimum supported Sdk value from the AndroidManifest.xml or 11 if none is defined.
- VersionCode – Uses the version code directly from Properties\AndroidManifest.xml.
By default the value of $(AndroidVersionCodePattern)
will be set to {abi}{versionCode:D6}
. So as an example, if you are splitting your APK’s by ABI and your versionCode
in the AndroidManifest.xml
is currently 1, the following should result:
2000001
for armeabi-v7a4000001
for armeabi-v8a
This can be broken down like so:
2 | 000001 |
---|---|
{abi} | {versionCode:D8} |
Notice the {token} supports the same zero padding definition that string.Format
supports. In this example, the D6
means “left pad the result so that it is 6 digits long”. Another example might be {abi}{minSDK:D2}{versionCode:D4}
. If the minSdk was API-9 and your versionCode
in the AndroidManifest.xml
is currently 21, you will see the following result.
2090021
for armeabi-v7a4090021
for armeabi-v8a
This can be broken down like so:
2 | 09 | 0021 |
---|---|---|
{abi} | {minSDK:D2} | {versionCode:D4} |
AndroidVersionCodeProperties
Support for allowing you to define your own {token} has also been added. This is done via the $(AndroidVersionCodeProperties)
. This is a comma-separated token=value pair string which defines the new {token} and its value. The value can be hard-coded for any one of the many MSBuild properties which are available.
For example: screen=23;target=$(_SupportedApiLevel)
. This defines two new tokens {screen} and {target}. One of which is derived from a Xamarin.Android MSBuild property. With this in mind, you can now define a $(AndroidVersionCodePattern)
of:
{abi}{minSDK:D2}{screen:D2}{target:D2}{versionCode:D4}
Which will make use of your custom {token} values in the final APK versionCode
Getting VersionCode from your Assembly
Information for the AndroidManifest.xml
can be useful if your project is setup to auto increment your assembly version for each build.
Use the MSBuild Task GetAssemblyIdentity
to retrieve the compiled assembly’s version information. Then use some MSBuild:Foo to split that into a usable format. Finally, create a set of {token}={value} items in the $(AndroidVersionCodeProperties)
property.
<Target Name="CalculateVersionCodeProperties" AfterTargets="CoreCompile">
<GetAssemblyIdentity AssemblyFiles="$(OutputPath)$(AssemblyName).dll">
<Output TaskParameter="Assemblies" ItemName="AssemblyVersionInfo" />
</GetAssemblyIdentity>
<PropertyGroup>
<BuildNumber>$([System.Version]::Parse(%(AssemblyVersionInfo.Version)).ToString(4))</BuildNumber>
<Major>$(BuildNumber.Split('.')[0])</Major>
<Minor>$(BuildNumber.Split('.')[1])</Minor>
<Build>$(BuildNumber.Split('.')[2])</Build>
<Revision>$(BuildNumber.Split('.')[3])</Revision>
<Year>$([System.DateTime]::Now.ToString ('yyyy'))</Year>
<Month>$([System.DateTime]::Now.ToString ('MM'))</Month>
<Day>$([System.DateTime]::Now.ToString ('dd'))</Day>
</PropertyGroup>
<PropertyGroup>
<AndroidVersionCodeProperties>year=$(Year);month=$(Month);day=$(Day);major=$(Major);minor=$(Minor);build=$(Build);revision=$(Revision)</AndroidVersionCodeProperties>
</PropertyGroup>
</Target>
With $(AndroidVersionCodeProperties)
in place we can now define our $(AndroidVersionCodePattern)
.
{abi}{major:D2}{minor:D2}{build:D2}{revision:D4}
Wrapping Up
Once this is all in place, there is no need to update the Android VersionCode in the AndroidManifest.xml
as it can all be done programmatically. Just remember to update the versionName
when themajor build version updates.
To discuss this article, head on over to our Xamarin Forums!
0 comments