Xamarin Android package name in build config

January 27th 2023 Xamarin Android

The identity of an Android application consists of its package name, its label, and its icon. In a Xamarin.Forms Android application, these are specified in the AndroidManifest.xml file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          android:versionCode="1"
          android:versionName="1.0"
          package="com.damirscorner.package1">
    <application android:label="Application 1" android:theme="@style/MainTheme">
    </application>
    <!-- ... -->
</manifest>

and as an attribute on the MainActivity class:

[Activity(
    Label = "Application 1", Icon = "@mipmap/icon",
    Theme = "@style/MainTheme", MainLauncher = true,
    ConfigurationChanges =
        ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
        ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
public class MainActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    // ...
}

So how would you create a build configuration with a different value for these three properties? For example, if you are creating a white-label application.

With conditional compilation symbols, it is quite easy to change the part in the attribute. You can define an additional conditional compilation symbol for your build configuration on the Build tab of the Android project Properties window (you may already have one because the code differs between build configurations) and then specify a different annotation for it:

#if App2
[Activity(
    Label = "Application 2", Icon = "@mipmap/icon2",
    Theme = "@style/MainTheme", MainLauncher = true,
    ConfigurationChanges =
        ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
        ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
#else
[Activity(
    Label = "Application 1", Icon = "@mipmap/icon",
    Theme = "@style/MainTheme", MainLauncher = true,
    ConfigurationChanges =
        ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
        ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
#endif
public class MainActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    // ...
}

The above code assumes that you have a second application icon icon2 in your Android project Resources folder.

Unfortunately, you cannot take the same approach in the AndroidManifest.xml file. You need to make a copy of the file and change the relevant parts in it:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          android:versionCode="1"
          android:versionName="1.0"
          package="com.damirscorner.package2">
    <application android:label="Application 2" android:theme="@style/MainTheme">
    </application>
    <!-- ... -->
</manifest>

Now you need to manually modify the Android project's .csproj file to specify the correct AndroidManifest.xml file for each build configuration. By default, there is an AndroidManifest element in the main PropertyGroup element of the file:

<PropertyGroup>
    <!-- ... -->
    <AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
</PropertyGroup>

You need to delete it and then add an AndroidManifest element with the correct value in the PropertyGroup element for each build configuration:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <!-- ... -->
    <AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug2|AnyCPU'">
    <!-- ... -->
    <AndroidManifest>Properties\AndroidManifest2.xml</AndroidManifest>
</PropertyGroup>

This should be enough to build an application with a different identity by simply choosing a different build configuration. To be on the safe side, I recommend using the Clean Solution command before you build the project after switching to a different configuration. Without this command I usually had problems with the build.

You can find a working example with full source code in my GitHub repository. I created a separate Debug and Release configuration for each application identity.

In this blog post, I described how I built two applications with different identities from the same source code by simply using a different build configuration. This works well enough, but unfortunately requires duplicate AndroidManifest.xml files and Activity attributes. So if you change any of these in the future, all copies must be changed at the same time to avoid unwanted discrepancies between applications.

Get notified when a new blog post is published (usually every Friday):

Copyright
Creative Commons License