Jak zmienić nazwę aplikacji na typ kompilacji Gradle

135

Próbuję znaleźć sposób, aby zmienić nazwę mojej aplikacji na typ kompilacji w gradle.

Na przykład chciałbym mieć wersję debugowania <APP_NAME>-debugi wersję QA <APP-NAME>-QA.

Jestem zaznajomiony z:

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

Jednak nie mogę znaleźć polecenia gradle, aby zastosować zmianę aplikacji w programie uruchamiającym.

Andre Perkins
źródło

Odpowiedzi:

167

Jeśli przez „nazwę aplikacji” masz android:labelna myśli włączone <application>, najprostszym rozwiązaniem jest umieszczenie tego punktu w zasobie ciągu (np. android:label="@string/app_name"), A następnie posiadanie innej wersji tego zasobu ciągu wsrc/debug/ zestawie źródeł.

Widać to w tym przykładowym projekcie , w którym mam zamiennik dla app_namew src/debug/res/values/strings.xml, który zostanie zastosowany do debugkompilacji. releasekompilacje będą używać wersji app_namein src/main/.

CommonsWare
źródło
czy to rozwiązanie nie oznaczałoby, że musielibyśmy dodać dodatkowy ciąg string.xml do każdego tłumaczenia? to może być trudne do utrzymania ...
sfera
7
@sfera: Po pierwsze, możesz odizolować ten ciąg w swoim własnym pliku zasobów, jeśli chcesz. Po drugie, dotyczy to tylko jednego ciągu. Po trzecie, dotyczy to tylko typów kompilacji, w których chcesz zamienić ten ciąg. Po czwarte, gdybyś nie miał zespołu programistów bez wspólnego języka, nie musiałbyś tłumaczyć releaseznaków niebędących ciągami znaków.
CommonsWare,
Izolowanie struny wydaje się dobrym pomysłem. Dziękuję za to! Jeśli chodzi o releaseczęść niezwiązaną , widzę to nieco inaczej, ponieważ można również chcieć przetestować pod kątem problemów z lokalizacją, jednocześnie zezwalając na współistnienie kompilacji „wydanie” i „test” na tym samym urządzeniu. W takim przypadku obie kompilacje mogą skończyć z tą samą etykietą programu uruchamiającego, prawdopodobnie powodując pewne zamieszanie. Właśnie tego starałem się uniknąć.
sfera
1
@sfera: "Właśnie tego starałem się uniknąć" - więc nie tłumacz tego jednego ciągu. Test na tym łańcuchu i tak będzie nieprawidłowy, ponieważ z definicji nie jest to ciąg, którego chcesz używać w releasetrybie. I używaj tego zasobu ciągu tylko app_namedla żadnej innej roli, a nie.
CommonsWare,
3
@sfera: Nigdy nie wyślesz aplikacji z „AppNom-DEBUG”. Możesz wysłać aplikację z „AppNom”. Dlatego testowanie „AppNom-DEBUG” nie jest konieczne. Z pewnością możesz przetłumaczyć wersję do debugowania app_name, nawet jeśli nie jest to konieczne (np. Masz francuskich lub niemieckich programistów, którzy nie mówią po angielsku i dlatego muszą ją przetłumaczyć). Do testowania, aby sprawdzić, czy niezmodyfikowana releasewersja app_namedziała wraz z tłumaczeniami, przetestuj releasekompilację lub utwórz near-releasetyp kompilacji, który po prostu dodaje sufiks identyfikatora aplikacji i pozostawia ciągi w spokoju.
CommonsWare,
159

Możesz użyć czegoś takiego

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

Możesz użyć @ string / app_name w plikach AndroidManifest.xml.

Upewnij się, że usunąłeś app_name z wartości / folderu (brak wpisu o tej nazwie).

irscomp
źródło
Idealne, gdy nazwę aplikacji trzeba odczytać z zewnętrznego pliku
Joe Maher
Podczas budowania w ten sposób wystąpił błąd. Wykonanie nie powiodło się dla zadania „: app: mergeDebugResources” .. Zduplikowane zasoby: res / values ​​/ strings.xml: string /
nazwa_aplikacji
5
Jeśli otrzymasz: Podczas tworzenia w ten sposób wystąpił błąd. Wykonanie nie powiodło się dla zadania „: app: mergeDebugResources” .. Zduplikowane zasoby: res / values ​​/ strings.xml: string / nazwa_aplikacji, które należy zrobić, tak jak napisano: „Upewnij się, że usunąłeś app_name z wartości / folderu (brak wpisu o tej nazwie ). ”
ivan.panasiuk,
Podoba mi się to, ponieważ rozwiązanie z folderem ciągów (zaakceptowane rozwiązanie powyżej) działa tylko wtedy, gdy nazwa aplikacji jest zdefiniowana dla określonego zestawu źródłowego / smaku produktu. W moim przypadku konfiguruję zadanie Jenkins Pipeline, aby automatycznie budować różne wersje naszej aplikacji z różnymi nazwami, a nie wszystkie te nazwy mają zdefiniowane dla nich productFlavors. Więc Jenkins po prostu dostarcza nazwę aplikacji za pośrednictwem środowiska, a gradle czyta ją:resValue "string", "app_name", System.getenv("APP_NAME") ?: "MyApp"
Aphex
jeśli usunąłem app_name z folderu string, wtedy pojawia się błąd podczas kompilacji i pojawia się błąd -Error: wykonanie nie powiodło się dla zadania ': app: processDevDebugManifest'. > Manifest fuzja nie powiodło się z
powodu
55

Możesz to zrobić za pomocą gradle:

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

Następnie w twoim AndroidManifest.xml miejscu:

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

Uwaga: działa również z plikami productFlavors.

Albert Vila Calvo
źródło
uzyskiwanie błędu -Error: wykonanie nie powiodło się dla zadania „: app: processDevDebugManifest”. > Manifest fuzja nie powiodło się z
powodu
NIE DZIAŁA --- buildTypes {release {minifyEnabled false proguardFiles getDefaultProguardFile ('proguard-android.txt'), 'proguard-rules.pro'} debug {manifestPlaceholder = [appName: "GridL Debug"] applicationIdSuffix ".dev1"}}
JSONParser
44

Aby wspierać tłumaczenia, wykonaj następujące czynności:

1. usuń ciąg „nazwa_aplikacji”

2. dodać do 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. Ustaw nazwę aplikacji w manifeście jako „@ string / app_name”

4. Dodaj do wartości 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
źródło
Jakie są rodzaje typów kompilacji? Inne niż admin, wydanie i debugowanie?
Dinesh
@DineshVG możesz samodzielnie ustawić różnicę, na przykład inny applicationId
NickUnuchek
Chcę użyć testu UIAutomator w innej konfiguracji kompilacji innej niż debugowanie z różnymi regułami ochrony. Czy to jest możliwe ?
Dinesh
To powinna być akceptowana odpowiedź, działała świetnie
Oleg Dater
Bardzo podoba mi się takie podejście, ponieważ pozwala nawet dodać zwyczaj app_namew productFlavors części build.gradlepliku. Niezwykle wygodne i elastyczne podejście, gdy tego potrzebujesz.
Egel
15

Nazwa aplikacji jest widoczna dla użytkownika i dlatego Google zachęca do jej przechowywania w pliku strings.xml. Możesz zdefiniować oddzielny plik zasobów ciągu, który zawiera ciągi, które są specyficzne dla twojego buildTypes. Wygląda na to, że możesz mieć niestandardowy qabuildType. Jeśli to nieprawda, zignoruj ​​poniższą część qa.

└── src
    ├── debug
       └── res
           └── buildtype_strings.xml
    ├── release
       └── res
           └── buildtype_strings.xml
    └── qa
        └── res
            └── buildtype_strings.xml
Krylez
źródło
1
czy to kiedykolwiek działało dla ciebie? Udokumentowałem mój przykład i nie działa ... stackoverflow.com/questions/26032950/
volkersfreunde
to są smaki, a nie typy
budowli
13

Potrzebujemy rozwiązania obsługującego nazwę aplikacji z lokalizacją (dla wielu języków). Testowałem z rozwiązaniem @Nick Unuchek, ale kompilacja się nie powiodła (nie znaleziono @ string /). mała zmiana, aby naprawić ten błąd: plik 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 ]
        }

    }

wartości \ 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
źródło
Na przykład gra taka jak „Need for Speed” nigdy nie będzie nazywana w Niemczech „Bedürfnis nach Geschwindigkeit”. Chyba że jest to zdzierstwo od wątpliwego programisty ...
Niesamowity styczeń
To działa. Dziękuję bardzo. Jednak w moim przypadku, muszę dodać 1 tools:replace="android:label"w applicationwAndroidManifest
Phan Van Linh
5

Aby uzyskać bardziej dynamiczne rozwiązanie oparte na gradle (np. Ustaw strings.xmlraz nazwę aplikacji bazowej w main i unikaj powtarzania się w każdej kombinacji smaku / kompilacji strings.xml), zobacz moją odpowiedź tutaj: https://stackoverflow.com/a/32220436/1128600

Steffen Funke
źródło
2

Możesz używać strings.xmlw różnych folderach, zobacz wartości oddzielnych ciągów dla systemu Android dla kompilacji do wydania i debugowania .

Więc utwórz ten plik:

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

Następnie wklej go do folderów app\src\debug\res\values\i app\src\release\res\values\. Zastąp tekst „Nazwa Twojej aplikacji” w plikach debugowania i zwalniania. Usuń app_nameelement z strings.xmlwapp\src\main\res\values\ folderze.

W AndroidManifestbędziesz miał to samo

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

Żadnych zmian. Nawet jeśli dodałeś bibliotekę z jej AndroidManifestplikiem i strings.xml.

CoolMind
źródło
1

Ponieważ autor prosi o zrobienie tego w Gradle , możemy założyć, że chce to zrobić w skrypcie, a nie w plikach konfiguracyjnych. Ponieważ zarówno Android Studio, jak i Gradle zostały mocno zaktualizowane i zmodyfikowane w ciągu ostatniego roku (~ 2018), wszystkie inne powyższe odpowiedzi wydają się nadmiernie wykrzywione. Najłatwiejszym sposobem jest dodanie następujących elementów do 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
źródło