3

We have an Android app built with Mono for Android, and now we have desire to make a deployable test version for use in acceptance testing. It is important that the production version remains on the device and keeps working. What is the recommended way of creating a test build without causing interference like package name collisions?

Tormod Fjeldskår
  • 5,952
  • 1
  • 29
  • 47

2 Answers2

4

This solution applies to Mono for Android and allows you to change the package name of an application based on build configuration in Visual Studio:

  1. Create a new Build Configuration, Test, for your solution.
  2. Define a new Conditional compilation symbol, TEST, in your project.
  3. Rename your existing AndroidManifest.xml to AndroidManifest-Template.xml
  4. Create two .xslt files in the Properties folder:
    manifest-transform.xslt:

    <?xml version="1.0" ?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:output indent="yes" />
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
      </xsl:template>
      <xsl:template match="/manifest/@package">
        <xsl:attribute name="package">
          <xsl:value-of select="'<your.test.package.name.here>'" />
        </xsl:attribute>
      </xsl:template>
    </xsl:stylesheet>
    

    manifest-copy.xslt:

    <?xml version="1.0" ?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:output indent="yes" />
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
      </xsl:template>
    </xsl:stylesheet>
    
  5. Add two XslTransformation tasks to the BeforeBuild target of your project file:

    <Target Name="BeforeBuild">
      <XslTransformation 
        Condition="'$(Configuration)|$(Platform)' != 'Test|AnyCPU'" 
        XslInputPath="Properties\manifest-copy.xslt" 
        XmlInputPaths="Properties\AndroidManifest-Template.xml" 
        OutputPaths="Properties\AndroidManifest.xml" />
      <XslTransformation 
        Condition="'$(Configuration)|$(Platform)' == 'Test|AnyCPU'" 
        XslInputPath="Properties\manifest-transform.xslt" 
        XmlInputPaths="Properties\AndroidManifest-Template.xml" 
        OutputPaths="Properties\AndroidManifest.xml" />
    </Target>
    
  6. Use the TEST symbol for conditional code:

    #if TEST
        [Application(
            Label = "App Test", 
            Theme = "@style/Theme.App.Test", 
            Icon = "@drawable/ic_launcher_test")]
    #else
        [Application(
            Label = "App", 
            Theme = "@style/Theme.App", 
            Icon = "@drawable/ic_launcher")]
    #endif
    

You can now switch between test and regular app by changing build config :)

khellang
  • 17,550
  • 6
  • 64
  • 84
0

Changing the package name should probably be enough to keep things from conflicting, unless you are writing data to a hardcoded location, which would also need to be changed.

jpobst
  • 9,982
  • 1
  • 29
  • 33
  • Changing the package name must be done in both manifest and all resource files, though. And this must be done back and forth every time we need a test build. Can this be automated based on e.g. a build configuration? – Tormod Fjeldskår Mar 12 '12 at 09:36
  • I was under the impression that when you changed the package name, you had to change the namespaces in your XML GUI files accordingly. Am I missing something here? – Tormod Fjeldskår Mar 13 '12 at 07:27
  • If you use a custom view with custom attributes, you need to define a namespace to use them. Like: `` and then use the app namespace: ``. This would be a problem when changing the package name of the application... – khellang Mar 14 '12 at 08:26