由于android版本名称是String数据类型,我想将我设备上现有的apk与新的apk更新版本名称进行比较。我知道如何以编程方式获取版本名称,并且我有两个版本名称,但两个版本名称之间的字符串比较未显示正确的结果
if ( oldVersionName.compareTo( newVersionName ) < 0 ) {
}
此比较在1.0.9和1.0.12,1.0.9和1.0.10等少数场景中不起作用。
请给我解决方法如何以编程方式比较两个字符串版本名称?谢谢!
答案 0 :(得分:14)
您可以获得&#39; int表格&#39;使用
的Android版本 Build.VERSION.SDK_INT
无论如何,如果您拥有的所有版本名称都是&#39;点符号&#39;,您可以通过&#39;来split
字符串。&#39; 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;
}
只是在没有尝试的情况下写作,所以确保可以优化,但这只是一个开始。
答案 1 :(得分: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(字符串版本)将不带任何点,一个或多个点的字符串值转换为双精度值
答案 2 :(得分: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);
}
}
可以通过提供正确的包名来检索其他应用的版本代码。
答案 3 :(得分: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();
}
答案 4 :(得分:0)
/ **
*该方法比较两个APK版本并返回true,如果existing更小/更旧,则返回新版本。
*
* @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;
}
答案 5 :(得分: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;
}
此代码段不提供任何错误检查或处理。除此之外,我的图书馆还支持诸如&#34; 1.2-rc&#34;之类的后缀。 &GT; &#34; 1.2-β&#34;
答案 6 :(得分:0)
您正在以字符串形式获取版本,因此请删除。然后转换为浮动并进行比较
onlineVersion = onlineVersion.replace(".", "");
currentVersion = currentVersion.replace(".", "");
if (Float.valueOf(currentVersion) < Float.valueOf(onlineVersion)) {
//if new update is available it will come here
}
答案 7 :(得分:0)
newVersion = 1.2.1-> 121-> 121
oldVersion = 1.2-> 12-> 120
121> 120吗?
返回真
newVersion = 1.5.15-> 1515-> 1515
oldVersion = 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);
}
答案 8 :(得分:0)
我对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)
}
答案 9 :(得分: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!
快乐编码!
答案 10 :(得分:0)
//这是一个c#版本但是你可以很容易地转换成java
//两个版本相同返回0,version1大返回1,version1小返回-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;
}