Jan Hudec
Jan Hudec

Reputation: 76276

How to set version to android manifest during build

Is there any way I could generate value for the versionCode in android manifest during build? The problem is that since AndroidManifest.xml is versioned, it must not be modified in place. I'd prefer if it was possible to set it when building with eclipse too.

I want to generate it based on information from version control system. It's not possible to use keyword expansion, because it needs to be derived from information about whole tree, not just the AndrdoidManifest.xml file.

I can kind-of easily deal with versionName. Since it can refer to a resource and since there can be any number of .xml files in res/values, I can write a non-versioned res/values/version.xml with the appropriate value. But it does not look like the same trick should work with versionCode (if I try it it installs directly, but I don't have environment for testing installation via market set up yet).

Update: The main_rules.xml, which defines the rules for building with ant uses a version.code property, so it's possible there. The question still stands for building with Eclipse.

Upvotes: 1

Views: 3147

Answers (2)

Jan Hudec
Jan Hudec

Reputation: 76276

I now build the application using CMake (the application is mostly native and multi-platform), generating all of the android project including AndroidManifest.xml and build.xml during the build, so I can insert anything I want there.

Upvotes: 0

jchristof
jchristof

Reputation: 2834

This doesn't address the version.code part of your questions, but here's how I'm accomplishing it in our project:

I've created a C# tool that collects info that I want to include in our about page. This tool is invoked at the first step in our project's builders list (Properties->Builders) where you can specify the tool and command line args. In our instance the builder info looks like this:

Location: C:\Projects\Mobile\Tools\AndroidBuildVersioner\AndroidBuildVersioner\bin\Release\AndroidBuildVersioner.exe

Arguments: -f C:\Projects\Mobile\Android\ProjectName\res\values\build_version.xml

The tool examines the head revision of the project and associated libs in my case using a perforce lib and then writes this info tp the writable file build_version.xml. This file remains writable in the workspace since it's an auto generated file. The output is just a set of string resources so that the info is easily available to the project's about activity. I was also initially writing to the manifest as well, but of course it's easy to run into conflicts when build tools modify files that you also have to modify by hand.

here are a couple of examples if it helps:

build_version.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="build_revision">9</string>
    <string name="build_date">7/25/2011 9:48:13 AM</string>
    <string name="build_machine">JMARTIN-PC</string>
    <string name="build_user">jmartin</string>
</resources>

AndroidBuildVersioner.exe - this simplified block just increments a local build number and writes it and some extra env info back to the strings xml file.

    private static void updateBuildFileInfo(String file)
    {
        String fileContents = ReadFile(file);
        String buildRevision =  "0";
        String newFileContents =  @"<?xml version=""1.0"" encoding=""utf-8""?>"
            + Environment.NewLine + "<resources>" + Environment.NewLine ;

        //find the build version in the contents of the file so it can be incremented
        Match m = Regex.Match(fileContents, @"<string name=""build_revision"">(.*)</string>");

        if (m.Success)
            buildRevision = m.Groups[1].Value;

        int intBuildRevision = 0;

        try
        {
            intBuildRevision = Convert.ToInt32(buildRevision);
        }
        catch (FormatException e)
        {
            Console.WriteLine("Input string is not a sequence of digits.");
        }
        catch (OverflowException e)
        {
            Console.WriteLine("The number cannot fit in an Int32.");
        }
        finally
        {
            ++intBuildRevision;
            newFileContents += '\t' + @"<string name=""build_revision"">" + intBuildRevision + "</string>" + Environment.NewLine;
            newFileContents += '\t' + @"<string name=""build_date"">" + DateTime.Now.ToString() + "</string>" + Environment.NewLine;
            newFileContents += '\t' + @"<string name=""build_machine"">" + Environment.MachineName + "</string>" + Environment.NewLine;
            newFileContents += '\t' + @"<string name=""build_user"">" + Environment.UserName + "</string>" + Environment.NewLine;
            newFileContents += "</resources>";
        }

        writeOutput(file, newFileContents);
    }

Upvotes: 1

Related Questions