问题
I want to have ONE Android Studio (AS) 1.1.0 project create TWO APK files: one for pay version and one for free version of my Google Play Store (GPS) app. Using gradle build variants ("flavors"). I'm VERY close. I have uploaded from one AS project both versions--free and pay.
The only relatively-minor problems: I can't make the two versions have different icons and I can't make the action bar display different titles for the different apps.
Since we're dealing with flavors, there are three AndroidManifest.xml
files: one I CAN edit and two that gradle generates, one for each flavor. If I edit those, the edits are lost with the next build.
Here's "my" AndroidManifest.xml
:
package="com.dslomer64.kakurocombosbuildvariants" >
<application
android:icon="@drawable/kc_icon_free">
android:label="@string/app_name"
android:allowBackup="true"
>
<activity
android:screenOrientation="portrait"
android:icon="@drawable/kc_icon_free"
android:name=".MyActivity"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Except for package name, the generated AndroidManifest.xml
files are identical (here's one):
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dslomer64.kakurocombosbuildvariants.pro"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:label="KC" >
<activity
android:name="com.dslomer64.kakurocombosbuildvariants.MyActivity"
android:icon="@drawable/kc_icon_free"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I'm basing what I'm doing on this build.gradle
file listed here, which has outdated content, flagged with ///////////:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.5.+' /////////(wrong version)
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
android {
compileSdkVersion 18
buildToolsVersion "18.0.1"
defaultConfig {
minSdkVersion 15
targetSdkVersion 18
}
productFlavors {
production {
packageName "be.tamere.gradlebuildtypesexample" ////// packageName should be applicationId
}
staging {
packageName "be.tamere.gradlebuildtypesexample.staging"
}
}
}
dependencies {
compile 'com.android.support:appcompat-v7:18.0.0'
}
Also basing my effort on this sketch of the associated file structure:
+-- main
¦ +-- AndroidManifest.xml
¦ +-- ic_launcher-web.png
¦ +-- java
¦ ¦ +-- be
¦ ¦ +-- tamere
¦ ¦ +-- gradlebuildtypesexample
¦ ¦ +-- MainActivity.java
¦ +-- res
¦ +-- drawable-hdpi
¦ ¦ +-- ic_launcher.png
¦ +-- drawable-mdpi
¦ ¦ +-- ic_launcher.png
¦ +-- drawable-xhdpi
¦ ¦ +-- ic_launcher.png
¦ +-- drawable-xxhdpi
¦ ¦ +-- ic_launcher.png
¦ +-- layout
¦ ¦ +-- activity_main.xml
¦ +-- menu
¦ ¦ +-- main.xml
¦ +-- values
¦ ¦ +-- dimens.xml
¦ ¦ +-- strings.xml
¦ ¦ +-- styles.xml
¦ +-- values-v11
¦ ¦ +-- styles.xml
¦ +-- values-v14
¦ +-- styles.xml
+-- production
¦ +-- java
¦ +-- be
¦ +-- tamere
¦ +-- gradlebuildtypesexample
¦ +-- Constants.java
+-- staging
+-- java
¦ +-- be
¦ +-- tamere
¦ +-- gradlebuildtypesexample
¦ +-- Constants.java
+-- res
+-- drawable-hdpi
¦ +-- ic_launcher.png
+-- drawable-mdpi
¦ +-- ic_launcher.png
+-- drawable-xhdpi
¦ +-- ic_launcher.png
+-- drawable-xxhdpi
¦ +-- ic_launcher.png
+-- values
+-- string.xml
I don't know if lack of "|" symbols from staging on down is significant. If so, that could be where I'm diverging.
When I try to create both APKs, I eventually get this screen, which is great news:

Inside AS, I see this, which is great news:

And in Windows 7 Explorer I see:

Here's my structure inside AS:

This corresponds to the structure shown in the link. Note especially NO res
folder in the free
version. The res
folder in main
contains the icon for free
version. The res
folder in pro
contains the icon for pro
version.
How can I get different icons for the two different APKs?
Why does the title in the action bar for both versions show as a fully-qualified package name?
Is there a way to edit the generated AndroidManifest.xml
files? Or to make each flavor have its own editable AndroidManifest.xml
?
回答1:
I can't make the two versions have different icons and I can't make the action bar display different titles for the different apps.
Step #1: Choose one (free or paid) to be the one you have in the main/
sourceset. For the purposes of this answer, I'll assume that the free one goes in main/
.
Step #2: Edit main/res/values/strings.xml
to have your desired free edition of the app_name
resource, as you are using the app_name
string resource in your manifest.
Step #3: Create a paid/res/values/strings.xml
with a definition of app_name
that contains your desired value for the paid
app's display name.
Step #4: Decide whether you are going to use mipmaps or drawables for your launcher icon. You seem to have mipmap directories, but your manifest references a drawable resource. For the purposes of this answer, I will assume that you will go with mipmaps.
Step #5: Decide what you are going to call the launcher icon. Your app presently does not build, it would appear, as your manifest refers to a kc_icon_free
drawable, but your directory listing shows ic_launcher
. In particular, you want the name to NOT refer to "free" or "paid". I will assume here that you go with ic_launcher
.
Step #6: Get your icons and manifest reorganized per the above, with your free edition of the icons in the main
sourceset.
Step #7: Create paid/res/mipmap-*/
directories and put the paid edition of ic_launcher
icons in there.
Since we're dealing with flavors, there are three AndroidManifest.xml files: one I CAN edit and two that gradle generates, one for each flavor. If I edit those, the edits are lost with the next build.
You are certainly welcome to have AndroidManifest.xml
files in the free
and paid
sourcesets. They will get merged with the one in main
, the Gradle settings, and manifests from any dependencies.
That being said, you don't need that here. Have one manifest, pointing to one set of resources for labels and icons. Have one edition of the labels and icons in the main
sourceset; have the other in a product flavor's sourceset (e.g., paid
per my steps above).
Why does the title in the action bar for both versions show as a fully-qualified package name?
Presumably, that is what you have for the app_name
string resource value. If you do not like it, change the string resource.
Is there a way to edit the generated AndroidManifest.xml files?
Not the merged ones.
Or to make each flavor have its own editable AndroidManifest.xml?
See above. Again, that's not the right solution for your problem.
回答2:
Here's a picture of what I had been stuck on that @CommonsWare so completely clarified:

Each with different app_name
:

Gradle
disambiguates both via ProductFlavors
block declarations:
apply plugin: 'com.android.application'
android
{
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig
{
applicationId "com.dslomer64.kakurocombosbuildvariants"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes
{
release
{
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors
{
pro
{
applicationId "com.dslomer64.kakurocombosbuildvariants.pro"
}
free
{
applicationId "com.dslomer64.kakurocombosbuildvariants.free"
}
}
}
dependencies
{
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
}
And here is the MyActivity.java
reference to BOTH variants:
public class MyActivity extends Activity {
boolean FREE = Free.FREE;
Depending on how the value of FREE is set in each variant, the variant is either "free" (FREE = true) or "pro" (FREE = false). Here are those two variant classes, both named Free
in their respective files:
In KakuroCombosBuildVariants\app\src\free\java\com\dslomer64\kakurocombosbuildvariants\Free.java
:
package com.dslomer64.kakurocombosbuildvariants;
public class Free
{
public static final boolean FREE = true;
}
In KakuroCombosBuildVariants\app\src\pro\java\com\dslomer64\kakurocombosbuildvariants\Free.java
:
package com.dslomer64.kakurocombosbuildvariants;
public class Free
{
public static final boolean FREE = false;
}
回答3:
I've used the ''Ribbonizer plugin for Android'', written by FUJI Goro.
This is a ribbonizer as a Gradle plugin for Android, which adds a ribbon to launcher icons automatically.
https://github.com/gfx/gradle-android-ribbonizer-plugin
来源:https://stackoverflow.com/questions/30019086/how-do-i-get-different-icons-for-the-two-versions-of-my-gps-app-generated-via-gr