如何为通过 gradle 构建变体生成的两个版本的 GPS 应用程序获取不同的图标?
How do I get different icons for the two versions of my GPS app generated via gradle build variants?
我想要一个 Android Studio (AS) 1.1.0 项目创建两个 APK 文件:一个用于付费版本,一个免费版本 Google Play 商店 (GPS) 应用程序。使用 gradle 构建变体 ("flavors")。 我非常接近。我已经从一个 AS 项目上传了两个版本——免费和付费。
唯一的 relatively-minor 问题:我不能让两个版本有不同的图标,我不能让操作栏为不同的应用程序显示不同的标题。
由于我们处理的是风味,所以有三个 AndroidManifest.xml
文件:一个我可以编辑,两个 gradle 生成,每个风味一个。如果我编辑这些,编辑内容将在下一个版本中丢失。
这里是 "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>
除了包名,生成的 AndroidManifest.xml
个文件是相同的(这里是一个):
<?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>
我的工作基于 build.gradle
列出的 here 文件,其中内容已过时,标记为 //////////:
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'
}
我的工作也基于相关文件结构的草图:
+-- 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
不知道是不是少了"|"从上到下的标志意义重大。如果是这样,那可能是我发散的地方。
当我尝试创建这两个 APK 时,我最终看到了这个屏幕,这是个好消息:
在 AS 内部,我看到了这个,这是个好消息:
在 Windows 7 Explorer 中我看到:
这是我在 AS 中的结构:
这对应于link中显示的结构。特别注意 free
版本中没有 res
文件夹。 main
中的 res
文件夹包含 free
版本的图标。 pro
中的 res
文件夹包含 pro
版本的图标。
如何为两个不同的 APK 获取不同的图标?
为什么两个版本的操作栏中的标题都显示为 fully-qualified 包名称?
有没有办法编辑生成的 AndroidManifest.xml
文件?或者让每种口味都有自己的可编辑 AndroidManifest.xml
?
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.
第 1 步:选择一个(免费或付费)作为您在 main/
源集中拥有的那个。出于此答案的目的,我假设免费的进入 main/
.
第 2 步:编辑 main/res/values/strings.xml
以获得您想要的 app_name
资源免费版本,因为您在清单中使用 app_name
字符串资源。
第 3 步:使用 app_name
的定义创建一个 paid/res/values/strings.xml
,其中包含您想要的 paid
应用显示名称的值。
第 4 步:决定是否要为启动器图标使用 mipmap 或可绘制对象。您似乎有 mipmap 目录,但您的清单引用了可绘制资源。出于此答案的目的,我假设您将使用 mipmap。
第 5 步:决定您要给启动器图标起什么名字。你的应用程序目前没有构建,它会出现,因为你的清单引用了一个 kc_icon_free
可绘制对象,但你的目录列表显示 ic_launcher
。特别是,您希望名称 而不是 引用 "free" 或 "paid"。我在这里假设你选择 ic_launcher
.
第 6 步:使用 main
源集中的免费图标,按照上述方法重新组织您的图标和清单。
第 7 步:创建 paid/res/mipmap-*/
目录并将 ic_launcher
图标的付费版本放在那里。
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.
当然欢迎您在 free
和 paid
源集中拥有 AndroidManifest.xml
文件。它们将与 main
中的那个、Gradle 设置合并,并从任何依赖项中体现出来。
话虽如此,您在这里不需要它。有一个清单,指向一组标签和图标资源。在 main
源集中拥有一个版本的标签和图标;在产品风味的源集中有另一个(例如,paid
按照我上面的步骤)。
Why does the title in the action bar for both versions show as a fully-qualified package name?
据推测,这就是您对 app_name
字符串资源值的看法。如果你不喜欢它,请更改字符串资源。
Is there a way to edit the generated AndroidManifest.xml files?
不是合并的。
Or to make each flavor have its own editable AndroidManifest.xml?
见上文。同样,这不是您问题的正确解决方案。
这是一张我被困在@CommonsWare 上的图片,非常清楚:
各有不同 app_name
:
Gradle
通过 ProductFlavors
块声明消除歧义:
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'
}
这里是对两个变体的 MyActivity.java
引用:
public class MyActivity extends Activity {
boolean FREE = Free.FREE;
根据每个变量中 FREE 值的设置方式,变量为 "free" (FREE = true) 或 "pro" (FREE = false)。这是这两个变体 类,它们在各自的文件中都命名为 Free
:
在KakuroCombosBuildVariants\app\src\free\java\com\dslomer64\kakurocombosbuildvariants\Free.java
中:
package com.dslomer64.kakurocombosbuildvariants;
public class Free
{
public static final boolean FREE = true;
}
在KakuroCombosBuildVariants\app\src\pro\java\com\dslomer64\kakurocombosbuildvariants\Free.java
中:
package com.dslomer64.kakurocombosbuildvariants;
public class Free
{
public static final boolean FREE = false;
}
我用过 FUJI Goro 写的''Ribbonizer plugin for Android''。
这是一个 ribbonizer,作为 Android 的 Gradle 插件,它会自动将功能区添加到启动器图标。
我想要一个 Android Studio (AS) 1.1.0 项目创建两个 APK 文件:一个用于付费版本,一个免费版本 Google Play 商店 (GPS) 应用程序。使用 gradle 构建变体 ("flavors")。 我非常接近。我已经从一个 AS 项目上传了两个版本——免费和付费。
唯一的 relatively-minor 问题:我不能让两个版本有不同的图标,我不能让操作栏为不同的应用程序显示不同的标题。
由于我们处理的是风味,所以有三个 AndroidManifest.xml
文件:一个我可以编辑,两个 gradle 生成,每个风味一个。如果我编辑这些,编辑内容将在下一个版本中丢失。
这里是 "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>
除了包名,生成的 AndroidManifest.xml
个文件是相同的(这里是一个):
<?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>
我的工作基于 build.gradle
列出的 here 文件,其中内容已过时,标记为 //////////:
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'
}
我的工作也基于相关文件结构的草图:
+-- 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
不知道是不是少了"|"从上到下的标志意义重大。如果是这样,那可能是我发散的地方。
当我尝试创建这两个 APK 时,我最终看到了这个屏幕,这是个好消息:
在 AS 内部,我看到了这个,这是个好消息:
在 Windows 7 Explorer 中我看到:
这是我在 AS 中的结构:
这对应于link中显示的结构。特别注意 free
版本中没有 res
文件夹。 main
中的 res
文件夹包含 free
版本的图标。 pro
中的 res
文件夹包含 pro
版本的图标。
如何为两个不同的 APK 获取不同的图标?
为什么两个版本的操作栏中的标题都显示为 fully-qualified 包名称?
有没有办法编辑生成的 AndroidManifest.xml
文件?或者让每种口味都有自己的可编辑 AndroidManifest.xml
?
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.
第 1 步:选择一个(免费或付费)作为您在 main/
源集中拥有的那个。出于此答案的目的,我假设免费的进入 main/
.
第 2 步:编辑 main/res/values/strings.xml
以获得您想要的 app_name
资源免费版本,因为您在清单中使用 app_name
字符串资源。
第 3 步:使用 app_name
的定义创建一个 paid/res/values/strings.xml
,其中包含您想要的 paid
应用显示名称的值。
第 4 步:决定是否要为启动器图标使用 mipmap 或可绘制对象。您似乎有 mipmap 目录,但您的清单引用了可绘制资源。出于此答案的目的,我假设您将使用 mipmap。
第 5 步:决定您要给启动器图标起什么名字。你的应用程序目前没有构建,它会出现,因为你的清单引用了一个 kc_icon_free
可绘制对象,但你的目录列表显示 ic_launcher
。特别是,您希望名称 而不是 引用 "free" 或 "paid"。我在这里假设你选择 ic_launcher
.
第 6 步:使用 main
源集中的免费图标,按照上述方法重新组织您的图标和清单。
第 7 步:创建 paid/res/mipmap-*/
目录并将 ic_launcher
图标的付费版本放在那里。
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.
当然欢迎您在 free
和 paid
源集中拥有 AndroidManifest.xml
文件。它们将与 main
中的那个、Gradle 设置合并,并从任何依赖项中体现出来。
话虽如此,您在这里不需要它。有一个清单,指向一组标签和图标资源。在 main
源集中拥有一个版本的标签和图标;在产品风味的源集中有另一个(例如,paid
按照我上面的步骤)。
Why does the title in the action bar for both versions show as a fully-qualified package name?
据推测,这就是您对 app_name
字符串资源值的看法。如果你不喜欢它,请更改字符串资源。
Is there a way to edit the generated AndroidManifest.xml files?
不是合并的。
Or to make each flavor have its own editable AndroidManifest.xml?
见上文。同样,这不是您问题的正确解决方案。
这是一张我被困在@CommonsWare 上的图片,非常清楚:
各有不同 app_name
:
Gradle
通过 ProductFlavors
块声明消除歧义:
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'
}
这里是对两个变体的 MyActivity.java
引用:
public class MyActivity extends Activity {
boolean FREE = Free.FREE;
根据每个变量中 FREE 值的设置方式,变量为 "free" (FREE = true) 或 "pro" (FREE = false)。这是这两个变体 类,它们在各自的文件中都命名为 Free
:
在KakuroCombosBuildVariants\app\src\free\java\com\dslomer64\kakurocombosbuildvariants\Free.java
中:
package com.dslomer64.kakurocombosbuildvariants;
public class Free
{
public static final boolean FREE = true;
}
在KakuroCombosBuildVariants\app\src\pro\java\com\dslomer64\kakurocombosbuildvariants\Free.java
中:
package com.dslomer64.kakurocombosbuildvariants;
public class Free
{
public static final boolean FREE = false;
}
我用过 FUJI Goro 写的''Ribbonizer plugin for Android''。
这是一个 ribbonizer,作为 Android 的 Gradle 插件,它会自动将功能区添加到启动器图标。