Como você pode obter o número da versão do manifesto a partir das variáveis ​​XML do aplicativo (layout)?

184

Eu gostaria de ter uma maneira de fazer referência ao número da versão do manifesto do projeto na parte principal do código. O que tenho feito até agora é vincular o número da versão em um arquivo XML String ao manifesto (@ string / Version). O que eu gostaria de fazer é fazer o contrário, vincular uma variável XML de cadeia de caracteres à versão no manifesto. O motivo? Gostaria apenas de alterar o número da versão em um local, o arquivo de manifesto. Há alguma maneira de fazer isso? Obrigado!

PearsonArtPhoto
fonte
17
Esta NÃO é uma duplicata. A pergunta em questão pergunta como fazer a mesma coisa em CODE, estou perguntando em XML. Duas construções muito diferentes na programação Android ...
Pearsonartphoto

Respostas:

367

Eu acredito que isso já foi respondido aqui .

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

OU

int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
Konstantin Burov
fonte
8
Quase, mas não completamente ... O que eu gostaria de fazer é para referenciá-lo para um código XML, mas parece que isso pode não ser possível, então ...
Pearsonartphoto
Muito obrigado!!! Eu tenho procurado em todos os lugares para isso:String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
Aaron Klap
1
@ Shubh Acho que não.
22913 Konstantin Burov
3
Adicione BuildConfig.VERSION_NAME à sua resposta para obter respostas sobre gradle.
jobbert
102

Não existe uma maneira de obter a versão diretamente, mas há duas soluções alternativas que podem ser feitas.

  1. A versão pode ser armazenada em uma cadeia de recursos e colocada no manifesto por:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.somepackage"
         android:versionName="@string/version" android:versionCode="20">
  2. Pode-se criar uma exibição personalizada e colocá-la no XML. A visualização usaria isso para atribuir o nome:

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

Qualquer uma dessas soluções permitiria colocar o nome da versão em XML. Infelizmente, não existe uma solução simples e agradável, android.R.string.versionalgo assim.

PearsonArtPhoto
fonte
14
uma pequena nota a 1 .: ele está trabalhando, mas eu acho que é desencorajado desde que eu receber um aviso dizendo-meThe android:versionName cannot be a resource url, it must be a literal string
Griddo
1
O que fiz foi deixar o nome da versão do manifesto intocado (mas atualizá-lo sempre que uma nova versão) e usar o string.xml para armazenar o valor que utilizarei no aplicativo.
Numeroweb
1
Para AndroidStudio, o manifesto versionNameé substituir por um conjunto de build.gradlearquivo
Adrian C.
66

Você pode usar os versionNamerecursos XML, como layouts de atividades. Primeiro, crie um recurso de cadeia no app/build.gradlecom o seguinte fragmento no androidnó:

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

Portanto, todo build.gradleo conteúdo do arquivo pode ficar assim:

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'
}

Então você pode usar @string/versionNameno XML. O Android Studio o marcará em vermelho, mas o aplicativo será compilado sem problemas. Por exemplo, isso pode ser usado assim em 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>
Arun Shankar
fonte
3
@DenisGL michiganlabs.com/…
Arun Shankar
3
Isto é melhor, do que estilo programático.
Neurotransmitter
2
Solução maravilhosa. Muito obrigado.
Samik Bandyopadhyay 7/08/16
2
Estou usando o mais recente e ainda funciona para mim. Eu uso isso e várias outras variáveis ​​como esta. @ k2col que erro você recebe durante a compilação? Pls post ur código Gradle
Arun Shankar
3
Essa deve ser considerada a melhor resposta.
pepan
15

Resolvi esse problema estendendo a classe 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);
        }
    }
}

Então, nas minhas preferências XML:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <com.example.android.VersionPreference android:title="Version" />
</PreferenceScreen>
Seastland
fonte
Opa Eu devo estar pensando em Preference XML com base em outro comentário.
seastland
No entanto, vou copiar e colar sua resposta de qualquer maneira.
Mathijs Segers
13

Eu uso BuildConfig.VERSION_NAME.toString();. Qual é a diferença entre isso e obtê-lo no packageManager?

Nenhuma solução baseada em XML funcionou para mim, desculpe.

Mullazman
fonte
7
BuildConfig.VERSION_NAME já é uma sequência, não é necessário chamar toString ().
precisa saber é o seguinte
Hábito. Justo o suficiente
Mullazman 06/04
Há casos em que chamar isso em seu projeto pode obter resultados diferentes do que você esperaria. Por exemplo, se você usar um submódulo android em seu projeto e chamá-lo a partir do código do submódulo, ele fará referência à criação da configuração do submódulo que pode ter uma versão diferente. Ou, se você o chamar a partir do código do seu projeto, poderá fazer referência por engano para criar a configuração do seu submódulo e obter o mesmo resultado. Apenas tome cuidado e verifique novamente se você faz referência a um pacote adequado da configuração de compilação.
MikeL
Tente usar este guia: medium.com/@manas/…
CrandellWS
diferença é que o BuilConfig é fornecido pela Gradle, enquanto que o obtê-lo em tempo de execução é feito pelo PackageManager (OS)
Ishaan Kumar
12

Se você estiver usando o Gradle, poderá usar o arquivo build.gradle para agregar programaticamente valor aos recursos xml em tempo de compilação.

Exemplo de código extraído de: 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}"
    }
}

agora use @string/app_versionconforme necessário em XML

Ele será adicionado .debugao nome da versão conforme descrito no artigo vinculado quando estiver no modo de depuração.

CrandellWS
fonte
1
melhor resposta de sempre !!
precisa saber é o seguinte
2

Você não pode usá-lo a partir do XML.

Você precisa estender o widget que você está usando no XML e adicionar a lógica para definir o texto usando o que é mencionado na resposta de Konstantin Burov.

Macarse
fonte
Eu tinha medo disso ... Obrigado pela ajuda!
Pearsonartphoto
2
nós podemos usá-lo. por favor, verifique minha resposta. Eu estou usando-o em meu aplicativo
Arun Shankar
1

A solução mais fácil é usar BuildConfig.

Eu uso BuildConfig.VERSION_NAMEno meu aplicativo.

Você também pode usar BuildConfig.VERSION_CODEpara obter o código da versão.

cHAuHaN
fonte
-3

Tarde para o jogo, mas você pode fazê-lo sem @string/xyzusar?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"
     />
ddrscott
fonte
11
Eu uso assim :, <Preference android:title="Version" android:summary="?android:attr/versionName" ></Preference>mas mostre como ?16843292.O que há de errado?
Suge
Não tenho certeza, mas acho que isso é para APIs posteriores?
Mafro34
@PearsonArtPhoto, na verdade, onde diz isso?
perfil completo de Mafro
não funciona; Retorna o número engraçado que @Suge apontado acima
pepan
trabalho doesnot em tudo e retorna valor aleatório como anteriormente publicado
A_rmas