Use variables in manifest - android

Integrating some libraries like Branch-io in Android need to define meta-data in the project manifest. some of these variables are like TestMode
<meta-data android:name="io.branch.sdk.TestMode" android:value="true" />
So, when we want to publish the application we should change it to False.
Is there any way to define a variable somewhere according to BuildType and assign it to the Meta-data to that?

You can do it by adding manifestPlaceholders to your build.gradle file:
android {
...
buildTypes {
debug {
manifestPlaceholders = [isBranchSdkInTestMode:"true"]
...
}
release {
manifestPlaceholders = [isBranchSdkInTestMode:"false"]
...
}
}
...
}
In AndroidManifest.xml, you can use it as ${isBranchSdkInTestMode}:
<meta-data android:name="io.branch.sdk.TestMode" android:value="${isBranchSdkInTestMode}" />

Yes you can inject build variables from gradle to manifest, it is done by adding variable to the build.gradle:
android {
defaultConfig {
manifestPlaceholders = [hostName:"www.example.com"]
}
deployConfg {
manifestPlaceholders = [hostName:"www.prod-server.com"]
}
...
}
And then in your manifest you can get it by:
<intent-filter ... >
<data android:scheme="http" android:host="${hostName}" ... />
...
</intent-filter>
You can read more about how this works here.

Related

How to add different values of string resource for different flavors?

I'm an iOS developer who is trying to make some small changes on android side but with no clue of how to achieve them. My goal is to implement Facebook SDK inside the app, official documentation says:
In /app/res/values/strings.xml add new string element:
<string name="facebook_app_id">Facebook App ID</string>
Then add in AndroidManifest.xml file new meta-data like below:
<application android:label="#string/app_name" ...>
...
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="#string/facebook_app_id"/>
...
</application>
All is understood but my problem is that I have few product flavors based on which I build at the end stand alone apps, for each I have different Facebook App ID. I would appreciate any kind of help. Thanks!
You can create multiple build types or product flavors inside the app-level build.gradle file and then define different strings for each build variant like this
buildTypes {
prod{
resValue "string", "facebook_app_id", "your app id"
}
dev {
resValue "string", "facebook_app_id", "your app id"
}
}
Now you can access this string inside manifest
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="#string/facebook_app_id"/>
There are many ways. But as you already define multiple flavour in build.gradle in app level then you can define the string over there like this
android {
buildTypes {
flavour1 {
buildConfigField "String", "facebook_app_id", "\"first facebook id 1\""
}
flavour2 {
buildConfigField "String", "facebook_app_id", "\"first facebook id 2\""
}
}
}
It automatically initialise the facebook_app_id to the build when you are creating the build of the flavour.
Happy Coding :)
In build.gradle :
productFlavors {
appDev {
applicationId 'com.android.dev'
}
appTest {
applicationId 'com.android.test'
}
}
flavorDimensions "default"
Inside src folder:
create folder with flavors name
-src
-appDev(folder)
-java(folder)
-res(folder)
-values(folder)
-appTest(folder)
-java(folder)
-res(folder)
-values(folder)
inside values folder you can create strings.xml each folder act as different flavor
you need to pass your facebook app_id in the string files.
<string name="facebook_app_id">35166120881***</string>
<string name="fb_login_protocol_scheme">fb35166120881****</string>
...
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="#string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
...
</application>
Important this
<meta-data android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id"/>

Unable to use Branch key as a Manifest Placeholders

I'm unable to add the Branch keys as ManifestPlaceholders.
gradle.properties:
branch_api_key_qa="key_test_xxxxxxxxxxxxxxxxxxxxxxxx"
build.gradle
falvour_qa {
...
...
manifestPlaceholders = [branchKey : branch_api_key_qa]
}
AndroidManifest.xml
<meta-data
android:name="io.branch.sdk.BranchKey.test"
android:value="${branchKey}" />
The above code not making initSession callback in my launcher activity.
But providing the key directly in the manifest is working as expected
Try this
falvour_qa {
manifestPlaceholders = [
branchKey: 'key_test_xxxxxxxxxxxxxxxxxxxxxxxx'
]
}
I have done like this
<meta-data
android:name="io.branch.sdk.BranchKey"
android:value="key_live_**********" />
<meta-data
android:name="io.branch.sdk.BranchKey.test"
android:value="key_test_***************" />

You should specify at least one URL in your Instant App APKs manifest Play Store [duplicate]

I need to prepare an Alpha testing for an Instant App and It run like a charm on Android Studio but It is failing when I try to upload it to the PlayStore, saying:
Upload failed
Your Instant App APKs should contain at least one base APK.
The app structure is done using three modules:
-base: It contains all the code
-apk: Wrapper to obtains the installable apk
-instantApp: Wrapper to obtain the instantApp apk
This are the build.gradles:
base/build.gradle
buildscript {
repositories {
jcenter()
}
}
apply plugin: 'com.android.feature'
repositories {
jcenter()
mavenCentral()
flatDir {
dirs 'libs'
}
maven { url 'https://maven.fabric.io/public' }
}
android {
compileSdkVersion 25
buildToolsVersion "26.0.0-rc2"
baseFeature = true
dataBinding {
enabled = true
}
defaultConfig {
minSdkVersion 18
targetSdkVersion 25
versionCode 7
versionName "1.1"
}
signingConfigs {
release {
[...]
}
}
buildTypes {
debug {
[...]
}
release {
minifyEnabled false
signingConfig signingConfigs.release
[...]
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
abortOnError false
}
dexOptions {
javaMaxHeapSize "4g"
}
}
dependencies {
application project(":apk")
[...]
}
apply plugin: 'com.google.gms.google-services'
apk/build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "26.0.0-rc2"
dataBinding {
enabled true
}
defaultConfig {
applicationId “…”
minSdkVersion 18
targetSdkVersion 25
versionCode 7
versionName "1.1"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
signingConfigs {
release {
[...]
}
}
buildTypes {
debug {
[…]
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
[…]
}
}
}
dependencies {
implementation project(':base')
}
instantApp/build.gradle
apply plugin: 'com.android.instantapp'
dependencies {
implementation project(':base')
}
And this are the Manifests files
base/Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package=“…”>
<uses-permission android:name="android.permission.INTERNET" />
[…]
<application
android:name=“[…].TrgApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppBaseTheme">
<activity
android:name=“[…].LauncherActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host=“[domain]” />
</intent-filter>
</activity>
<activity
android:name="[…].RootActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
<activity
android:name="[…].OnBoardingActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" />
<activity
android:name="[…].LocationPickerActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service android:name="com.parse.PushService" />
<receiver
android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<!--
IMPORTANT: Change "com.parse.starter" to match your app's package name.
-->
<category android:name="[…]" />
</intent-filter>
</receiver>
<meta-data
android:name="com.parse.push.gcm_sender_id"
android:value="id:[…]" />
</application>
</manifest>
apk/Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="..." />
This package is different that the app's one
I already tried this solution: (Android Instant-release build not includes base APK) but it didn't work.
I m stuck since the last Friday so any kind of idea could be awesome
Thanks in advance
P.D: Its my first question so I m sorry if I didn't do it propertly ;)
Yeah!!! I found the issue!!!!(and its not in any of the google help documents)
The issue was that I was dropping the instantApp apk file straight away. The solution is to create a zip file with the instantApp apk and the base apk and drop that zip file!!!
Thanks for your help!!! At the end the issue wasnt gradle or the code..it was the PlayStore :)
I hope that if anyone has the same problem this question can help them!!!
This sample project seems to be pretty close to what you're trying to achieve. Perhaps you don't need the application project(":apk") in your base/build.gradle since you only have one feature (and that is the base split). You could also try removing base = true.
This section of the docs covers your use case - but it sounds like everything is set up correctly.
Could you also add your AndroidManifests to your original post?

set android:value with a gradle properties on manifest

I have my facebook application id on my gradle properties with :
FACEBOOK_APPLICATION_ID="XXXXXXXXXXXXXXX"
and I set in my defaultConfig :
manifestPlaceholders = [facebookAppId: FACEBOOK_APPLICATION_ID]
then, I want to use this in my manifest with :
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="${facebookAppId}" />
but it doesn't work. The only things working are to set my faceboook id in a string :
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
or to put this directly with :
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="\ XXXXXXXXXXXXXX" />
but I must set my facebook id in my gradle properties. What is the right way to do this ?
Thanks.
I am new on Gradle, but if I understood your questions I would suggest using something like that:
buildTypes {
debug {
// ...
}
release {
// ...
resValue "string", "facebook_application_id", "XXXXXXXXXXXXXXXXX"
}
}
Then, at your release build, for this example, you can use it as
android:value="#string/facebook_application_id"
Or even
R.string.facebook_application_id

Set a global variable in gradle that can use in manifest file

I want to create a global variable similar with applicationId.
It is set value in build.gradle and will be used in manifest. Is it possible?
You can set them, for instance I'm setting it for different product flavors
productFlavors {
production {
applicationId = "com.myapp.app"
resValue "string", "authority", "com.facebook.app.FacebookContentProvider5435651423234"
}
development {
applicationId = "com.myapp.development"
resValue "string", "authority", "com.facebook.app.FacebookContentProvider2134564533421"
}
qa {
applicationId = "com.myapp.qa"
resValue "string", "authority", "com.facebook.app.FacebookContentProvider29831237981287319"
}
}
And use it like this
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="#string/authority"
android:exported="true" />
If you just want to use the application id set in gradle in your manifest, you can simply use:
${applicationId}
For instance:
<provider
android:authorities="${applicationId}.ShareFileProvider" ... >
...
</provider>
If you want the same behavior with custom variables, you can use manifestPlaceholders, like this:
android {
defaultConfig {
manifestPlaceholders = [hostName:"www.example.com"]
}
}
And in your manifest:
<intent-filter ... >
<data android:scheme="http" android:host="${hostName}" ... />
...
</intent-filter>
See https://developer.android.com/studio/build/manifest-build-variables.html for more information.
While Marko's answer seems to work, there's currently a better solution that doesn't require adding variables to the string resource files.
The manifest merger accepts placeholders:
For custom placeholders replacements, use the following DSL to
configure the placeholders values :
android {
defaultConfig {
manifestPlaceholders = [ activityLabel:"defaultName"]
}
productFlavors {
free {
}
pro {
manifestPlaceholders = [ activityLabel:"proName" ]
}
}
will substitute the placeholder in the following declaration :
<activity android:name=".MainActivity" android:label="${activityLabel}" >
You can also manipulate those strings with groovy functions.
To use the string in Manifest, you can directly make it in strings.xml.
Like this,
<string name="variable_name">value</string>

Categories

Resources