Automatically increment version code in Android app

Is there a way to automatically increment the version code every time you create an Android application in Eclipse?

According to http://developer.android.com/guide/publishing/versioning.html you need to manually increase your version code in AndroidManifest.xml .

I understand that you need to run a script before each assembly, which will be, for example. analyze the AndroidManifest.xml file, find the version number, increase it and save the file before the build starts. However, I could not find out how and if Eclipse supports run scripts before / after the build.

I found this article about setting up ant builder, but it's not really about Android, and I'm afraid that it will spoil too much the predefined building steps for Android?

Should be a common problem, how did you solve it?

Well, you can do it manually, but as soon as you forget to do this work, you will get different versions with the same number, and all versions make no sense.

+62
android eclipse build version
Jul 20 2018-11-11T00:
source share
14 answers

So, I see it like this:

Depending on the article you are submitting, use ant for these tasks (goals?).

  • parse manifest (parse XML)
  • get the declaration form of the old version and increase it / get the version from the repo
  • save new version in manifest
  • Create an Android app.

But in my case, I usually fill out this field by value based on the tag change when deploying or distributing the application.

+4
Jul 20 '11 at 8:10
source share

I have done it. And here is how I did it for the next guy (using Eclipse):

1) Create an executable file of the external console that is going to write the code for the new version in AndroidManifest.xml: (mine is in C #)

 using System.IO; using System.Text.RegularExpressions; namespace AndroidAutoIncrementVersionCode { class Program { static void Main(string[] args) { try { string FILE = @"AndroidManifest.xml"; string text = File.ReadAllText(FILE); Regex regex = new Regex(@"(?<A>android:versionCode="")(?<VER>\d+)(?<B>"")", RegexOptions.IgnoreCase); Match match = regex.Match(text); int verCode = int.Parse(match.Groups["VER"].Value) + 1; string newText = regex.Replace(text, "${A}" + verCode + "${B}", 1); File.WriteAllText(FILE, newText); } catch { } } } } 

aside: any c-sharp compiler can create this application, you do not need Visual Studio or even Windows

  • If you don’t have it yet, install .NET runtime ( Mono will work, link ) ( link to MS.NET framework 2.0, 2.0 - the smallest download, any version> = 2.0 is fine )
  • copy this code to the *.cs file (I called mine: AndroidAutoIncrementVersionCode.cs )
  • open a command prompt and go to where you created the *.cs file
  • create a file using this command (on Windows, similar to Mono, but change the compiler path): c:\Windows\Microsoft.NET\Framework\v2.0.50727\csc AndroidAutoIncrementVersionCode.cs (see c:\Windows\Microsoft.NET\Framework\v2.0.50727\csc AndroidAutoIncrementVersionCode.cs NET or Mono for more details )
  • congrats, you just created a C # application without any tools, it should have generated AndroidAutoIncrementVersionCode.exe in the same directory automatically

    ** mileage may vary, paths may be different, no purchase required, void where prohibited, I added this because C # is awesome and people mistakenly believe that it has an MS lock, you could just transfer it to another language (but I'm not going to do it for you;). By the way, any version of any .NET compiler will work, I adapted the code for the least common denominator ... *

end>

2) Run the executable file during the build process: a) Go to the project properties

go to project properties

b) In the properties, go to "Builders" → "Create ..."

Eclipse properties screen

c) Select "Program"

choose program

d) On the "Home" tab, select the location of the program (I also set the working directory to a safe state) and give it a name if you want.

edit configuration - main

e) On the Refresh tab, select the option “Refresh resources after completion” and “Selected resource” - this will update the manifest after it is written.

edit configuration - refresh

f) On the "Assembly Options" tab, you can disable "Allocate Console" because you do not have input and output, and then select only "During manual assemblies" and "During automatic assembly" clear the "After cleaning" checkbox if This is verified. Then select "Specify a working set of relevant resources" and click the "Specify resources ..." button. In the "Change Working Set" dialog box, find the file "AndroidManifest.xml" in the dialog box and check it, then click "Finish"

edit configuration - build optionsedit working set

f) Now click "OK" inside the "Edit configuration dialog" and in the properties of your application, select the newly created builder and click "Up" until it appears at the top of the list, so auto increment starts first and does not trigger random states synchronization or adjustment. Once the new creator that you created is at the top of the list, click OK and you're done.

edit configuration - hit okenter image description here

+112
Nov 16 '11 at 18:34
source share

This shell script, suitable for * nix systems, sets the version code and the latest versionName component to the current subversion revision. I use Netbeans with NBAndroid, and I call it the script from target -pre-compile in custom_rules.xml.

Save this script in the incVersion file in the same directory as AndroidManifest.xml, make it executable: chmod +x incVersion

 manf=AndroidManifest.xml newverfull=`svnversion` newvers=`echo $newverfull | sed 's/[^0-9].*$//'` vers=`sed -n '/versionCode=/s/.*"\([0-9][0-9]*\)".*/\1/p' $manf` vername=`sed -n '/versionName=/s/.*"\([^"]*\)".*/\1/p' $manf` verbase=`echo $vername | sed 's/\(.*\.\)\([0-9][0-9]*\).*$/\1/'` newvername=$verbase$newverfull sed /versionCode=/s/'"'$vers'"'/'"'$newvers'"'/ $manf | sed /versionName=/s/'"'$vername'"'/'"'$newvername'"'/ >new$manf && cp new$manf $manf && rm -f new$manf echo versionCode=$newvers versionName=$newvername 

Create or edit custom_rules.xml and add the following:

 <?xml version="1.0" encoding="UTF-8"?> <project name="custom_rules"> <xmlproperty file="AndroidManifest.xml" prefix="mymanifest" collapseAttributes="true"/> <target name="-pre-compile"> <exec executable="./incVersion" failonerror="true"/> </target> </project> 

So, if my current version of svn is 82, I get this in AndroidManifest.xml:

 android:versionCode="82" android:versionName="2.1.82"> 

When I want to release a new version, I usually update the first parts of versionName, but even if I forget, the last part of versionName (which appears in my active activity) will always tell me that svn remade it was built from. In addition, if I did not check for changes, the version number will be 82M, and versionName will be approximately 2.1.82M.

The advantage over simply increasing the version number each time the build is done is that the number remains under control and can be directly related to a specific version of svn. Very useful when investigating bugs in other versions.

+8
Oct 18
source share

FWIW, I was able to update the assembly version value in six lines of python:

 #!/bin/env python import os from xml.dom.minidom import parse dom1 = parse("AndroidManifest.xml") dom1.documentElement.setAttribute("android:versionName","%build.number%") f = os.open("AndroidManifest.xml", os.O_RDWR) os.write( f, dom1.toxml() ) 
+7
Aug 01 '12 at 6:21
source share

Based on Charles's answer , the next step extends the existing version of the assembly:

 #!/usr/bin/python from xml.dom.minidom import parse dom1 = parse("AndroidManifest.xml") oldVersion = dom1.documentElement.getAttribute("android:versionName") versionNumbers = oldVersion.split('.') versionNumbers[-1] = unicode(int(versionNumbers[-1]) + 1) dom1.documentElement.setAttribute("android:versionName", u'.'.join(versionNumbers)) with open("AndroidManifest.xml", 'wb') as f: for line in dom1.toxml("utf-8"): f.write(line) 
+6
Sep 12 '12 at 18:22
source share

Receipe:

To automatically use the android: versionCode attribute of the manifest element in AndroidManifest.xml set to the current time (from the era in seconds, obtained from the unix shell) every time you run the assembly, add it to your target -pre-build Custom_rules.xml file for Android.

 <target name="-pre-build"> <exec executable="date" outputproperty="CURRENT_TIMESTAMP"> <arg value="+%s"/> </exec> <replaceregex file="AndroidMainfest.xml" match="android:versionCode=.*" replace='android:versionCode="${CURRENT_TIMESTAMP}"' /> </target> 

Confirmation Test :

Get the versionCode attribute of the generated apk file using the following shell command from the Android projects directory:

 $ANDROID_SDK/build-tools/20.0.0/aapt dump badging bin/<YourProjectName>.apk | grep versionCode 

and compare it with the current date returned by the shell command: date +%s The difference should equal the time period in seconds between the two above confirmation steps.

The advantages of this approach:

  • Regardless of whether the assembly is started from the command line or Eclipse, it will update the version.
  • The version code is guaranteed to be unique and increase for each assembly
  • Version code can be converted in reverse order to an approximate build time if you need it
  • The above script replaces any current versionCode value, even 0, and does not require a macro holder (e.g. -build_id-).
  • Since the value is updated in the AndroidManifest.xml file, you can check it for version control and save the actual value, and not some macro (for example, -build_id -).
+3
Sep 15 '14 at 23:12
source share

Based on Rocky's answer I increased this python script a bit to increase also versionCode, works for me on Eclipse (integrated as ckozl great tutorial ) and Mac OSX

 #!/usr/bin/python from xml.dom.minidom import parse dom1 = parse("AndroidManifest.xml") oldVersion = dom1.documentElement.getAttribute("android:versionName") oldVersionCode = dom1.documentElement.getAttribute("android:versionCode") versionNumbers = oldVersion.split('.') versionNumbers[-1] = unicode(int(versionNumbers[-1]) + 1) dom1.documentElement.setAttribute("android:versionName", u'.'.join(versionNumbers)) dom1.documentElement.setAttribute("android:versionCode", str(int(oldVersionCode)+1)) with open("AndroidManifest.xml", 'wb') as f: for line in dom1.toxml("utf-8"): f.write(line) 

also don't forget chmod +x autoincrement.py and make sure you have the correct python path in the first line (depending on your environment) as sulai pointed from

+2
Oct 09 '13 at 15:45
source share

I did something similar, but wrote it as a Desktop AIR application instead of some external C # (did not feel like installing another build system). Create this Flex / ActionScript application and change the path to your file, create it as a standalone desktop application. It overwrites part 1.2.3 of your file.

  <?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="371" height="255" applicationComplete="Init();"> <fx:Declarations> <!-- Place non-visual elements (eg, services, value objects) here --> </fx:Declarations> <fx:Script> <![CDATA[ public function Init():void { import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; var myFile:File = new File("D:\\Dropbox\\Projects\\My App\\src\\Main-app.xml"); var fileStream:FileStream = new FileStream(); fileStream.open(myFile, FileMode.READ); var fileContents:String = fileStream.readUTFBytes(fileStream.bytesAvailable); var startIndex:Number = fileContents.indexOf("<versionNumber>"); var numberIndex:Number = startIndex + 15; var endIndex:Number = fileContents.indexOf("</versionNumber>"); if (startIndex == -1 || endIndex == -1) return; var versionNumber:String = fileContents.substr(numberIndex, endIndex - numberIndex); var versionArr:Array = versionNumber.split("."); var newSub:Number = Number(versionArr[2]); newSub++; versionArr[2] = newSub.toString(); versionNumber = versionArr.join("."); var newContents:String = fileContents.substr(0, startIndex) + "<versionNumber>" + versionNumber + "</versionNumber>" + fileContents.substr(endIndex + 16); fileStream.close(); fileStream = new FileStream(); fileStream.open(myFile, FileMode.WRITE); fileStream.writeUTFBytes(newContents); fileStream.close(); close(); } ]]> </fx:Script> <s:Label x="10" y="116" width="351" height="20" fontSize="17" text="Updating My App Version Number" textAlign="center"/> </s:WindowedApplication> 
+1
Apr 28 '12 at 8:53
source share

I was able to develop my own solution from the information given. In case this is useful to someone, this is my bash script for updating versionCode and versionName attributes when using GIT VCS on Linux.

My script for editing the AndroidManifest.xml file is as follows:

 #/bin/bash CODE=`git tag | grep -c ^v` NAME=`git describe --dirty` COMMITS=`echo ${NAME} | sed -e 's/v[0-9\.]*//'` if [ "x${COMMITS}x" = "xx" ] ; then VERSION="${NAME}" else BRANCH=" (`git branch | grep "^\*" | sed -e 's/^..//'`)" VERSION="${NAME}${BRANCH}" fi cat AndroidManifest.template.xml \\ | sed -e "s/__CODE__/${CODE}/" \\ -e "s/__VERSION__/${VERSION}/" > AndroidManifest.xml exit 0 

It parses the template file (AndroidManifest.template.xml) and replaces the strings "__VERSION__" and "__CODE__" with more appropriate values:

  • "__ CODE__" is replaced by the number of tags counter in the GIT repository, which starts with one lowercase V and is followed by a sequence of numbers and dots. This is similar to most version lines: "v0.5", "v1.1.4", etc.
  • "__ VERSION__" is replaced by a combination of the output of the "git describe" command and, if not a "clean" assembly, the branch on which it was built.

By "clean" build, I mean that all components are under version control, and their last commit is marked. "git describe --dirty" will report the version number based on the last available annotated tag in your last commit in the current branch. If there are commits from this tag, the number of these commits is reported as the abbreviated name of the object of your last commit. The "--dirty" option will add "-dirty" to the above information if any files that are under version control have been changed.

So, AndroidManifest.xml should no longer be versioned, and you should only edit the AndroidManifest.template.xml file. The beginning of your AndroidManifest.template.xml file looks something like this:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.packagename" android:versionCode="__CODE__" android:versionName="__VERSION__" > 

Hope this is useful to someone

+1
Nov 13 '12 at 18:30
source share

All loans go to ckoz, but I debugged my own implementation in C #. I think this is a little faster and there is no mistake, because if something goes wrong, maybe something is incorrectly configured, and I should know about it.

 namespace AndroidVersionCodeAutoIncrement { using System.IO; using System.Text.RegularExpressions; public class Program { private static readonly Regex VersionCodeRegex = new Regex("android:versionCode=\"(?<version>.*)\"", RegexOptions.Compiled); public static void Main() { using (var manifestFileStream = File.Open("AndroidManifest.xml", FileMode.Open, FileAccess.ReadWrite)) using (var streamReader = new StreamReader(manifestFileStream)) { var manifestFileText = streamReader.ReadToEnd(); var firstMatch = VersionCodeRegex.Match(manifestFileText); if (firstMatch.Success) { int versionCode; var versionCodeValue = firstMatch.Groups["version"].Value; if (int.TryParse(versionCodeValue, out versionCode)) { manifestFileText = VersionCodeRegex.Replace(manifestFileText, "android:versionCode=\"" + (versionCode + 1) + "\"", 1); using (var streamWriter = new StreamWriter(manifestFileStream)) { manifestFileStream.Seek(0, SeekOrigin.Begin); streamWriter.Write(manifestFileText); manifestFileStream.SetLength(manifestFileText.Length); } } } } } } } 
+1
Dec 26 '12 at 20:41
source share

For those who are on OSX and want to use Python, but will not lose the XML formatting that occurs when parsing with the python XML parser, here is a python script that will do incremental based on a regular expression that preserves the formatting:

 #!/usr/bin/python import re f = open('AndroidManifest.xml', 'r+') text = f.read() result = re.search(r'(?P<groupA>android:versionName=")(?P<version>.*)(?P<groupB>")',text) version = str(float(result.group("version")) + 0.01) newVersionString = result.group("groupA") + version + result.group("groupB") newText = re.sub(r'android:versionName=".*"', newVersionString, text); f.seek(0) f.write(newText) f.truncate() f.close() 

This code was based on @ckozl's answer, just in python, so you don’t need to create an executable for this. Just name the script autoincrement.py, put it in the same folder with the manifest.xml file, and then follow the steps described above ckozl!

+1
Jan 08 '14 at 18:38 on
source share

If you want to update AndroidManifest.xml to use a specific version number, possibly from the build system, then you can use the project that I just clicked on GitHub: https://github.com/bluebirdtech/AndroidManifestVersioner

This is the basic .NET command line application using:

 AndroidManifestVersioner <path> <versionCode> <versionName>. 

Thanks to the other posters for their code.

0
Jul 10 '13 at 21:07 on
source share

Here is the Java version for what it costs. Also handles several manifestations.

 String directory = "d:\\Android\\workspace\\"; String[] manifests = new String[] { "app-free\\AndroidManifest.xml", "app-donate\\AndroidManifest.xml", }; public static void main(String[] args) { new version_code().run(); } public void run() { int I = manifests.length; for(int i = 0; i < I; i++) { String path = directory + manifests[i]; String content = readFile(path); Pattern versionPattern = Pattern.compile( "(.*android:versionCode=\")([0-9]+)(\".*)", Pattern.DOTALL ); Matcher m = versionPattern.matcher(content); if (m.matches()) { int code = Integer.parseInt( m.group(2) ) + 1; System.out.println("Updating manifest " + path + " with versionCode=" + code); String newContent = m.replaceFirst("$1" + code + "$3"); writeFile(path + ".original.txt", content); writeFile(path, newContent); } else { System.out.println("No match to update manifest " + path); } } } 
0
Nov 13 '13 at 11:58 on
source share

If you use gradle, then in build.gradle you can use special versionName and versionCode . You can use git commit count as an increasing number to identify the assembly.

You can also use this library: https://github.com/rockerhieu/Versionberg .

0
Sep 19 '16 at 10:16
source share



All Articles