Cách thay đổi tên ứng dụng cho mỗi loại bản dựng Gradle


135

Tôi đang cố gắng tìm ra một cách để có thể thay đổi tên ứng dụng của ứng dụng cho mỗi loại bản dựng.

Ví dụ, tôi muốn phiên bản gỡ lỗi có <APP_NAME>-debug và phiên bản qa phải có <APP-NAME>-QA.

Tôi quen thuộc với:

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

Tuy nhiên, tôi dường như không thể tìm thấy lệnh gradle để áp dụng thay đổi ứng dụng khi trong trình khởi chạy.

Câu trả lời:


167

Nếu bởi "tên ứng dụng", bạn có ý nghĩa android:labeltrên <application>, giải pháp đơn giản nhất là phải có điểm đó tại một nguồn tài nguyên chuỗi (ví dụ android:label="@string/app_name"), sau đó có một phiên bản khác của rằng tài nguyên chuỗi trong mộtsrc/debug/ sourceset.

Bạn có thể thấy rằng trong dự án này mẫu , nơi tôi có một sự thay thế cho app_namesrc/debug/res/values/strings.xml, mà sẽ được áp dụng cho debugxây dựng. releasebản dựng sẽ sử dụng phiên bản app_nametrong src/main/.


giải pháp này có ngụ ý rằng chúng ta sẽ phải thêm một chuỗi XML thêm cho mỗi bản dịch không? điều đó có thể trở thành nỗi đau để duy trì ...
sfera

7
@sfera: Trước tiên, bạn có thể tách chuỗi này trong tệp tài nguyên của chính nó nếu bạn muốn. Thứ hai, điều này chỉ dành cho một chuỗi. Thứ ba, điều này chỉ dành cho các kiểu xây dựng mà bạn muốn thay thế chuỗi đó. Thứ tư, trừ khi bạn có một nhóm phát triển không có ngôn ngữ chung, bạn sẽ không cần dịch các releasechuỗi không .
CommonsWare

Cô lập chuỗi âm thanh như một ý tưởng tốt. Cảm ơn vì điều đó! Về releasephần không , tôi thấy rằng hơi khác một chút vì người ta cũng có thể muốn kiểm tra các vấn đề bản địa hóa trong khi cho phép các bản dựng "phát hành" và "kiểm tra" cùng tồn tại trên cùng một thiết bị. Trong trường hợp như vậy, cả hai bản dựng có thể có cùng nhãn launcher, có thể gây ra một số nhầm lẫn. Đó là những gì tôi đã cố gắng tránh.
sfera

1
@sfera: "Đó là điều tôi đã cố tránh" - vì vậy, đừng dịch chuỗi này. Thử nghiệm trên chuỗi đó dù sao cũng sẽ không hợp lệ, vì theo định nghĩa, nó không phải là chuỗi bạn muốn sử dụng trong releasechế độ. Và chỉ sử dụng tài nguyên chuỗi này cho app_name, không cho bất kỳ vai trò nào khác.
CommonsWare

3
@sfera: Bạn sẽ không bao giờ gửi ứng dụng có "AppNom-DEBUG". Bạn có thể gửi một ứng dụng với "AppNom". Do đó, việc kiểm tra "AppNom-DEBUG" là không cần thiết. Bạn chắc chắn được hoan nghênh dịch phiên bản gỡ lỗi app_name, mặc dù không cần thiết (ví dụ: bạn có nhà phát triển tiếng Pháp hoặc tiếng Đức không nói tiếng Anh và do đó cần phải dịch nó). Để thử nghiệm để xem liệu releasephiên bản app_namecông việc chưa sửa đổi , với bản dịch của nó, kiểm tra bản releasedựng hoặc tạo near-releaseloại bản dựng chỉ thêm hậu tố ID ứng dụng và để lại chuỗi.
CommonsWare

159

Bạn có thể sử dụng một cái gì đó như thế này

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

Bạn có thể sử dụng @ chuỗi / app_name trong các tệp AndroidManifest.xml.

Đảm bảo bạn xóa app_name khỏi giá trị / thư mục (không có mục nào có tên này).


Hoàn hảo khi tên ứng dụng phải được đọc dưới dạng tệp bên ngoài
Joe Maher

Có một lỗi khi xây dựng theo cách này. Việc thực thi không thành công cho nhiệm vụ ': app: mergeDebugResource' .. Tài nguyên trùng lặp: res / value / chuỗi.xml: string / app_name
user2010496

5
Nếu bạn nhận được: Có lỗi khi xây dựng theo cách này. Việc thực thi không thành công cho nhiệm vụ ': app: mergeDebugResource' .. Tài nguyên trùng lặp: res / value / String.xml: string / app_name bạn nên làm, như được viết: "Hãy chắc chắn rằng bạn xóa app_name khỏi giá trị / thư mục (không có tên này ). "
ivan.panasiuk

Tôi thích điều này bởi vì giải pháp thư mục chuỗi (giải pháp được chấp nhận ở trên) chỉ hoạt động nếu tên ứng dụng được xác định cho một bộ sản phẩm / hương vị sản phẩm cụ thể. Trong trường hợp của tôi, tôi đang thiết lập một công việc Đường ống Jenkins để tự động xây dựng các phiên bản khác nhau của ứng dụng của chúng tôi với các tên khác nhau và không phải tất cả các tên đó đều có ProductFlavors được định nghĩa cho chúng. Vì vậy, Jenkins chỉ cần cung cấp tên ứng dụng thông qua môi trường và học sinh đọc nó:resValue "string", "app_name", System.getenv("APP_NAME") ?: "MyApp"
Aphex

nếu tôi xóa app_name khỏi thư mục chuỗi thì sẽ nhận được lỗi biên dịch thời gian bị lỗi -Error: Thực thi không thành công cho nhiệm vụ ': app: processDevDebugManifest'. > Việc sáp nhập không thành công với nhiều lỗi, xem nhật ký
aj0822ArpitJoshi

55

Bạn có thể làm điều này với gradle:

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

Sau đó, trong của bạn AndroidManifest.xml:

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

Lưu ý: nó cũng hoạt động với productFlavors.


gặp lỗi -Error: Thực thi không thành công cho nhiệm vụ ': app: processDevDebugManifest'. > Việc sáp nhập không thành công với nhiều lỗi, xem nhật ký
aj0822ArpitJoshi

KHÔNG LÀM VIỆC --- buildTypes {phát hành {minifyEnables false proguardFiles getDefaultProguardFile ('proguard-android.txt'), 'proguard-rules.pro'} debug {manifestPlaceholder = [appName: "GridL Debug"]
JSONParser

44

Để hỗ trợ dịch, hãy thực hiện điều này:

1. xóa chuỗi "app_name"

2. thêm vào lớp

 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. Đặt tên ứng dụng trong Manifest là "@ string / app_name"

4. Thêm vào các giá trị chuỗi

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

Các loại khác nhau của các loại xây dựng là gì? Khác với, quản trị viên, phát hành và gỡ lỗi?
Dinesh

@DineshVG bạn có thể tự đặt sự khác biệt, ví dụ như ứng dụng khác nhau
NickUnuchek

Tôi muốn sử dụng thử nghiệm UIAutomator trong một cấu hình xây dựng khác ngoài gỡ lỗi với các quy tắc bảo vệ khác nhau. Điều đó có thể không ?
Dinesh

Đây phải là câu trả lời được chấp nhận, làm việc rất tốt cho tôi
Oleg Dater

Tôi thực sự thích cách tiếp cận này vì nó cho phép bạn thậm chí thêm một phần tùy chỉnh app_nametrong phần ProductFlavors của build.gradletệp. Một cách tiếp cận cực kỳ thuận tiện và linh hoạt khi bạn cần nó.
Egel

15

Tên ứng dụng có thể nhìn thấy được bởi người dùng và đó là lý do tại sao Google khuyến khích bạn giữ nó trong tệp String.xml của bạn. Bạn có thể định nghĩa một tệp tài nguyên chuỗi riêng có chứa các chuỗi dành riêng cho buildTypes của bạn. Có vẻ như bạn có thể có một qabuildType tùy chỉnh . Nếu điều đó không đúng, hãy bỏ qua phần qa bên dưới.

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

1
điều này đã từng làm việc cho bạn? Tôi đã ghi lại ví dụ của mình và nó không hoạt động ... stackoverflow.com/questions/26032950/
Khăn

Đây là những hương vị không phải kiểu xây dựng
Georgian Benetatos 7/1/2016

13

Chúng tôi cần một giải pháp để hỗ trợ tên ứng dụng với bản địa hóa (cho đa ngôn ngữ). Tôi đã thử nghiệm với giải pháp @Nick Unuchek, nhưng việc xây dựng không thành công (không tìm thấy @ chuỗi /). thay đổi một chút để sửa lỗi này: tệp 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 ]
        }

    }

giá trị \ String.xml:

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

</resources>

value-en \ String.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>

Một trò chơi như "Need for Speed" chẳng hạn sẽ không bao giờ được gọi là "Bedürfnis nach Geschwindigkeit" ở Đức. Trừ khi đó là bất kỳ sự lột xác nào từ một nhà phát triển đáng ngờ ...
Không thể tin được vào

Nó đang làm việc. Cảm ơn bạn rất nhiều. Tuy nhiên, trong trường hợp của tôi, tôi cần thêm 1 hơn tools:replace="android:label"trong applicationtrongAndroidManifest
Phan Văn Linh

5

Để biết giải pháp dựa trên lớp động hơn (ví dụ: đặt tên Ứng dụng cơ sở trong tên chính strings.xmlmột lần và tránh lặp lại chính mình trong mỗi kết hợp loại hương vị / kiểu xây dựng strings.xml), hãy xem câu trả lời của tôi tại đây: https://stackoverflow.com/a/32220436/1128600


2

Bạn có thể sử dụng strings.xmltrong các thư mục khác nhau, xem các giá trị chuỗi riêng biệt của Android để phát hành và gỡ lỗi bản dựng .

Vì vậy, tạo tập tin này:

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

Sau đó dán nó vào app\src\debug\res\values\app\src\release\res\values\thư mục. Thay thế "Tên ứng dụng của bạn" trong các tệp gỡ lỗi và phát hành. Xóa app_namemục từ strings.xmltrongapp\src\main\res\values\ thư mục.

Trong AndroidManifestbạn sẽ có cùng

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

Không có thay đổi nào cả. Ngay cả khi bạn đã thêm một thư viện với AndroidManifesttệp đó và strings.xml.


1

Khi tác giả yêu cầu làm điều này trong Gradle , chúng ta có thể giả sử anh ta muốn làm điều đó trong kịch bản chứ không phải trong các tệp cấu hình. Vì cả Android StudioGradle đã được cập nhật và sửa đổi rất nhiều trong năm ngoái (~ 2018), tất cả các câu trả lời khác ở trên, dường như quá mâu thuẫn. Cách dễ dàng, là thêm những điều sau vào 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"
        }
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.