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

How can you get the Manifest Version number from the App's (Layout) XML variables?

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


我相信这里已经回答了。

1
String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;

要么

1
int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;


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

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

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

    1
    context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
  • 这些解决方案中的任何一个都允许将版本名称放在XML中。不幸的是,没有一个很好的简单解决方案,比如android.R.string.version或类似的东西。


    您可以在XML资源中使用versionName,例如活动布局。首先在app/build.gradle中创建一个字符串资源,并在android节点中使用以下代码段:

    1
    2
    3
    applicationVariants.all { variant ->
        variant.resValue"string","versionName", variant.versionName
    }

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    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'
    }

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <?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>


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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);
            }
        }
    }

    然后在我的首选项XML:

    1
    2
    3
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
        <com.example.android.VersionPreference android:title="Version" />
    </PreferenceScreen>


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

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


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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    buildTypes {
        debug {
            versionNameSuffix".debug"
            resValue"string","app_version","${defaultConfig.versionName}${versionNameSuffix}"
        }
        release {
            resValue"string","app_version","${defaultConfig.versionName}"
        }
    }

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

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


    您无法从XML中使用它。

    您需要在XML中扩展您正在使用的小部件,并添加逻辑以使用Konstantin Burov的答案中提到的内容来设置文本。


    最简单的解决方案是使用BuildConfig

    我在我的应用程序中使用BuildConfig.VERSION_NAME

    您还可以使用BuildConfig.VERSION_CODE来获取版本代码。


    游戏的后期,但你可以使用?android:attr在没有@string/xyz的情况下完成

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="?android:attr/versionName"
         />
        <!-- or -->
        <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="?android:attr/versionCode"
         />