如何从App的(布局)XML变量中获取Manifest版本号?

Pea*_*oto 177 android android-manifest android-xml

我想有一种方法在代码的主要部分引用项目的清单版本号.到目前为止我一直在做的是将String XML文件中的版本号链接到清单(@ string/Version).我想做的是反过来做,将字符串XML变量链接到清单中的版本.原因?我只想在一个位置更改清单文件中的版本号.有没有办法做到这一点?谢谢!

Kon*_*rov 361

我相信这里已经回答.

String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
Run Code Online (Sandbox Code Playgroud)

要么

int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
Run Code Online (Sandbox Code Playgroud)

  • 几乎,但不完全......我想做的是将它引用到XML代码,但看起来可能不可能,所以...... (8认同)
  • 将BuildConfig.VERSION_NAME添加到您的答案中以获取gradle fokes. (2认同)

Pea*_*oto 99

没有办法直接获得版本,但有两种解决办法可以完成.

  1. 版本可以存储在资源字符串中,并通过以下方式放入清单:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.somepackage"
         android:versionName="@string/version" android:versionCode="20">
    
    Run Code Online (Sandbox Code Playgroud)
  2. 可以创建自定义视图,并将其放入XML中.视图将使用它来指定名称:

    context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
    
    Run Code Online (Sandbox Code Playgroud)

这些解决方案中的任何一个都允许将版本名称放在XML中.不幸的是,没有一个很好的简单解决方案,比如类似的android.R.string.version东西.

  • 一个小注1:它正在工作,但我认为它是气馁的,因为我得到一个警告告诉我'android:versionName不能是一个资源网址,它必须是一个文字字符串` (14认同)

Aru*_*kar 60

您可以使用versionNameXML资源,例如活动布局.首先app/build.gradle使用android节点中的以下代码段创建字符串资源:

applicationVariants.all { variant ->
    variant.resValue "string", "versionName", variant.versionName
}
Run Code Online (Sandbox Code Playgroud)

所以整个build.gradle文件内容可能如下所示:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion '24.0.0 rc3'
    defaultConfig {
        applicationId 'com.example.myapplication'
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 17
        versionName '0.2.3'
        jackOptions {
            enabled true
        }
    }
    applicationVariants.all { variant ->
        variant.resValue "string", "versionName", variant.versionName
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
} 

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.android.support:design:23.3.0'
    compile 'com.android.support:support-v4:23.3.0'
}
Run Code Online (Sandbox Code Playgroud)

然后你可以@string/versionName在XML中使用.Android Studio会将其标记为红色,但应用程序将编译没有问题.例如,这可以像这样使用app/src/main/res/xml/preferences.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory
        android:title="About"
        android:key="pref_key_about">

        <Preference
            android:key="pref_about_build"
            android:title="Build version"
            android:summary="@string/versionName" />

    </PreferenceCategory>


</PreferenceScreen>
Run Code Online (Sandbox Code Playgroud)

  • @DenisGL http://michiganlabs.com/string-constants-generated-gradle-build-configurations/#.VtB0-px96Um (3认同)
  • 这比程序化风格更好. (3认同)
  • 这应该被认为是最好的答案。 (3认同)
  • 精彩的解决方案.万分感谢. (2认同)
  • 我正在使用最新的并且仍然对我有用。我使用这个和其他几个像这样的变量。@k2col 编译时出现什么错误?请发布您的gradle代码 (2认同)
  • @ArunElectra 无法解析符号。但它允许运行和生成 apk。它只是错误的标记。 (2认同)

小智 15

我通过扩展Preference类解决了这个问题.

package com.example.android;

import android.content.Context;
import android.preference.Preference;
import android.util.AttributeSet;

public class VersionPreference extends Preference {
    public VersionPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        String versionName;
        final PackageManager packageManager = context.getPackageManager();
        if (packageManager != null) {
            try {
                PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
                versionName = packageInfo.versionName;
            } catch (PackageManager.NameNotFoundException e) {
                versionName = null;
            }
            setSummary(versionName);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在我的首选项XML:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <com.example.android.VersionPreference android:title="Version" />
</PreferenceScreen>
Run Code Online (Sandbox Code Playgroud)


Mul*_*man 10

我用BuildConfig.VERSION_NAME.toString();.它与packageManager之间的区别是什么?

对不起,没有基于XML的解决方案对我有用.

  • BuildConfig.VERSION_NAME已经是一个字符串,无需在其上调用toString(). (5认同)

Cra*_*lWS 8

如果使用的是Gradle,则可以在编译时使用build.gradle文件以编程方式向xml资源添加值。

示例代码摘自:https : //medium.com/@manas/manage-your-android-app-s-versioncode-versionname-with-gradle-7f9c5dcf09bf

buildTypes {
    debug {
        versionNameSuffix ".debug"
        resValue "string", "app_version", "${defaultConfig.versionName}${versionNameSuffix}"
    }
    release {
        resValue "string", "app_version", "${defaultConfig.versionName}"
    }
}
Run Code Online (Sandbox Code Playgroud)

现在@string/app_version根据需要在XML中使用

.debug在调试模式下,它将添加到链接的文章中描述的版本名称。