Auto increment version code in Android app

后端 未结 15 992
忘掉有多难
忘掉有多难 2020-12-07 08:22

is there a way to auto-increment the version code each time you build an Android application in Eclipse?

According to http://developer.android.com/guide/publishing/v

相关标签:
15条回答
  • 2020-12-07 08:43

    Building on Charles' answer, the following increments the existing build version:

    #!/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)
    
    0 讨论(0)
  • 2020-12-07 08:43

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

    It's a basic .NET command line app, usage:

    AndroidManifestVersioner <path> <versionCode> <versionName>.
    

    Thanks to other posters for their code.

    0 讨论(0)
  • 2020-12-07 08:43

    There are two solutions I really like. The first depends on the Play Store and the other depends on Git.

    Using the Play Store, you can increment the version code by looking at the highest available uploaded version code. The benefit of this solution is that an APK upload will never fail since your version code is always one higher than whatever is on the Play Store. The downside is that distributing your APK outside of the Play Store becomes more difficult. You can set this up using Gradle Play Publisher by following the quickstart guide and telling the plugin to resolve version codes automatically:

    plugins {
        id 'com.android.application'
        id 'com.github.triplet.play' version 'x.x.x'
    }
    
    android {
        ...
    }
    
    play {
        serviceAccountCredentials = file("your-credentials.json")
        resolutionStrategy = "auto"
    }
    

    Using Git, you can increment the version code based on how many commits and tags your repository has. The benefit here is that your output is reproducible and doesn't depend on anything outside your repo. The downside is that you have to make a new commit or tag to bump your version code. You can set this up by adding the Version Master Gradle plugin:

    plugins {
        id 'com.android.application'
        id 'com.supercilex.gradle.versions' version 'x.x.x'
    }
    
    android {
        ...
    }
    
    0 讨论(0)
  • 2020-12-07 08:44

    This shell script, suitable for *nix systems, sets the versionCode and the last component of versionName to the current subversion revision. I'm using Netbeans with NBAndroid and I call this script from the target -pre-compile in custom_rules.xml.

    Save this script in a file called incVersion 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 this:

    <?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 svn revision is 82, I end up with this in AndroidManifest.xml:

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

    When I want to release a new version I'll typically update the first parts of versionName, but even if I forget, the last part of versionName (which is exposed in my About activity) will always tell me what svn revision it was built from. Also, if I have not checked in changes, the revision number will be 82M and versionName will be something like 2.1.82M.

    The advantage over simply incrementing the version number each time a build is done is that the number stays under control, and can be directly related to a specific svn revision. Very helpful when investigating bugs in other than the latest release.

    0 讨论(0)
  • 2020-12-07 08:46

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

    My script to edit the AndroidManifest.xml file looks like this:

    #/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 with a count of the number of tags in the Git repo which starts with a single lowercase V and is followed by a sequence of digits and dots. This looks like most version string like: "v0.5", "v1.1.4" and so on.
    • "__VERSION__" is replaced with a combination of the output from the "git describe" command and, if not a "clean" build, the branch on which it was built.

    By a "clean" build I mean one where all the components are under version control and their is latest commit is tagged. "git describe --dirty" will report a version number based upon the last reachable annotated tag in your latest commit on the current branch. If there are commits since that tag a count of those commits is reported as is the abbreviated object name of your last commit. The "--dirty" option will append "-dirty" to the above information if any files are modified that are under version control have been modified.

    So AndroidManifest.xml should not be under version control any more, and you should only edit the AndroidManifest.template.xml file. The start 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

    0 讨论(0)
  • 2020-12-07 08:47

    I've done something similar but written it as a Desktop AIR app instead of some external C# (didn't feel installing another build system). Build this Flex/ActionScript app and change the path to your file, the build it as a standalone desktop app. It rewrites the 1.2.3 part 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 (e.g., 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>
    
    0 讨论(0)
提交回复
热议问题