How to refer to a String var defined in build.gradle? - android

I hope to display different app name based free and pro version.
I define buildConfigField "String", "AppName", "\"Message Cleanup\"" in build.gradle, but I don't know how to apply to android:label in AndroidManifest.xml.
Could you help me ? Thanks!
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.dodata.messagecleanup" >
<application
android:allowBackup="true"
android:icon="#mipmap/clenupmessage"
android:label="AppName"
android:theme="#style/AppTheme" >
<activity android:name="ui.CleanupDelete"
android:label="AppName">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "info.dodata.messagecleanup"
minSdkVersion 9
targetSdkVersion 22
versionCode 7
versionName "1.07"
archivesBaseName = "MessageCleanup-V" + versionName
}
productFlavors {
free {
applicationId "info.dodata.messagecleanup"
buildConfigField "String", "AppName", "\"Message Cleanup\""
}
pro {
applicationId "info.dodata.messagecleanup.pro"
buildConfigField "String", "AppName", "\"Message Cleanup Pro\""
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.google.android.gms:play-services:7.3.0'
}
To kcoppock
The manifestPlaceholders can do that.
productFlavors {
wandoujia {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
}
baidu {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "New"]
}
c360 {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "c360"]
}
uc {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "uc"]
}
}
In AndroidManifest.xml, I can use it as the following code
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL_VALUE}" />

Assuming you are using the standard project structure (e.g. you have something like src/main/res/values/strings.xml), create additional directories for each flavor:
src/free/res/values/strings.xml
src/pro/res/values/strings.xml
And define the same string key (e.g. app_name) in both of those files, with the correct value for each variant. So you'd have something like:
src/free/res/values/strings.xml
<string name="app_name">Message Cleanup</string>
src/pro/res/values/strings.xml
<string name="app_name">Message Cleanup Pro</string>
The resource merger will merge in these strings based on which variant is being built. Now you can just refer to the app_name string in code, and know that it'll render correctly based on the currently built flavor.

Related

Why can't I debug my Android project over the phone?

I'm just getting into the field of Android development and I need to run my project for the first time in order to continue my learning process.
Unfortunately my computer is'nt powerful enough to run an AVD and every time I try to debug it with my phone I get this error message:
A problem was found with the configuration of task ':app:processDebugManifest'
(type' ProcessMultiApkApplicationManifest').
File 'E:\android\app\build\intermediates\merged_manifest\debug\out\AndroidManifest.xml' specified for
property 'mainMergedManifest' does not exist.
General Information:
I'm trying to debug a brand new project using my Galaxy A 70 (running Android 10). If necessary I would be happy to provide any additional information (to the best of my ability) regarding the project, the specifications of my phone or computer, etc.
build.gradle of app module:
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 29
defaultConfig {
applicationId "com.example.myapplication"
minSdkVersion 18
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.MyApplication">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I would be very grateful for any help regarding this problem.
Thanks in advance
Perry
You need a debug build type that is set to debuggable true
Add this to your buildTypes in build.gradel
buildTypes {
debug {
debuggable true
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
Then run gradle sync. , and in the build variants select the debug configuration, and then you'll be able to debug your app

How to use different package names between flavors?

I'm trying to create a single project with 2 flavors: free and pro (versions).
My app is already in PlayStore with different packages (E.g.: com.example.appfree and com.example.app)
This is my build.gradle:
defaultConfig {
applicationId "com.example.appfree"
}
productFlavors{
lite {
applicationIdSuffix 'lite'
}
pro {
}
}
And this is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".SplashScreenActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"/>
</application>
</manifest>
I tried to upload a build apk for free and pro flavors. Pro flavor is ok, but free flavor isnt accepted by Google, because the package is incorrect. How can I solve this?
====== Solved: ======
applicationIdSuffix only works with buildTypes.
With the new Android Gradle build system, you can easily build multiple different versions of your app; for example, you can build both a "free" version and a "pro" version of your app (using flavors), and these should have different packages in the Google Play store such that they can be installed and purchased separately, both installed at the same time, and so on. Similarly, you may also build both "debug" and "alpha" and "beta" versions of your app (using build types) and these can also similarly contribute to unique package names.
app/build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 19
buildToolsVersion "19.1"
defaultConfig {
applicationId "com.example.my.app"
minSdkVersion 15
targetSdkVersion 19
versionCode 1
versionName "1.0"
}
...
app/build.gradle:
productFlavors {
pro {
applicationId = "com.example.my.pkg.pro"
}
free {
applicationId = "com.example.my.pkg.free"
}
}
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
....
from Android Studio Project Site - ApplicationId versus PackageName
flavorDimensions "version"
productFlavors {
demo {
// Assigns this product flavor to the "version" flavor dimension.
// This property is optional if you are using only one dimension.
dimension "version"
applicationIdSuffix ".demo"
versionNameSuffix "-demo"
}
full {
dimension "version"
applicationIdSuffix ".full"
versionNameSuffix "-full"
}
}
Besides the basic gradle.build (app level) changes. Note that you only need to add the config you need to, not all of these:
productFlavors {
enterprise {
applicationId = "com.example.appname.enterprise"
}
consumer {
applicationId = "com.example.appname.consumer"
}
}
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
I wanted to add that if you are using Firebase and you are required to have a google-services.json file. You will see the following:
ERROR: No matching client found for package name "com.example.appname.debug"
To fix it, you will need to register the new package name in Firebase and download the new google-services.json which will have all your existing packages names. If not you will have a compile error saying no client was found for the new package name.

Dexguard error while running signed apk

I am using Android Studio,my project has 5 modules.
While running signed obfuscated apk I am getting the following error
Unable to instantiate application com.....FTApplication: java.lang.ClassNotFoundException: Didn't find class "com....FTApplication" on path: DexPathList[[zip file "/data/app/app.apk"].
This is my configuration
DexGuard6.1.03
com.android.tools.build:gradle:1.0.0 - dependency
Application extends from MultiDexApplication.
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.project.package">
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:name="com.project.package.FTApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<activity
android:name=".ui.activity.FTSplashActivity"
android:label="#string/app_name"
android:noHistory="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
top-level build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
module build.grade
apply plugin: 'com.android.application'
apply plugin: 'dexguard'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
buildscript {
repositories {
mavenCentral()
flatDir { dirs '../../DexGuard6.1.03/lib' }
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
classpath ':dexguard:'
}
}
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.project.package"
minSdkVersion 17
targetSdkVersion 21
versionCode 1
versionName "1.0"
multiDexEnabled = true
}
buildTypes {
debug {
proguardFile getDefaultDexGuardFile('dexguard-debug.pro')
proguardFile 'dexguard-project.txt'
}
release {
proguardFile getDefaultDexGuardFile('dexguard-release.pro')
proguardFile 'dexguard-project.txt'
}
// release {
// minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
// }
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':materialdialogs')
compile project(':AndroidKit')
compile 'com.joanzapata.pdfview:android-pdfview:1.0.4#aar'
compile files('libs/disklrucache-2.0.1.jar')
compile 'com.android.support:multidex:1.0.1'
compile 'com.jakewharton:disklrucache:2.0.2'
compile files('libs/commons-httpclient-3.0.jar')
compile files('libs/httpclientandroidlib-1.2.1.jar')
}
Thanks to #John for the comment.
Here is the solution for MultiDex with Dexguard:
1) Apply default MultiDex rules correctly. See my another post for correct options.
2) Modify build.gradle and dexguard-project.txt files.
build.gradle : Set multiDexEnabled true only for debug builds. Dexguard is going to handle it at release build.
defaultConfig {
applicationId "com.sample"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
// NOTE 1 : Remove multiDexEnabled setting from here
}
buildTypes {
debug {
// NOTE 2 : By default, debug builds don't need Dexguard. So set multiDexEnabled here.
multiDexEnabled true
}
release {
// NOTE 3 : Multidex is handled at dexguard-project.txt. So remove multiDexEnabled setting if exists.
proguardFiles getDefaultDexGuardFile('dexguard-release.pro'),'dexguard-project.txt'
}
}
dexguard-project.txt : Do not forget to add multidex option here!
-multidex

gradle placeholder can not solve the ${com.nssb.zssb}

gradle placeholder support problem :
my placeholder looks like ${com.nssb.zssb}
how can gradle deal with this situation, I tried the following command:
manifestPlaceholders = [com.nssb.zssb:"djdssb"]
but it didnt worked. any suggestion? many thanks~~~~~
my mainifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="differentbuild.com.mike.differentbuild" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="${com.nssb.zssb}"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="${com.nssb.zssb}" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:label="${com.nssb.zssb}" >
</activity>
</application>
</manifest>
my build gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "differentbuild.com.mike.differentbuild"
minSdkVersion 19
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
production {
applicationId "differentbuild.com.mike.differentbuild"
manifestPlaceholders = [com.nssb.zssb:"SecondActivity"]
versionName "1.0-pro"
}
pros {
applicationId "differentbuild.com.mike.differentbuild"
manifestPlaceholders = [com.nssb.zssb:"SecondActivity111"]
versionName "1.0.1-pro"
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
}

custom strings for debug buildType

I have an android app and I want to change the app label for the debug and other buildTypes. I donĀ“t have any flavors!
Here is the setup that I believe looks like it should work:
-src
|-debug
|-res
|-values
|-strings.xml
|-main
|-res
|-values
|-strings.xml
|-java
[...]
I have no custom sourcesets just a debug buildType:
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
so I though
sourceSets.debug.res.srcDirs = ['src/debug/res']
would to the trick. But it doesn't. Any ideas?
How to change app name per Gradle build type does not work anymore...
I found another sweet solution to this, using manifest placeholders:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="${applicationLabel}">
<activity
android:label="${applicationLabel}">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
and in your gradle file:
android {
defaultConfig {
manifestPlaceholders = [ applicationLabel:"#string/app_name"]
}
buildTypes {
debug {
applicationIdSuffix ".debug"
manifestPlaceholders = [ applicationLabel:"MyApp Debug"]
}
}
}
buildTypes {
release {
resValue 'string', 'APP_NAME', '"My App Release"'
}
debug {
resValue 'string', 'APP_NAME', '"My App Debug"'
}
}
value\strings.xml
< string name="app_name" >#string/APP_NAME< /string>
and use app_name everywhere
You have to use
|-debug
|-res
|-values
|-strings.xml
In your picture you have debug/res/strings.xml
Also you doens't need it (because it is the standard, but the issue isn't here).
sourceSets.debug.res.srcDirs = ['src/debug/res']
Forget the string.xml files. All can be easily configured in build.gradle.
First of all, you should maintain the string pointer "app_name" in AndroidManifest file, and delete all instances of "app_name" in string's resource files:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="#string/app_name">
<activity
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Secondly, the resource value of #string/app_name is currently not defined. So we must apply its default definition in build.gradle:
defaultConfig {
applicationId "com.example.myapp"
minSdkVersion 14
targetSdkVersion 22
versionCode 123423432
versionName "1.0.0"
resValue 'string', 'app_name', '"My app label"'
}
Currently, app_name is defined for all build types. By assuming you want to change the app label for the buildTypes, each build type must be defined with a string value in the same build.gradle branch:
buildTypes {
release {
resValue 'string', 'app_name', '"My app label Release"'
}
debug {
resValue 'string', 'app_name', '"My app label Debug"'
}
}
Since this resource value is set programmatically, we also need to add a certain translations lint ignore in case of a Release build:
lintOptions { disable 'MissingTranslation' }
In case you want to change it accordingly with a set of defined Flavours(dev, qua or prd) add the resValues definitions in productFlavours instead of buildTypes:
productFlavors {
dev {
applicationId "com.example.myapp.dev"
resValue 'string', 'app_name', '"My app label Dev"'
}
qua {
applicationId "com.example.myapp.qua"
resValue 'string', 'app_name', '"My app label Qua"'
}
prd {
applicationId "com.example.myapp.prd"
resValue 'string', 'app_name', '"My app label Prd"'
}
}
You can create a string in gradle that will be available in xml too:
buildTypes {
debug {
buildConfigField "String", "app_name", "AppDebug"
}
release {
buildConfigField "String", "app_name", "AppRelease"
}
And then use it in xml:
android:label="#string/app_name"
Just make sure app_name not specified in your strings.xml.
Try this.
buildTypes {
debug {
applicationIdSuffix ".debug"
}
sourceSets.debug.resources.srcDirs = ['src/debug/res']
}
Have you remembered to get rid of the directory listing inside your app's build.gradle?
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDir 'src'
// res.srcDir 'res' <--- This line should be removed
assets.srcDir 'assets'
I know this is quite an old question, but I've had the same problem and just solved it.
You should update these codes if you have one in your build.gradle for your app.
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
These codes automatically generate your AppName.iml and set default debug and release directory to /build-types/debug/res, which is different from src/debug/res.

Categories

Resources