Cara mengubah nama aplikasi per tipe build Gradle

135

Saya mencoba mencari cara untuk dapat mengubah nama aplikasi aplikasi saya per tipe build secara gradle.

Sebagai contoh, saya ingin memiliki versi debug untuk memiliki <APP_NAME>-debugdan versi qa untuk dimiliki <APP-NAME>-QA.

Saya kenal dengan:

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

Namun, sepertinya saya tidak dapat menemukan perintah gradle untuk menerapkan perubahan aplikasi saat berada di peluncur.

Andre Perkins
sumber

Jawaban:

167

Jika dengan "nama aplikasi", Anda berarti android:labelpada <application>, solusi yang paling sederhana adalah memiliki titik itu pada sumber daya string (misalnya, android:label="@string/app_name"), kemudian memiliki versi yang berbeda dari yang sumber daya string dalam src/debug/sourceset.

Anda dapat melihat bahwa dalam proyek ini sampel , di mana saya memiliki pengganti untuk app_namedi src/debug/res/values/strings.xml, yang akan diterapkan untuk debugmembangun. releasebuild akan menggunakan versi app_namein src/main/.

CommonsWare
sumber
bukankah solusi ini menyiratkan bahwa kita harus menambahkan strings.xml tambahan untuk setiap terjemahan? itu bisa menjadi sakit untuk mempertahankan ...
sfera
7
@sfera: Pertama, Anda dapat mengisolasi string ini dalam file sumber dayanya sendiri jika Anda mau. Kedua, ini hanya untuk satu string. Ketiga, ini hanya untuk tipe build di mana Anda ingin mengganti string itu. Keempat, kecuali jika Anda memiliki tim pengembangan tanpa bahasa yang sama, Anda tidak perlu menerjemahkan non- releasestring.
CommonsWare
Mengisolasi senar terdengar seperti ide yang bagus. Terima kasih untuk itu! Sedangkan untuk non- releasebagian, saya melihat bahwa sedikit berbeda karena orang mungkin ingin juga menguji untuk masalah pelokalan sementara memungkinkan "rilis" dan "tes" dibangun untuk hidup berdampingan pada perangkat yang sama. Dalam kasus seperti itu, kedua build mungkin berakhir dengan label launcher yang sama, mungkin menyebabkan kebingungan. Itulah yang saya coba hindari.
sfera
1
@sfera: "Itulah yang saya coba hindari" - jadi, jangan menerjemahkan string yang satu ini. Tes pada string itu akan tetap tidak valid, karena menurut definisi, itu bukan string yang ingin Anda gunakan dalam releasemode. Dan hanya gunakan sumber daya string ini untuk app_name, bukan untuk peran lain.
CommonsWare
3
@sfera: Anda tidak akan pernah mengirimkan aplikasi dengan "AppNom-DEBUG". Anda mungkin mengirim aplikasi dengan "AppNom". Menguji "AppNom-DEBUG", oleh karena itu, tidak perlu. Anda tentu saja dapat menerjemahkan versi debug app_name, walaupun itu tidak perlu (misalnya, Anda memiliki pengembang Perancis atau Jerman yang tidak berbicara bahasa Inggris dan karenanya perlu diterjemahkan). Agar pengujian dapat melihat apakah releaseversi app_namekarya yang tidak dimodifikasi , dengan terjemahannya, uji coba releasepembuatannya, atau buat near-releasejenis pembuatan yang hanya menambahkan akhiran ID aplikasi dan membiarkan senarnya.
CommonsWare
159

Anda dapat menggunakan sesuatu seperti ini

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

Anda dapat menggunakan @ string / app_name di file AndroidManifest.xml.

Pastikan Anda menghapus app_name dari nilai / folder (tidak ada entri dengan nama ini).

irscomp
sumber
Sempurna ketika nama aplikasi harus dibaca dari file eksternal
Joe Maher
Mendapat kesalahan saat membangun dengan cara ini. Eksekusi gagal untuk tugas ': app: mergeDebugResources' .. Sumber daya rangkap: res / values ​​/ strings.xml: string / app_name
user2010496
5
Jika Anda mendapat: Mendapat kesalahan saat membangun dengan cara ini. Eksekusi gagal untuk tugas ': app: mergeDebugResources' .. Sumber rangkap: res / values ​​/ strings.xml: string / app_name yang harus Anda lakukan, seperti yang tertulis: "Pastikan Anda menghapus app_name dari nilai / folder (tidak ada entri dengan nama ini ). "
ivan.panasiuk
Saya suka ini karena solusi folder string (solusi yang diterima, di atas) hanya berfungsi jika nama aplikasi didefinisikan untuk sumber set / rasa produk tertentu. Dalam kasus saya, saya sedang menyiapkan pekerjaan Jenkins Pipeline untuk membuat versi aplikasi kami yang berbeda secara otomatis dengan nama yang berbeda, dan tidak semua nama itu memiliki definisi ProductFlavor untuk mereka. Jadi Jenkins hanya memasok nama aplikasi melalui lingkungan, dan gradle membacanya:resValue "string", "app_name", System.getenv("APP_NAME") ?: "MyApp"
Aphex
jika saya menghapus app_name dari folder string kemudian mendapatkan waktu kompilasi kesalahan mendapatkan kesalahan -Error: Eksekusi gagal untuk tugas ': app: processDevDebugManifest'. > Manifes merger gagal dengan banyak kesalahan, lihat log
aj0822ArpitJoshi
55

Anda dapat melakukan ini dengan gradle:

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

Kemudian di AndroidManifest.xmlput Anda :

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

Catatan: ini juga berfungsi dengan productFlavors.

Albert Vila Calvo
sumber
mendapatkan kesalahan -Error: Eksekusi gagal untuk tugas ': app: processDevDebugManifest'. > Manifest merger gagal dengan banyak kesalahan, lihat log
aj0822ArpitJoshi
TIDAK BEKERJA --- buildTypes {release {minifyEnabled proguardFiles palsu getDefaultProguardFile ('proguard-android.txt'), 'proguard-rules.pro'} debug {manifestPlaceholder = [appName: "GridL Debug"] applicationIdSuffix ".dev1"}}
JSONParser
44

Untuk mendukung terjemahan, buat ini:

1. hapus string "app_name"

2. tambahkan ke gradle

 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. Tetapkan nama aplikasi di Manifest sebagai "@ string / app_name"

4. Tambahkan ke nilai strings.xml

<string name="app_name_admin">App Admin</string>
<string name="app_name_release">App  release</string>
<string name="app_name_debug">App debug</string>
NickUnuchek
sumber
Apa saja jenis tipe bangunan yang berbeda? Selain, admin, lepaskan dan debug?
Dinesh
@DineshVG Anda dapat mengatur perbedaan sendiri, misalnya applicationId yang berbeda
NickUnuchek
Saya ingin menggunakan tes UIAutomator di konfigurasi build lain selain debug dengan aturan pro-guard yang berbeda. Apakah itu mungkin ?
Dinesh
Ini harus menjadi jawaban yang diterima, bekerja sangat baik untuk saya
Oleg Dater
Saya sangat suka pendekatan ini karena memungkinkan Anda bahkan untuk menambahkan kustom app_namedi bagian file productFlavoursbuild.gradle . Pendekatan yang sangat nyaman dan fleksibel saat Anda membutuhkannya.
Egel
15

Nama aplikasi terlihat oleh pengguna, dan itulah sebabnya Google mendorong Anda untuk menyimpannya di file strings.xml Anda. Anda bisa menentukan file sumber string terpisah yang berisi string yang spesifik untuk buildTypes Anda. Sepertinya Anda mungkin memiliki qabuildType khusus . Jika itu tidak benar, abaikan bagian qa di bawah ini.

└── src
    ├── debug
       └── res
           └── buildtype_strings.xml
    ├── release
       └── res
           └── buildtype_strings.xml
    └── qa
        └── res
            └── buildtype_strings.xml
Krylez
sumber
1
apakah ini pernah berhasil untukmu? Saya mendokumentasikan contoh saya, dan itu tidak berfungsi ... stackoverflow.com/questions/26032950/…
volkersfreunde
ini adalah jenis rasa bukan jenis
Georgia Benetatos
13

Kami membutuhkan solusi untuk mendukung nama aplikasi dengan pelokalan (untuk multi bahasa). Saya telah menguji dengan solusi @Nick Unuchek, tetapi bangunan gagal (tidak ditemukan @ string /). sedikit perubahan untuk memperbaiki bug ini: file build.gradle:

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

    }

values ​​\ strings.xml:

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

</resources>

values-en \ 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>
HungNM2
sumber
Gim seperti "Need for Speed" misalnya tidak akan pernah disebut "Bedürfnis nach Geschwindigkeit" di Jerman. Kecuali jika itu adalah rip-off dari pengembang yang meragukan ...
The Jan
Itu bekerja. Terima kasih banyak. Namun, dalam kasus saya, saya perlu menambahkan 1 tools:replace="android:label"di applicationdalamAndroidManifest
Phan Van Linh
5

Untuk solusi berbasis gradle yang lebih dinamis (mis. Tetapkan nama Aplikasi dasar di utama strings.xmlsekali, dan hindari mengulangi diri Anda sendiri dalam setiap kombinasi jenis rasa / bahan bangunan strings.xml), lihat jawaban saya di sini: https://stackoverflow.com/a/32220436/1128600

Steffen Funke
sumber
2

Anda dapat menggunakan strings.xmldi folder yang berbeda, lihat Android nilai string terpisah untuk rilis dan debug build .

Jadi, buat file ini:

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

Kemudian tempel ke app\src\debug\res\values\dan app\src\release\res\values\folder. Ganti "Nama aplikasi Anda" di debug dan lepaskan file. Hapus app_nameitem dari strings.xmldalamapp\src\main\res\values\ folder.

Di dalam AndroidManifestkamu akan memiliki yang sama

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

Tidak ada perubahan sama sekali. Bahkan jika Anda menambahkan perpustakaan dengan AndroidManifestfile itu dan strings.xml.

CoolMind
sumber
1

Ketika penulis meminta untuk melakukan ini di Gradle , kita dapat mengasumsikan dia ingin melakukannya dalam skrip dan bukan pada file konfigurasi. Karena baik Android Studio maupun Gradle telah banyak diperbarui dan dimodifikasi pada tahun lalu (~ 2018), semua jawaban lain di atas, tampaknya terlalu berbelit - belit . Cara mudah-peasy, adalah menambahkan berikut ini ke Anda 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"
        }
    }
}
not2qubit
sumber