Как получить номер версии манифеста из XML-переменных приложения (макета)? - PullRequest
176 голосов
/ 17 декабря 2010

Я хотел бы иметь возможность ссылаться на номер версии манифеста проекта в основной части кода. До этого момента я связывал номер версии в XML-файле String с манифестом (@ string / Version). Я хотел бы сделать это наоборот, связать строковую переменную XML с версией в манифесте. Причина? Я хотел бы только изменить номер версии в одном месте, файл манифеста. Есть какой-либо способ сделать это? Спасибо!

Ответы [ 9 ]

361 голосов
/ 17 декабря 2010

Я думаю, что уже ответили здесь .

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

ИЛИ

int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
98 голосов
/ 09 декабря 2012

Нет прямого способа получить версию, но есть два обходных пути, которые можно сделать.

  1. Версия может быть сохранена в строке ресурса и помещена в манифест следующим образом:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.somepackage"
         android:versionName="@string/version" android:versionCode="20">
    
  2. Можно создать собственное представление и поместить его в XML. Представление будет использовать это, чтобы назначить имя:

    context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
    

Любое из этих решений позволит разместить название версии в XML. К сожалению, не существует хорошего простого решения, такого как android.R.string.version или что-то в этом роде.

59 голосов
/ 07 апреля 2016

Вы можете использовать versionName в ресурсах XML, таких как макеты действий.Сначала создайте строковый ресурс в app/build.gradle со следующим фрагментом в узле android:

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

Таким образом, все содержимое файла 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'
}

Тогда вы можете использовать @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>
15 голосов
/ 23 ноября 2013

Я решил эту проблему, расширив класс 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);
        }
    }
}

Тогда в моих настройках XML:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <com.example.android.VersionPreference android:title="Version" />
</PreferenceScreen>
10 голосов
/ 08 января 2016

Я использую BuildConfig.VERSION_NAME.toString();.В чем разница между этим и получением его из packageManager?

Никакие решения на основе XML не помогли мне, извините.

6 голосов
/ 19 августа 2018

Если вы используете 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}"
    }
}

теперь используйте @string/app_version по мере необходимости в XML

Он добавит .debug к имени версии, как описано в связанной статье, когда находится в режиме отладки.

2 голосов
/ 17 декабря 2010

Вы не можете использовать его из XML.

Вам нужно расширить виджет, который вы используете в XML, и добавить логику для задания текста, используя то, что упоминается в ответе Константина Бурова.

0 голосов
/ 23 июня 2019

Самое простое решение - использовать BuildConfig.

Я использую BuildConfig.VERSION_NAME в своем приложении.

Вы также можете использовать BuildConfig.VERSION_CODE для получения кода версии.

0 голосов
/ 09 сентября 2013

Поздно к игре, но вы можете сделать это без @string/xyz, используя ?android:attr

    <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"
     />
...