【问题标题】:android manifest build numberandroid清单内部版本号
【发布时间】:2010-09-09 02:52:43
【问题描述】:

我想知道是否可以让 Eclipse 在我每次构建或运行 Android 应用程序时自动增加 Manifest 内的构建版本号。

有人做过这样的事吗?

【问题讨论】:

    标签: android eclipse android-manifest


    【解决方案1】:

    我不认为 Eclipse 本身可以做到这一点,但我想您可以编写一个脚本来解析清单文件并更新数字。您可以将其设置为预构建步骤,因此每次 Eclipse 编译您的代码时,它都会更改编号。

    我唯一担心的是,您可能会获得相当大的数字,具体取决于您的开发过程的迭代程度。此外,这会使您有忘记更新版本字符串的风险,并且会提示用户从版本 1.0 升级到版本 1.0。

    【讨论】:

    • 没有理由脚本也不能更新版本字符串 :) 你知道如何让 Eclipse 运行脚本吗?我计划通过将其设置为仅在我将其推送到设备/模拟器时运行来避免大量数字。
    • 当然可以,但我不知道您是否更愿意控制版本字符串,因为它会暴露给用户。您可以在项目设置中设置构建步骤。我现在没有它,但基本上有构建步骤a)构建时,b)清理项目时,您可以添加任意数量的步骤。每个步骤都可以是执行的任意命令。
    【解决方案2】:

    这是我的几乎通用 Java 应用程序来更新版本代码和版本名称

    几乎是通用的,因为文件解析不是 100% 保证(与格式良好的 xml 清单一起工作正常,在大多数情况下应该没问题)

    选择/先决条件:

    • versionName 应该是 ma​​jor.minor.point(根据 Android 文档的建议)
    • versionName 可以保留、重置为 1.0.0 或递增(其中一个部分和尾随部分设置为 0)
    • versionCode 将替换为 Unix 时间

    代码:

    package com.mycompany.tools;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class IncrementVersion
    {
        enum INCREMENT
        {
            MAJOR, // increment 1rst component of version Code (i.e. 'major') add trailing '.0.0'
            MINOR, // preserve major, increment 2nd component of version Code (i.e. 'minor'), add trailing '.0'
            POINT, // preserver major, minor, increment 3rd component of version Code (i.e. 'point')
            NONE, // do not change versionName, only change version code (to current Unix times)
            RESET // RESET -> reset verseionNAme to 1.0.0
        }
    
    
        // update this to select which version name part to update
        static final INCREMENT increment = INCREMENT.NONE;
    
        static final String projectName = "com.mycompany.myproject";
        // OR static final String projectName = "com.mycompany"; -> match all my projects :-)
    
        public static void main(String[] args)
        {
            File directory = new File("");
    
            for (File projectDirecotry : directory.listFiles())
            {
                if (projectDirecotry.getName().startsWith(projectName))
                {
                    exec(projectDirecotry);
                }
            }
        }
    
        private static void exec(File projectDirectory)
        {
            File androidManifestFile = new File(projectDirectory, "AndroidManifest.xml");
            if (androidManifestFile.exists())
            {
                writeFile(androidManifestFile, readFile(androidManifestFile));
            }
        }
    
        private static void writeFile(File androidManifestFile, String newContent)
        {
            BufferedWriter bw = null;
            try
            {
                bw = new BufferedWriter(new FileWriter(androidManifestFile));
                bw.write(newContent);
            } catch (Throwable th)
            {
                th.printStackTrace();
            } finally
            {
                if (bw != null)
                {
                    try
                    {
                        bw.close();
                    } catch (Throwable th)
                    {
                    }
                }
            }
        }
    
        private static String readFile(File androidManifestFile)
        {
            StringBuilder sb = new StringBuilder();
            BufferedReader br = null;
            try
            {
                br = new BufferedReader(new FileReader(androidManifestFile));
                String line;
                while ((line = br.readLine()) != null)
                {
                    sb.append(parse(line)).append('\n');
                    //              System.out.println(line);
                }
            } catch (Throwable th)
            {
                th.printStackTrace();
            } finally
            {
                if (br != null)
                {
                    try
                    {
                        br.close();
                    } catch (Throwable th)
                    {
                    }
                }
            }
            return sb.toString();
        }
    
        //  public static final DateFormat dateTimeFormat = new SimpleDateFormat("yyyyMMddHHmm", Locale.ROOT);
    
        public static long getUnixTime()
        {
            return System.currentTimeMillis() / 1000L;
        }
    
        private static String parse(String line)
        {
            {
                //      android:versionCode="1"
                // use 201408221404 instead
                String versionCodePrefix = "android:versionCode=\"";
    
                int indexOfVersionCodePrefix = line.indexOf(versionCodePrefix);
                if (indexOfVersionCodePrefix != -1)
                {
                    indexOfVersionCodePrefix += versionCodePrefix.length();
                    versionCodePrefix = line.substring(0, indexOfVersionCodePrefix);
                    String versionCode = line.substring(indexOfVersionCodePrefix, line.length());
    
                    int indexOfVersionCodeSuffix = versionCode.indexOf('"');
                    if (indexOfVersionCodeSuffix != -1)
                    {
                        String versionCodeSuffix = versionCode.substring(indexOfVersionCodeSuffix);
                        //                  versionCode = versionCode.substring(0, indexOfVersionCodeSuffix);
                        //                  return versionCodePrefix + (Integer.parseInt(versionCode) + 1) + versionCodeSuffix;
                        // 1409302337
                        return versionCodePrefix + getUnixTime() + versionCodeSuffix;
                    }
                }
            }
    
            {
                if (increment != INCREMENT.NONE)
                {
                    //      android:versionName="1.0.0" >
    
                    String versionNamePrefix = "android:versionName=\"";
    
                    int indexOfVersionNamePrefix = line.indexOf(versionNamePrefix);
                    if (indexOfVersionNamePrefix != -1)
                    {
                        indexOfVersionNamePrefix += versionNamePrefix.length();
                        versionNamePrefix = line.substring(0, indexOfVersionNamePrefix);
                        String versionName = line.substring(indexOfVersionNamePrefix, line.length());
    
                        int indexOfVersionCodeSuffix = versionName.indexOf('"');
                        if (indexOfVersionCodeSuffix != -1)
                        {
                            String versionNameSuffix = versionName.substring(indexOfVersionCodeSuffix);
                            versionName = versionName.substring(0, indexOfVersionCodeSuffix);
    
                            Pattern pattern = Pattern.compile("([^\\.])*\\.([^\\.])*\\.([^\\.])*");
                            Matcher m = pattern.matcher(versionName);
                            if (m.matches())
                            {
                                int major = Integer.parseInt(m.group(1));
                                int minor = Integer.parseInt(m.group(2));
                                int point = Integer.parseInt(m.group(3));
    
                                switch (increment)
                                {
                                case MAJOR:
                                    major += 1;
                                    minor = 0;
                                    point = 0;
                                    break;
                                case MINOR:
                                    minor += 1;
                                    point = 0;
                                    break;
                                case POINT:
                                    point += 1;
                                    break;
                                case RESET:
                                    major = 1;
                                    minor = 0;
                                    point = 0;
                                    break;
                                default:
                                    break;
                                }
    
                                return versionNamePrefix + major + '.' + minor + '.' + point + versionNameSuffix;
                            }
                        }
                    }
                }
            }
    
            return line;
        }
    }
    

    【讨论】: