11

由于 android 版本名称是字符串数据类型,我想将我设备上现有的 apk 与新的 apk 更新版本名称进行比较。我知道如何以编程方式获取版本名称,并且我有两个版本名称,但是两个版本名称之间的字符串比较未显示正确的结果

if ( oldVersionName.compareTo( newVersionName ) < 0 ) {
}

此 compareTo 在 1.0.9 和 1.0.12、1.0.9 和 1.0.10 等少数情况下不起作用。

请给我关于如何以编程方式比较两个字符串版本名称的解决方案?谢谢!

4

11 回答 11

24

您可以使用获取 Android 版本的“int 形式”

 Build.VERSION.SDK_INT

无论如何,如果您只有“点表示法”中的版本名称,则可以split通过“。”来字符串。char,并迭代以逐部分比较。在我的头顶上,它看起来像.-

public int compareVersionNames(String oldVersionName, String newVersionName) {
    int res = 0;

    String[] oldNumbers = oldVersionName.split("\\.");
    String[] newNumbers = newVersionName.split("\\.");

    // To avoid IndexOutOfBounds
    int maxIndex = Math.min(oldNumbers.length, newNumbers.length);

    for (int i = 0; i < maxIndex; i ++) {
        int oldVersionPart = Integer.valueOf(oldNumbers[i]);
        int newVersionPart = Integer.valueOf(newNumbers[i]);

        if (oldVersionPart < newVersionPart) {
            res = -1;
            break;
        } else if (oldVersionPart > newVersionPart) {
            res = 1;
            break;
        }
    }

    // If versions are the same so far, but they have different length...
    if (res == 0 && oldNumbers.length != newNumbers.length) {
        res = (oldNumbers.length > newNumbers.length)?1:-1;
    }

    return res;
}

刚写没试过,所以肯定可以优化,不过是个开始。

于 2013-09-09T13:44:56.367 回答
3

新版本 = 1.2.1 -> 121 -> 121

旧版本 = 1.2 -> 12 -> 120

121 > 120 ?

返回真


新版本 = 1.5.15 -> 1515 -> 1515

旧版本 = 2.0 -> 20 -> 2000

1515 > 2000 ?

返回假

public static boolean checkForUpdate(String existingVersion, String newVersion) {
    if (existingVersion.isEmpty() || newVersion.isEmpty()) {
        return false;
    }

    existingVersion = existingVersion.replaceAll("\\.", "");
    newVersion = newVersion.replaceAll("\\.", "");

    int existingVersionLength = existingVersion.length();
    int newVersionLength = newVersion.length();

    StringBuilder versionBuilder = new StringBuilder();
    if (newVersionLength > existingVersionLength) {
        versionBuilder.append(existingVersion);
        for (int i = existingVersionLength; i < newVersionLength; i++) {
            versionBuilder.append("0");
        }
        existingVersion = versionBuilder.toString();
    } else if (existingVersionLength > newVersionLength){
        versionBuilder.append(newVersion);
        for (int i = newVersionLength; i < existingVersionLength; i++) {
            versionBuilder.append("0");
        }
        newVersion = versionBuilder.toString();
    }

    return Integer.parseInt(newVersion) > Integer.parseInt(existingVersion);
}
于 2019-05-18T08:38:26.577 回答
1
public boolean checkVersion() {
    boolean isLastVersion = false;
    Double lastVersion = convertVersion(getAppVersion());
    Double runningVersion = convertVersion(BuildConfig.VERSION_NAME);

    if (runningVersion >= lastVersion) {
        isLastVersion = true;
    }

    return isLastVersion;
}
public Double convertVersion(String version) {
    Double convertedVersion = 0.0;

    version = version.replace(".", "");
    String versionAux1 = version.substring(0,1);
    String versionAux2 = version.substring(1, version.length());

    version = versionAux1 + "." + versionAux2;
    convertedVersion = Double.valueOf(version);
    return convertedVersion;
}

getAppVersion() 返回要比较的版本

convertVersion(String version) 将没有一个或多个点的 String 值转换为 Double 值

于 2019-10-09T11:50:57.913 回答
0

AndroidManifest.xml你必须指定一个整数versionCode以及一个字符串versionName。这两个值都可以在运行时检索,因此您应该使用versionCode而不是versionName比较应用程序版本。

如果要检索versionCode自己的应用程序,可以使用以下代码:

public static int getAppVersionCode(Context context) {
    PackageInfo packageInfo = getPackageInfo(context);
    return packageInfo.versionCode;
}

private static PackageInfo getPackageInfo(Context context) {
    try {
        return context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
    }
    catch (NameNotFoundException e) {
        throw new IllegalStateException(e);
    }
}

可以通过提供正确的包名称来检索其他应用程序的版本代码。

于 2013-09-09T14:48:54.807 回答
0

//这是ac#版本但是你可以很容易地转换成java

//如果两个版本相同则返回0,如果版本1更大则返回1,如果版本1更低则返回-1

    public int compareVersionCode(string version1,string version2,char spliteType='.')
    {

        string[] version1A = version1.Split(spliteType);
        string[] version2A = version2.Split(spliteType);



        // To avoid IndexOutOfBounds
        int maxIndex = Math.Min(version1A.Length, version2A.Length);
    
        for (int i = 0; i < maxIndex; i++)
        {
            int v1 = int.Parse(version1A[i]);
            int v2 = int.Parse(version2A[i]);

            if (v1 < v2)
            {
               return -1;
            }
            else if (v1 > v2)
            {
                return  1;
            }

        }
        return 0;
    }
于 2021-06-01T09:40:41.573 回答
0

我用以下代码解决了这个问题:

    String VERSION_TO_COMPARE = "1.2.3"   

    try {

        //get current Version Code
        PackageManager manager = this.getPackageManager();
        PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0);
        String currentVersionName = info.versionName;

        if(!VERSION_TO_COMPARE.equals(currentVersionName)){
            //version string not the same, version is NOT up to date

            Boolean updateNeeded = false;
            String[] currentVersionCodeArray = currentVersionName.split("\\.");
            String[] storeVersionCodeArray = VERSION_TO_COMPARE.split("\\.");

            int maxLength = currentVersionCodeArray.length;
            if(storeVersionCodeArray.length > maxLength){
                maxLength = storeVersionCodeArray.length;
            }

            for (int i = 0; i < maxLength; i++){

                try{
                    if(Integer.parseInt(storeVersionCodeArray[i]) > Integer.parseInt(currentVersionCodeArray[i])){
                        updateNeeded = true;
                        continue;
                    }
                }
                catch(IndexOutOfBoundsException e){
                    //store version code length > current version length = version needs to be updated
                    //if store version length is shorter, the if-statement already did the job
                    if(storeVersionCodeArray.length > currentVersionCodeArray.length){
                        updateNeeded = true;
                    }
                }


            }

            if(updateNeeded){
                //current version of app, lower than VERSION_TO_COMPARE
                //do sth. in our case, show an update-dialog
            }

        }
        else{
            //do nothing: version is up to date
        }

    } catch (PackageManager.NameNotFoundException e){
        e.printStackTrace();
    }
于 2015-07-09T07:42:29.580 回答
0

我为此编写了一个小型 Android 库:https ://github.com/G00fY2/version-compare

它的基本作用是这样的:

  public int compareVersions(String versionA, String versionB) {
    String[] versionTokensA = versionA.split("\\.");
    String[] versionTokensB = versionB.split("\\.");
    List<Integer> versionNumbersA = new ArrayList<>();
    List<Integer> versionNumbersB = new ArrayList<>();

    for (String versionToken : versionTokensA) {
      versionNumbersA.add(Integer.parseInt(versionToken));
    }
    for (String versionToken : versionTokensB) {
      versionNumbersB.add(Integer.parseInt(versionToken));
    }

    final int versionASize = versionNumbersA.size();
    final int versionBSize = versionNumbersB.size();
    int maxSize = Math.max(versionASize, versionBSize);

    for (int i = 0; i < maxSize; i++) {
      if ((i < versionASize ? versionNumbersA.get(i) : 0) > (i < versionBSize ? versionNumbersB.get(i) : 0)) {
        return 1;
      } else if ((i < versionASize ? versionNumbersA.get(i) : 0) < (i < versionBSize ? versionNumbersB.get(i) : 0)) {
        return -1;
      }
    }
    return 0;
  }

此代码段不提供任何错误检查或处理。除此之外,我的库还支持“1.2-rc”>“1.2-beta”等后缀。

于 2018-02-27T14:08:18.597 回答
0

最重要的是,解决方案对我不起作用。所以我有另一个解决方案给大家

1.使用这个类:

public class VersionComparator implements Comparator {

public boolean equals(Object o1, Object o2) {
    return compare(o1, o2) == 0;
}

public int compare(Object o1, Object o2) {
    String version1 = (String) o1;
    String version2 = (String) o2;

    VersionTokenizer tokenizer1 = new VersionTokenizer(version1);
    VersionTokenizer tokenizer2 = new VersionTokenizer(version2);

    int number1, number2;
    String suffix1, suffix2;

    while (tokenizer1.MoveNext()) {
        if (!tokenizer2.MoveNext()) {
            do {
                number1 = tokenizer1.getNumber();
                suffix1 = tokenizer1.getSuffix();
                if (number1 != 0 || suffix1.length() != 0) {
                    // Version one is longer than number two, and non-zero
                    return 1;
                }
            }
            while (tokenizer1.MoveNext());

            // Version one is longer than version two, but zero
            return 0;
        }

        number1 = tokenizer1.getNumber();
        suffix1 = tokenizer1.getSuffix();
        number2 = tokenizer2.getNumber();
        suffix2 = tokenizer2.getSuffix();

        if (number1 < number2) {
            // Number one is less than number two
            return -1;
        }
        if (number1 > number2) {
            // Number one is greater than number two
            return 1;
        }

        boolean empty1 = suffix1.length() == 0;
        boolean empty2 = suffix2.length() == 0;

        if (empty1 && empty2) continue; // No suffixes
        if (empty1) return 1; // First suffix is empty (1.2 > 1.2b)
        if (empty2) return -1; // Second suffix is empty (1.2a < 1.2)

        // Lexical comparison of suffixes
        int result = suffix1.compareTo(suffix2);
        if (result != 0) return result;

    }
    if (tokenizer2.MoveNext()) {
        do {
            number2 = tokenizer2.getNumber();
            suffix2 = tokenizer2.getSuffix();
            if (number2 != 0 || suffix2.length() != 0) {
                // Version one is longer than version two, and non-zero
                return -1;
            }
        }
        while (tokenizer2.MoveNext());

        // Version two is longer than version one, but zero
        return 0;
    }
    return 0;
}

// VersionTokenizer.java
public static class VersionTokenizer {
    private final String _versionString;
    private final int _length;

    private int _position;
    private int _number;
    private String _suffix;
    private boolean _hasValue;

    VersionTokenizer(String versionString) {
        if (versionString == null)
            throw new IllegalArgumentException("versionString is null");

        _versionString = versionString;
        _length = versionString.length();
    }

    public int getNumber() {
        return _number;
    }

    String getSuffix() {
        return _suffix;
    }

    public boolean hasValue() {
        return _hasValue;
    }

    boolean MoveNext() {
        _number = 0;
        _suffix = "";
        _hasValue = false;

        // No more characters
        if (_position >= _length)
            return false;

        _hasValue = true;

        while (_position < _length) {
            char c = _versionString.charAt(_position);
            if (c < '0' || c > '9') break;
            _number = _number * 10 + (c - '0');
            _position++;
        }

        int suffixStart = _position;

        while (_position < _length) {
            char c = _versionString.charAt(_position);
            if (c == '.') break;
            _position++;
        }

        _suffix = _versionString.substring(suffixStart, _position);

        if (_position < _length) _position++;

        return true;
    }
}

}

2.创建这个函数

    private fun isNewVersionAvailable(currentVersion: String, latestVersion: String): Boolean {
    val versionComparator = VersionComparator()
    val result: Int = versionComparator.compare(currentVersion, latestVersion)
    var op = "=="
    if (result < 0) op = "<"
    if (result > 0) op = ">"
    System.out.printf("%s %s %s\n", currentVersion, op, latestVersion)
    return if (op == ">" || op == "==") {
        false
    } else op == "<"
}

3. 只需调用它

例如isNewVersionAvailable("1.2.8","1.2.9")1.2.8您的当前版本在哪里,并且1.2.9是最新版本,返回 true!

快乐编码!

于 2020-05-13T11:40:23.437 回答
0

/** * 该方法比较两个 APK 版本并返回 true,如果现有版本更小/更旧,则为新版本。* * @param existingVersion 验证的版本newVersion。* @param newVersion 最近可能在一个驱动器或 Playstore 中更新的版本。*/

 public static boolean checkForUpdate(String existingVersion, String newVersion) {
     if (TextUtils.isEmpty(existingVersion) || TextUtils.isEmpty(newVersion)) {
         return false;
     }
     boolean newVersionIsGreater = false;
     String[] existingVersionArray = existingVersion.split("\\.");
     String[] newVersionArray = newVersion.split("\\.");

     int maxIndex = Math.max(existingVersionArray.length, newVersionArray.length);
     for (int i = 0; i < maxIndex; i++) {
         int newValue;
         int oldValue;
         try {
             oldValue = Integer.parseInt(existingVersionArray[i]);
         } catch (ArrayIndexOutOfBoundsException e) {
             oldValue = 0;
         }
         try {
             newValue = Integer.parseInt(newVersionArray[i]);
         } catch (ArrayIndexOutOfBoundsException e) {
             newValue = 0;
         }
         if (oldValue < newValue) {
             newVersionIsGreater = true;
             continue;
         }
     }
     return newVersionIsGreater;
 }
于 2016-12-29T09:00:04.383 回答
-1

我有一个更简单的 Kotlin 解决方案。

它支持与非数字字符的版本比较和大于 10 的版本号,如下例所示。

"1.0.0".compareToVersion("1.0.0")result = 0

"1.0.0c".compareToVersion("1.0.0b")result < 0

"1.0.10".compareToVersion("1.0.9c")result > 0

"1.0.10-1".compareToVersion("1.0.10-2")result < 0

"10.0.1a".compareToVersion("9.0.10a")result > 0

fun String.compareToVersion(version: String): Int {
    // Split with non-digit char
    val pattern = Pattern.compile("[^0-9]")
    val inputVersionSplit = version.split(pattern)

    // Convert each block as Int and return the first return that is not equal
    split(pattern).mapIndexed { index, thisVersionSub ->
        thisVersionSub.toIntOrNull()
            ?.compareTo(inputVersionSplit.getOrNull(index)?.toIntOrNull() ?: 0)
            ?.takeIf { it != 0 }
            ?.also { return it }
    }

    // If version splits are identical, compare by String
    return compareTo(version)
}
于 2019-06-11T06:27:21.123 回答
-1

您正在获取字符串中的版本,因此请删除。在那并转换为浮动并比较

onlineVersion = onlineVersion.replace(".", "");
currentVersion = currentVersion.replace(".", "");

if (Float.valueOf(currentVersion) < Float.valueOf(onlineVersion)) {
    //if new update is available it will come here
}
于 2019-05-03T08:21:17.943 回答