Wie können Sie die Manifest-Versionsnummer aus den XML-Variablen der App (Layout) abrufen?

184

Ich möchte eine Möglichkeit haben, auf die Manifest-Versionsnummer des Projekts im Hauptteil des Codes zu verweisen. Bisher habe ich die Versionsnummer in einer String-XML-Datei mit dem Manifest (@ string / Version) verknüpft. Was ich tun möchte, ist es umgekehrt zu machen, eine String-XML-Variable mit der Version im Manifest zu verknüpfen. Der Grund? Ich möchte nur die Versionsnummer an einem Ort ändern müssen, der Manifestdatei. Gibt es eine Möglichkeit, dies zu tun? Vielen Dank!

PearsonArtPhoto
quelle
17
Dies ist KEIN Duplikat. Die fragliche Frage fragt, wie man dasselbe in CODE macht, das ich in XML stelle. Zwei sehr unterschiedliche Konstrukte in der Android-Programmierung ...
PearsonArtPhoto

Antworten:

367

Ich glaube , dass schon beantwortet wurde hier .

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

ODER

int versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
Konstantin Burov
quelle
8
Fast, aber nicht ganz ... Ich würde gerne auf einen XML-Code verweisen, aber es sieht so aus, als wäre das möglicherweise nicht möglich, also ...
PearsonArtPhoto
Ich danke dir sehr!!! Ich habe überall danach gesucht:String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
Aaron Klap
1
@ Shubh Ich glaube nicht.
Konstantin
3
Fügen Sie BuildConfig.VERSION_NAME zu Ihrer Antwort für Gradle Fokes hinzu.
Jobbert
102

Es gibt keine Möglichkeit, die Version direkt herauszubringen, aber es gibt zwei Problemumgehungen, die durchgeführt werden könnten.

  1. Die Version kann in einer Ressourcenzeichenfolge gespeichert und in das Manifest eingefügt werden durch:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.somepackage"
         android:versionName="@string/version" android:versionCode="20">
  2. Man könnte eine benutzerdefinierte Ansicht erstellen und sie in das XML einfügen. Die Ansicht würde dies verwenden, um den Namen zuzuweisen:

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

Jede dieser Lösungen würde es ermöglichen, den Versionsnamen in XML zu platzieren. Leider gibt es keine schöne einfache Lösung, so android.R.string.versionoder so.

PearsonArtPhoto
quelle
14
eine kleine Anmerkung zu 1.: es funktioniert, aber ich denke, es ist entmutigt, da ich eine Warnung bekomme, die mir sagtThe android:versionName cannot be a resource url, it must be a literal string
Griddo
1
Ich habe den Namen der Manifestversion unberührt gelassen (aber bei jeder neuen Version aktualisiert) und den Wert, den ich in der gesamten App verwenden werde, in der Datei string.xml gespeichert.
Numediaweb
1
Denn AndroidStudiodas Manifest versionNamewird von dem in der build.gradleDatei festgelegten überschrieben
Adrian C.
66

Sie können die versionNamein XML-Ressourcen verwenden, z. B. Aktivitätslayouts. Erstellen Sie zunächst eine Zeichenfolgenressource im app/build.gradlemit dem folgenden Snippet im androidKnoten:

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

Der gesamte build.gradleDateiinhalt kann also folgendermaßen aussehen:

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

Dann können Sie @string/versionNamein der XML verwenden. Android Studio markiert es rot, aber die App wird ohne Probleme kompiliert. Dies kann beispielsweise folgendermaßen verwendet werden in 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
quelle
3
@ DenisGL michiganlabs.com/…
Arun Shankar
3
Das ist besser als programmatischer Stil.
Neurotransmitter
2
Wunderbare Lösung. Danke vielmals.
Samik Bandyopadhyay
2
Ich benutze die neueste und funktioniert immer noch für mich. Ich benutze diese und einige andere Variablen wie diese. @ k2col Welchen Fehler bekommst du beim Kompilieren? Pls post ur gradle code
Arun Shankar
3
Dies sollte als die beste Antwort angesehen werden.
Pepan
15

Ich habe dieses Problem durch Erweitern der Voreinstellungsklasse gelöst.

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);
        }
    }
}

Dann in meinen Einstellungen XML:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <com.example.android.VersionPreference android:title="Version" />
</PreferenceScreen>
Seeland
quelle
Hoppla. Ich muss Preference XML basierend auf einem anderen Kommentar gedacht haben.
Seastland
Trotzdem werde ich seine Antwort trotzdem einfach kopieren und einfügen.
Mathijs Segers
13

Ich benutze BuildConfig.VERSION_NAME.toString();. Was ist der Unterschied zwischen dem und dem Abrufen vom packageManager?

Für mich haben leider keine XML-basierten Lösungen funktioniert.

Mullazman
quelle
7
BuildConfig.VERSION_NAME ist bereits eine Zeichenfolge, für die kein toString () aufgerufen werden muss.
Makotosan
Gewohnheit. Fair genug
Mullazman
Es gibt Fälle, in denen das Aufrufen in Ihrem Projekt zu einem anderen Ergebnis führt als erwartet. Wenn Sie beispielsweise ein Android-Submodul in Ihrem Projekt verwenden und es aus dem Code des Submoduls aufrufen, wird auf die Build-Konfiguration des Submoduls verwiesen, das möglicherweise eine andere Version hat. Oder wenn Sie es aus dem Code Ihres Projekts aufrufen, können Sie versehentlich darauf verweisen, die Konfiguration Ihres Submoduls zu erstellen und das gleiche Ergebnis zu erhalten. Seien Sie vorsichtig und überprüfen Sie, ob Sie auf ein geeignetes Paket der Build-Konfiguration verweisen.
MikeL
Versuchen Sie es mit diesem Handbuch: medium.com/@manas/…
CrandellWS
Der Unterschied besteht darin, dass BuilConfig von Gradle bereitgestellt wird, während es zur Laufzeit von PackageManager (OS)
Ishaan Kumar
12

Wenn Sie Gradle verwenden, können Sie die Datei build.gradle verwenden, um den XML-Ressourcen beim Kompilieren programmgesteuert einen Wert hinzuzufügen.

Beispielcode extrahiert aus: 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}"
    }
}

jetzt benutzen @string/app_version nach Bedarf in XML verwenden

Im .debugDebug-Modus wird der Versionsname wie im verlinkten Artikel beschrieben hinzugefügt .

CrandellWS
quelle
1
beste Antwort aller Zeiten !!
Raheel Hasan
2

Sie können es nicht aus dem XML verwenden.

Sie müssen das Widget, das Sie in XML verwenden, erweitern und die Logik hinzufügen, um den Text anhand der Angaben in der Antwort von Konstantin Burov festzulegen.

Macarse
quelle
Ich hatte Angst davor ... Danke für die Hilfe!
PearsonArtPhoto
2
wir können es benutzen. Bitte überprüfen Sie meine Antwort. Ich benutze es in meiner App
Arun Shankar
1

Die einfachste Lösung ist die Verwendung BuildConfig.

Ich benutze BuildConfig.VERSION_NAMEin meiner Anwendung.

Sie können auch BuildConfig.VERSION_CODEden Versionscode abrufen.

cHAuHaN
quelle
-3

Spät zum Spiel, aber Sie können es ohne @string/xyzmit tun?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
quelle
11
Ich benutze so : <Preference android:title="Version" android:summary="?android:attr/versionName" ></Preference>, aber zeige als ?16843292.Was ist falsch?
Suge
Ich bin mir nicht sicher, aber denke, das ist für spätere APIs?
Mafro34
@PearsonArtPhoto eigentlich, wo steht das?
Mafro34
funktioniert nicht; gibt eine lustige Zahl zurück, auf die @Suge oben hingewiesen hat
pepan
funktioniert überhaupt nicht und gibt einen zufälligen Wert zurück, wie zuvor veröffentlicht
A_rmas