Gradle derleme türüne göre uygulama adı nasıl değiştirilir


135

Gradle'daki derleme türüne göre uygulamamın uygulama adını değiştirebilmenin bir yolunu bulmaya çalışıyorum.

Örneğin, hata ayıklama sürümünün sahip olmasını <APP_NAME>-debugve qa sürümünün olmasını istiyorum <APP-NAME>-QA.

Aşinayım:

debug {
        applicationIdSuffix '.debug'
        versionNameSuffix '-DEBUG'
}

Ancak, başlatıcıdayken uygulama değişikliğini uygulamak için bir gradle komutu bulamıyorum.

Yanıtlar:


168

"Uygulama adına" yaparak, demek durumunda android:labelilgili <application>, basit çözüm bir dize kaynağı olan bu noktaya sahip olmaktır (örneğin android:label="@string/app_name"), sonra bir de bu dize kaynak sürümü farklı src/debug/sourceset.

İçeri görebilirsiniz Bu örnek proje ı için bir yedek var, app_nameiçinde src/debug/res/values/strings.xmliçin uygulanacak, debuginşa eder. releasesürümünü kullanacak oluşturur app_nameiçinde src/main/.


bu çözüm, her çeviri için fazladan bir strings.xml eklememiz gerektiği anlamına gelmez mi? sürdürmek için bir acı olabilir ...
sfera

7
@sfera: Öncelikle, isterseniz bu dizeyi kendi kaynak dosyasında izole edebilirsiniz. İkincisi, bu yalnızca bir dizi içindir. Üçüncüsü, bu yalnızca dizeyi değiştirmek istediğiniz yapı türleri içindir. Dördüncüsü, ortak dili olmayan bir geliştirme ekibiniz yoksa, releasedizge olmayanları çevirmenize gerek kalmaz .
CommonsWare

İpin izole edilmesi kulağa iyi bir fikir gibi geliyor. Bunun için teşekkürler! Olmayan releaseparçaya gelince , yerelleştirme sorunlarını da test etmek isteyebileceğinden, "yayınlama" ve "test" yapılarının aynı cihazda bir arada bulunmasına izin verebileceğinden biraz farklı görüyorum. Böyle bir durumda, her iki yapı da aynı başlatıcı etiketiyle sonuçlanabilir ve muhtemelen biraz kafa karışıklığına neden olabilir. Kaçınmaya çalıştığım şey buydu.
sfera

1
@sfera: "Kaçınmaya çalıştığım şey buydu" - bu yüzden bu dizeyi çevirmeyin. Bu dizedeki test, tanım gereği, releasemodda kullanmak istediğiniz dizge olmadığı için yine de geçersiz olacaktır . Ve bu dize kaynağını app_namebaşka herhangi bir rol için değil, yalnızca kullanın .
CommonsWare

3
@sfera: "AppNom-DEBUG" ile bir uygulamayı asla göndermeyeceksiniz. "AppNom" ile bir uygulama gönderebilirsiniz. Bu nedenle, "AppNom-DEBUG" testini yapmak gereksizdir. app_nameGerekli olmasa bile, bir hata ayıklama sürümünü çevirebilirsiniz (örneğin, İngilizce bilmeyen ve bu nedenle tercüme ettirmeniz gereken Fransızca veya Almanca geliştiricileriniz var). Testin değiştirilmemiş releasesürümünün app_nameçevirileriyle çalışıp çalışmadığını görmek için releasederlemeyi test edin veya near-releaseyalnızca uygulama kimliği sonekini ekleyen ve dizeleri yalnız bırakan bir yapı türü oluşturun .
CommonsWare

159

Bunun gibi bir şey kullanabilirsin

 buildTypes {
    debug {
        applicationIdSuffix '.debug'
        versionNameSuffix '-DEBUG'
        resValue "string", "app_name", "AppName debug"
    }
    release {
        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
        zipAlignEnabled true
        resValue "string", "app_name", "AppName"
    }
}

AndroidManifest.xml dosyalarında @ string / app_name kullanabilirsiniz .

App_name değerini değerler / klasörden kaldırdığınızdan emin olun (bu ada göre giriş yok).


Uygulama adının harici bir dosyadan okunması gerektiğinde mükemmel
Joe Maher

Bu şekilde inşa ederken bir hata aldım. Yürütme ': app: mergeDebugResources' görevi için başarısız oldu .. Yinelenen kaynaklar: res / values ​​/ strings.xml: string / app_name
user2010496

5
Şunu alırsanız: Bu şekilde oluştururken bir hata aldınız. Yürütme ': app: mergeDebugResources' görevi için başarısız oldu .. Yinelenen kaynaklar: res / values ​​/ strings.xml: string / app_name, yazdığı gibi yapmanız gereken: "app_name'i değerler / klasörden kaldırdığınızdan emin olun (bu adla giriş yok )."
ivan.panasiuk

Bunu seviyorum çünkü dizeler klasörü çözümü (yukarıdaki kabul edilen çözüm) yalnızca uygulama adı belirli bir kaynak kümesi / ürün çeşidi için tanımlanmışsa çalışır. Benim durumumda, uygulamamızın farklı sürümlerini farklı adlarla otomatik olarak oluşturmak için bir Jenkins Pipeline işi kuruyorum ve bu adların hepsinde productFlavors tanımlanmış değil. Yani Jenkins basitçe uygulama adını ortam aracılığıyla sağlar ve gradle bunu okur:resValue "string", "app_name", System.getenv("APP_NAME") ?: "MyApp"
Aphex

app_name'i dizgi klasöründen kaldırırsam ve derleme zamanı hatası alırsam -Error: ': app: processDebugManifest' görevi için yürütme başarısız oldu. > Manifest birleşmesi birden fazla hatayla başarısız oldu, günlüklere bakın
aj0822ArpitJoshi

55

Bunu gradle ile yapabilirsiniz:

android {
    buildTypes {
        release {
            manifestPlaceholders = [appName: "My Standard App Name"]
        }
        debug {
            manifestPlaceholders = [appName: "Debug"]
        }
    }
}

Sonra senin AndroidManifest.xmlyerine:

<application
    android:label="${appName}"/>
    <activity
        android:label="${appName}">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Not: ile de çalışır productFlavors.


hata alma -Error: ': app: processDebugManifest' görevi için yürütme başarısız oldu. > Manifest birleşmesi birden çok hatayla başarısız oldu, günlüklere bakın
aj0822ArpitJoshi

ÇALIŞMIYOR --- buildTypes {release {minifyEnabled false proguardFiles getDefaultProguardFile ('proguard-android.txt'), 'proguard-rules.pro'} hata ayıklama {manifestPlaceholders = [appName: "GridL Hata Ayıklama"] applicationIdSuffix ".dev1"}}
JSONParser

44

Çevirileri desteklemek için şunu yapın:

1. "uygulama_adı" dizesini kaldırın

2. derecelendirmeye ekleyin

 buildTypes {
    admin {
       resValue "string", "app_name", "@string/app_name_admin"
    }
    release {
        resValue "string", "app_name", "@string/app_name_release"
    }
    debug {
        resValue "string", "app_name", "@string/app_name_debug"
    }
}

3. Manifest'teki uygulama adını "@ string / app_name" olarak ayarlayın

4. strings.xml değerlerine ekleyin

<string name="app_name_admin">App Admin</string>
<string name="app_name_release">App  release</string>
<string name="app_name_debug">App debug</string>

Farklı yapı türleri nelerdir? Yönetici, yayınlama ve hata ayıklama dışında mı?
Dinesh

@DineshVG farkı kendiniz belirleyebilirsiniz, örneğin farklı applicationId
NickUnuchek

UIAutomator testini, farklı pro-guard kurallarıyla hata ayıklama dışında başka bir yapı yapılandırmasında kullanmak istiyorum. Mümkün mü ?
Dinesh

Bu kabul edilen cevap olmalı, benim için harika çalıştı
Oleg Dater

Gerçekten bu yaklaşım gibi o bile özel bir eklemenizi sağlar çünkü app_nameiçinde productFlavors bölümünde build.gradledosyası. İhtiyaç duyduğunuzda son derece kullanışlı ve esnek bir yaklaşım.
Egel

15

Uygulama adı kullanıcı tarafından görülebilir ve bu nedenle Google, onu strings.xml dosyanızda tutmanızı önerir. BuildTypes'ınıza özgü dizeleri içeren ayrı bir dize kaynak dosyası tanımlayabilirsiniz. Görünüşe göre özel bir qabuildType'a sahip olabilirsiniz . Bu doğru değilse, aşağıdaki qa bölümünü göz ardı edin.

└── src
    ├── debug
       └── res
           └── buildtype_strings.xml
    ├── release
       └── res
           └── buildtype_strings.xml
    └── qa
        └── res
            └── buildtype_strings.xml

1
bu senin için hiç işe yaradı mı? Örneğimi belgeledim ve çalışmıyor ... stackoverflow.com/questions/26032950/…
volkersfreunde

bunlar türler değil tatlar
Gürcü Benetatos

13

Yerelleştirme ile uygulama adını desteklemek için bir çözüme ihtiyacımız var (çoklu dil için). @Nick Unuchek çözümüyle test ettim, ancak oluşturma başarısız oldu (@ string / bulunamadı). bu hatayı düzeltmek için biraz değişiklik: build.gradle dosyası:

android {
    ext{
        APP_NAME = "@string/app_name_default"
        APP_NAME_DEV = "@string/app_name_dev"
    }

    productFlavors{

        prod{
            manifestPlaceholders = [ applicationLabel: APP_NAME]
        }

        dev{
            manifestPlaceholders = [ applicationLabel: APP_NAME_DEV ]
        }

    }

değerlerin \ strings.xml:

<resources>
    <string name="app_name_default">AAA prod</string>
    <string name="app_name_dev">AAA dev</string>

</resources>

değerler-tr \ strings.xml:

<resources>
    <string name="app_name_default">AAA prod en</string>
    <string name="app_name_dev">AAA dev en</string>

</resources>

Manifest.xml:

<application
    android:label="${applicationLabel}" >
</application>

Örneğin "Need for Speed" gibi bir oyun Almanya'da asla "Bedürfnis nach Geschwindigkeit" olarak adlandırılmayacak. Şüpheli bir geliştiriciden herhangi bir soygun olmadığı sürece ...
The Incredible Jan

Çalışıyor. Çok teşekkür ederim. Ancak, benim durumumda, ben daha 1 eklemeniz gerekir tools:replace="android:label"de applicationiçindeAndroidManifest
Phan Van Linh


2

strings.xmlFarklı klasörlerde kullanabilirsiniz , sürüm ve hata ayıklama yapıları için Android ayrı dize değerlerine bakın .

Öyleyse, şu dosyayı oluşturun:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Your app name</string>
</resources>

Ardından app\src\debug\res\values\ve app\src\release\res\values\klasörlere yapıştırın . Hata ayıklama ve yayın dosyalarında "Uygulamanızın adını" değiştirin. Kaldır app_nameöğeyi strings.xmliçinde app\src\main\res\values\klasöründe.

İçinde AndroidManifestaynısına sahip olacaksın

<application
    android:label="@string/app_name"
    ...

Hiç değişiklik yok. Dosyasıyla bir kitaplık ekleseniz bile AndroidManifestve strings.xml.


1

Yazar bunu Gradle'da yapmak istediğinden, bunu yapılandırma dosyalarında değil komut dosyasında yapmak istediğini varsayabiliriz. Her iki yana Android Studio ve Gradle ağır güncel ve son bir yıl içinde modifiye edilmiş (~ 2018) Yukarıdaki tüm diğer cevaplar, aşırı çarpılmış görünüyor. Kolay kolay yol, aşağıdakileri eklemektir app/build.gradle:

android {
    ...
    buildTypes {
        ...
        // Rename/Set default APK name prefix (app*.apk --> AwesomeApp*.apk)
        android.applicationVariants.all { variant ->
            variant.outputs.all { output ->
                def appName = "AwesomeApp"
                outputFileName = appName+"-${output.baseName}-${variant.versionName}.apk"
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.