คุณจะรับหมายเลขเวอร์ชันได้จากตัวแปร XML ของแอพ (เค้าโครง) อย่างไร


184

ฉันต้องการมีวิธีการอ้างอิงหมายเลขรุ่นรายการของโครงการในส่วนหลักของรหัส สิ่งที่ฉันทำมาจนถึงตอนนี้คือการเชื่อมโยงหมายเลขเวอร์ชันในไฟล์ String XML ไปยังรายการ (@ string / Version) สิ่งที่ฉันอยากทำคือทำอย่างอื่นเชื่อมโยงตัวแปร XML สตริงกับเวอร์ชันในไฟล์ Manifest เหตุผล? ฉันต้องการจะเปลี่ยนหมายเลขเวอร์ชั่นในไฟล์เดียวไฟล์เดียว มีวิธีการทำเช่นนี้? ขอบคุณ!


17
นี่ไม่ใช่สิ่งที่ซ้ำกัน คำถามที่ถามถามว่าจะทำอย่างไรใน CODE ฉันถามใน XML โครงสร้างที่แตกต่างกันสองอย่างในการเขียนโปรแกรม Android ...
PearsonArtPhoto

คำตอบ:


367

ผมเชื่อว่าได้รับการตอบอยู่แล้วนี่

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

หรือ

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

8
เกือบ แต่ไม่มาก ... สิ่งที่ฉันต้องการทำคืออ้างอิงไปยังโค้ด XML แต่ดูเหมือนว่ามันอาจเป็นไปไม่ได้ดังนั้น ...
PearsonArtPhoto

ขอบคุณมาก!!! ฉันได้รับการมองหาทุกที่สำหรับนี้:String versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
Aaron Klap

1
@Shubh ฉันไม่คิดอย่างนั้น
Konstantin Burov

3
เพิ่ม BuildConfig.VERSION_NAME ในคำตอบของคุณสำหรับการไล่ระดับสี
jobbert

102

ไม่มีวิธีในการรับรุ่นโดยตรง แต่มีสอง work-arounds ที่สามารถทำได้

  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หรืออะไรทำนองนั้น


14
โน้ตตัวน้อยต่อ 1: มันใช้งานได้ แต่ฉันคิดว่ามันหมดกำลังใจเพราะฉันได้รับคำเตือนบอกฉันThe android:versionName cannot be a resource url, it must be a literal string
Griddo

1
สิ่งที่ฉันทำคือปล่อยให้ชื่อรุ่นรายการไม่มีการแตะต้อง (แต่อัปเดตทุกครั้งที่มีรีลีสใหม่) และใช้ string.xml เพื่อเก็บค่าที่ฉันจะใช้ข้ามแอพ
numediaweb

1
สำหรับAndroidStudioรายการversionNameจะถูกแทนที่ด้วยชุดที่อยู่ในbuild.gradleไฟล์
Adrian C.

66

คุณสามารถใช้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>


3
สิ่งนี้ดีกว่ารูปแบบการเขียนโปรแกรม
สารสื่อประสาท

2
ทางออกที่ยอดเยี่ยม ขอบคุณมาก
Samik Bandyopadhyay

2
ฉันใช้สิ่งล่าสุดและยังคงใช้ได้สำหรับฉัน ฉันใช้ตัวแปรนี้และตัวแปรอื่น ๆ เช่นนี้ @ k2col คุณเกิดข้อผิดพลาดในขณะรวบรวมอะไร โปรดโพสต์โค้ด gradle ของคุณ
Arun Shankar

3
นี่ควรเป็นคำตอบที่ดีที่สุด
แม่บ้าน

15

ฉันแก้ไขปัญหานี้โดยขยายคลาสการตั้งค่า

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>

อุ่ย ฉันต้องคิด Preference XML ตามความคิดเห็นอื่น
seastland

อย่างไรก็ตามฉันจะคัดลอกและวางคำตอบของเขาต่อไป
Mathijs Segers

13

BuildConfig.VERSION_NAME.toString();ฉันใช้ อะไรคือความแตกต่างระหว่างสิ่งนั้นกับการได้รับจาก packageManager?

ขออภัยที่ใช้ XML ไม่ทำงาน


7
BuildConfig.VERSION_NAME เป็นสตริงอยู่แล้วไม่จำเป็นต้องโทรไปที่ String ()
Makotosan

นิสัย. ยุติธรรมเพียงพอ
Mullazman

มีหลายกรณีที่เรียกสิ่งนี้ในโครงการของคุณอาจได้รับผลลัพธ์ที่แตกต่างจากสิ่งที่คุณคาดหวัง ตัวอย่างเช่นถ้าคุณใช้ android submodule ในโครงการของคุณและคุณเรียกมันจากรหัสของ submodule มันจะอ้างอิงถึงการสร้าง config ของ submodule ซึ่งอาจมีเวอร์ชั่นต่างกัน หรือถ้าคุณเรียกมันว่าจากรหัสของโครงการคุณอาจอ้างอิงโดยไม่ตั้งใจเพื่อสร้าง config ของ submodule ของคุณและรับผลลัพธ์เดียวกัน เพียงแค่ระมัดระวังและตรวจสอบอีกครั้งว่าคุณอ้างอิงถึงแพ็คเกจที่เหมาะสมของบิลด์บิลด์
MikeL

ลองใช้คู่มือนี้: medium.com/@manas/ ......
CrandellWS

ความแตกต่างคือ BuilConfig ให้บริการโดย Gradle ในขณะที่รับมันที่รันไทม์คือโดย PackageManager (OS)
Ishaan Kumar

12

หากคุณกำลังใช้ 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ชื่อรุ่นตามที่อธิบายในบทความที่เชื่อมโยงเมื่ออยู่ในโหมดแก้ไขข้อบกพร่อง


1
คำตอบที่ดีที่สุดที่เคย !!
Raheel Hasan

2

คุณไม่สามารถใช้งานได้จาก XML

คุณต้องขยายวิดเจ็ตที่คุณใช้ใน XML และเพิ่มตรรกะเพื่อตั้งค่าข้อความโดยใช้สิ่งที่กล่าวถึงในคำตอบของ Konstantin Burov


ฉันกลัวว่า ... ขอบคุณสำหรับความช่วยเหลือ!
PearsonArtPhoto

2
เราสามารถใช้มัน โปรดตรวจสอบคำตอบของฉัน ฉันใช้มันในแอพของฉัน
อรุณ Shankar

1

BuildConfigทางออกที่ง่ายที่สุดคือการใช้งาน

ฉันใช้BuildConfig.VERSION_NAMEในแอปพลิเคชันของฉัน

คุณสามารถใช้BuildConfig.VERSION_CODEเพื่อรับรหัสเวอร์ชัน


-3

มาถึงช่วงท้ายเกม แต่คุณสามารถทำได้โดยไม่ต้อง@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"
     />

11
ฉันใช้สิ่งนี้: <Preference android:title="Version" android:summary="?android:attr/versionName" ></Preference>แต่แสดงเป็น?16843292. มีอะไรผิดปกติ?
Suge

ฉันไม่แน่ใจ แต่คิดว่านี่เป็นของ API ในภายหลังหรือไม่
Mafro34

@PearsonArtPhoto จริงๆแล้วมันพูดว่าอะไร?
Mafro34

ไม่ทำงาน ส่งกลับตัวเลขตลกที่ @Suge ชี้ไปที่ด้านบน
มกราคม

ไม่ทำงานเลยและส่งกลับค่าสุ่มตามที่โพสต์ก่อนหน้านี้
A_rmas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.