ビルドフレーバーごとに異なるアプリ名?


94

たとえば、flavor1flavor2の2つのビルドフレーバーがあります

私は、たとえば、私のアプリケーションが名前を付ける「希望AppFlavor1をflavor1と」のとき、私のビルド「AppFlavor2」私は味2用にビルドする場合。

変えたい活動のタイトルではありません。電話メニューなどに表示されるアプリ名を変更したい。

build.gradle私は、アプリのラベル私の味のための各種パラメータを設定しますが、それはそう、することはできません。また、変数に基づいてプログラムでアプリのラベルを変更することもできません。

では、人々はこれをどのように処理しますか?

回答:


24

スクリプトを使用してメインのstrings.xmlを変更し、ソース管理を台無しにするリスクを冒す代わりに、Android Gradleビルドの標準のマージ動作に依存しませんか?

私のbuild.gradle内容

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src']
        resources.srcDirs = ['src']
        aidl.srcDirs = ['src']
        renderscript.srcDirs = ['src']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
    }

    release {
        res.srcDir 'variants/release/res'
    }

    debug {
        res.srcDir 'variants/debug/res'
    }
}

これで、でapp_name文字列を定義できますvariants/[release|debug]/res/strings.xml。そして、私が変えたい他のものも!


編集:res.srcDirを使用して、配列を完全に再定義するのではなく、配列に追加します。
Pierre-Luc Paour 2013年

はい、私も今ではそれを理解しています。
どうも

1
どこにsourceSetsブロックを追加する必要がありますか?android{...}ブロックの下にありますか?
Abel Callejo 2018

android確かにブロック内の@AbelMelquiadesCallejo 。
Pierre-Luc Paour 2018年

261

app_nameから削除しますstrings.xml(そうでない場合、gradleは重複したリソースについて文句を言います)。次に、ビルドファイルを次のように変更します。

productFlavors {
    flavor1{
        resValue "string", "app_name", "AppNameFlavor1"
    }

    flavor2{
        resValue "string", "app_name", "AppNameFlavor2"
    }
   } 

また、マニフェストの属性に@string/app_name値が割り当てられていることを確認android:labelしてください。

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

これはstrings.xml、異なるビルドセットで新しいものを作成したり、カスタムスクリプトを作成したりするよりも混乱が少なくなります。


9
これは魅力のように機能しますが、質問:このような文字列リソースを追加するときに、他のロケールにローカライズされた文字列を追加するにはどうすればよいですか?
AndroidMechanic-Viral Patel 2016年

ここにこれに関する質問を投稿しました:stackoverflow.com/questions/36105494/…見ていただけませんか?
AndroidMechanic-Viral Patel 2016年

3
複数のフレーバーディメンションを使用するのはどうですか?フレーバー/フレーバーの組み合わせごとに異なる名前を付けるにはどうすればよいですか?
ゾケット2017年

1
すべて問題ありませんが、ランチャーアイコンの下に表示されるアプリ名は、gradle製品のフレーバーによって設定されたとおりに変更されていません。strings.xmlから「app_name」を削除し、製品フレーバーに設定しました。Androidのアプリ情報ページからアプリ名が表示され、製品フレーバーによって設定されたアプリ名が表示されているが、ランチャーアイコンの下に以前のアプリ名が表示されている場合。
iamcrypticcoder 2017

2
@ mahbub.kuetを@string/app_nameランチャーactivityラベルに使用していますか?ことを覚えておいてくださいlabelメインランチャからはactivityに優先して使用されているapplication labelアプリの表示名のために。
user650881 2017

13

さまざまなフレーバーでアプリ名のローカリゼーションを維持したい場合は、次のように実現できます。

1)次のようandroid:label<application>利用可能で指定しますAndroidManifest.xml

<application
    ...
    android:label="${appLabel}"
    ...
>

2)appLabelアプリレベルでデフォルト値foを指定しますbuild.gradle

manifestPlaceholders = [appLabel:"@string/defaultName"]

3)次のように製品フレーバーの値をオーバーライドします。

productFlavors {
    AppFlavor1 {
        manifestPlaceholders = [appLabel:"@string/flavor1"]
    }
    AppFlavor2 {
        manifestPlaceholders = [appLabel:"@string/flavor2"]
    }

}

4)の各文字列(defaultName、flavor1、flavor2)の文字列リソースを追加しますstrings.xml。これにより、それらをローカライズできます。


ステップ2は、build.gradleの「defaultConfig」レベルにある必要があります。「android」レベルではありません。そうでない場合、manifestPlaceholders名に関連する不明なプロパティエラーが発生します。
Brendon Whateley 2018

8

文字列リソースファイルを各フレーバーに追加し、それらのリソースファイルを使用してアプリ名を変更できます。たとえば、私のアプリの1つに、無料版と有料版があります。それらの名前を「Lite」と「Pro」に変更するために、meta_data.xmlファイルを作成し、app_nameそのXMLに値を追加して、から削除しましたstrings.xml。次に、app/srcフレーバーごとにフォルダーを作成します(構造の例については以下を参照してください)。これらのディレクトリ内に、を追加しres/values/<string resource file name>ます。これで、ビルド時に、このファイルがビルドにコピーされ、アプリの名前が変更されます。

ファイル構造:

app/src
   /pro/res/values/meta_data.xml
   /lite/res/values/meta_data.xml

1
これは、gradleファイルで宣言するよりも優れています。チャームのように機能します。ありがとうございました。
フィリップルチアネンコ2017年

7

私が実際に使用するもう1つのオプションは、各アプリケーションのマニフェストを変更することです。リソースフォルダをコピーする代わりに、フレーバーごとにマニフェストを作成できます。

sourceSets {
  main {
 }

  release {
    manifest.srcFile 'src/release/AndroidManifest.xml'
 }

  debug {
    manifest.srcFile 'src/debug/AndroidManifest.xml'
 }
}

プリンシパルとなるプリンシパルAndroidManifestをsrcメインに含める必要があります。次に、(src / release / AndroidManifest.xml)のように、フレーバーごとにいくつかのオプションのみを使用してマニフェストを定義できます。

<manifest package="com.application.yourapp">
  <application android:icon="@drawable/ic_launcher">
  </application>
</manifest>

デバッグの場合、AndroidManifest(src / debug / AndroidManifest.xml):

<manifest package="com.application.yourapp">
  <application android:icon="@drawable/ic_launcher2">
  </application>
</manifest>

コンパイラーはマニフェストのマージを行い、各フレーバーのアイコンを持つことができます。


4

これはbuildTypesで簡単に実行できます

buildTypes {
    debug {
        buildConfigField("String", "server_type", "\"TEST\"")
        resValue "string", "app_name", "Eventful-Test"
        debuggable true
        signingConfig signingConfigs.debug_key_sign
    }

    stage {
        buildConfigField("String", "server_type", "\"STAGE\"")
        resValue "string", "app_name", "Eventful-Stage"
        debuggable true
        signingConfig signingConfigs.debug_key_sign
    }

    release {
        buildConfigField("String", "server_type", "\"PROD\"")
        resValue "string", "app_name", "Eventful"
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        //TODO - add release signing
    }
}

必ずstrings.xmlからapp_nameを削除してください


2

まず、この質問に答えます。「ユーザーは、アプリケーションの両方のフレーバーを同じデバイスにインストールできますか?」

ソースにパッチを適用するPythonスクリプトを使用しています。これには、いくつかの再利用可能な機能が含まれており、もちろん、この特定のプロジェクトでパッチを適用する必要があるものについての知識が含まれています。したがって、スクリプトはアプリケーション固有です。

多くのパッチがあり、パッチのデータはPython辞書(アプリケーションパッケージ名を含み、ところでJavaパッケージ名とは異なります)に保存され、フレーバーごとに1つの辞書があります。

l10nに関しては、文字列は他の文字列を指している可能性があります。たとえば、私のコードでは次のようになっています。

<string name="app_name">@string/x_app_name_xyz</string>

<string name="x_app_name_default">My Application</string>
<string name="x_app_name_xyz">My App</string>

これは一種の
Lightvs

次に、アプリのパッケージ名を変更する必要があります(例:com.example.mysoft.procom.example.mysoft.light)。そうしないと、ユーザーは同じデバイスにそのうちの1つしかインストールできません。
18446744073709551615 2013年

私はそれをしましたが、電話メニューで「マイアプリ」と「マイアプリプロ」を取得するにはどうすればよいですか?現在、2つのアプリ(ライトとプロ)がありますが、どちらも同じ名前です。そのために2つの異なるアプリ名が必要です。つまり、あなたが言っているように、それほど簡単ではありませんか?
Alexander Kulyakhtin 2013年

他の(反対票を投じられた)回答が言及しているように、AndroidManifest.xmlにはがあり<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" >ます。すべてをクリーンアップして再構築した後(2回、フレーバーごとに1回)、Androidパッケージ名とランチャーラベルが異なる2つのapkを取得する必要があります。ところで、Eclipseはリソースの変更を検出しないことが多いため、クリーンアップするように依頼する必要があります。
18446744073709551615 2013年

文字列/アプリ名をフレーバーごとに異なるようにするにはどうすればよいですか?申し訳ありませんが、まだ取得できません。
Alexander Kulyakhtin 2013年

0

文字列/アプリ名をフレーバーごとに異なるようにするにはどうすればよいですか?

更新を書きたかったのですが、ソースにパッチを適用するPythonスクリプトを使用しているという元の回答よりも大きいことに気付きました。

Pythonスクリプトには、パラメータ、ディレクトリ名があります。そのディレクトリには、フレーバーごとのアセット、ランチャーアイコンなどのリソース、およびPythonディクショナリを含むファイルproperties.txtが含まれています。

{ 'someBoolean' : True
, 'someParam' : 'none'
, 'appTitle' : '@string/x_app_name_xyz'
}

Pythonはスクリプトのロード、そのファイルから辞書をとの間の値を置き換え<string name="app_name"></string>の値によってproperties['appTitle']

以下のコードは、現状のまま/現状のままで提供されています。

for strings_xml in glob.glob("res/values*/strings.xml"):
    fileReplace(strings_xml,'<string name="app_name">',properties['appTitle'],'</string>',oldtextpattern=r"[a-zA-Z0-9_/@\- ]+")

1つ以上のそのようなファイルからプロパティを読み取るには:

with open(filename1) as f:
    properties = eval(f.read())
with open(filename2) as f:
    properties.update(eval(f.read()))

fileReplace関数は次のとおりです。

really = True
#False for debugging

# In the file 'fname',
# find the text matching "before oldtext after" (all occurrences) and
# replace 'oldtext' with 'newtext' (all occurrences).
# If 'mandatory' is true, raise an exception if no replacements were made.
def fileReplace(fname,before,newtext,after,oldtextpattern=r"[\w.]+",mandatory=True):
    with open(fname, 'r+') as f:
        read_data = f.read()
        pattern = r"("+re.escape(before)+r")"+oldtextpattern+"("+re.escape(after)+r")"
        replacement = r"\g<1>"+newtext+r"\g<2>"
        new_data,replacements_made = re.subn(pattern,replacement,read_data,flags=re.MULTILINE)
        if replacements_made and really:
            f.seek(0)
            f.truncate()
            f.write(new_data)
            if verbose:
                print "patching ",fname," (",replacements_made," occurrence" + ("s" if 1!=replacements_made else ""),")",newtext,("-- no changes" if new_data==read_data else "-- ***CHANGED***")
        elif replacements_made:
            print fname,":"
            print new_data
        elif mandatory:
            raise Exception("cannot patch the file: "+fname+" with ["+newtext+"] instead of '"+before+"{"+oldtextpattern+"}"+after+"'")

スクリプトの最初の行は次のとおりです。

#!/usr/bin/python
# coding: utf-8

import sys
import os
import re
import os.path
import shutil
import argparse
import string
import glob
from myutils import copytreeover

-4

AndroidManifestファイルでは、アプリケーションタグに次の行があります。

android:label

そしてそこであなたはアプリケーションラベルがデバイスのアプリケーションメニューに表示される方法を言うことができます


はい、質問を読みました... 2つのブランチを設定し、それぞれに(1つはflavor1用、もう1つはflavor2用)、AndroidManifestファイルに異なるandroid:labelを設定できます。
ヒットマン

6
ああ、知らなかった。これらの2つのマニフェストファイルを配置するにはどうすればよいですか?それは不可能ですが
Alexander Kulyakhtin 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.