Branch IO Android SDK initialization error - android

I try to setup Branch.io on android, but get an error:
BranchSDK: Warning: Please enter your branch_key in your project's
res/values/strings.xml!
Manifest:
<!-- Branch init -->
<meta-data android:name="io.branch.sdk.BranchKey" android:value="#string/branch_key" />
<!-- Branch testing (TestMode "true" to simulate fresh installs on dev environment) -->
<meta-data android:name="io.branch.sdk.TestMode" android:value="#bool/branch_io_test_mode" />
<!-- Branch install referrer tracking -->
<receiver android:name="io.branch.referral.InstallListener" android:exported="#bool/branch_io_test_mode">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
Gradle:
buildTypes {
debug {
resValue "bool", "branch_io_test_mode", "true"
resValue 'string', 'branch_key', '"key_live_*"'
...
}
release {
resValue "bool", "branch_io_test_mode", "false"
resValue 'string', 'branch_key', '"key_live_*"'
....
}
Application onCreate:
if (BuildConfig.DEBUG) {
Branch.enableDebugMode();
}
Branch.disableLogging();
Branch.getAutoInstance(this);
What exactly I am doing wrong? To be sure, there is no info about branch_key should be in strings on SDK setup page.

So a fed days after I got my fault.
Depending on build I neither set io.branch.sdk.TestMode to true or false. So when app compiled with TestMode true, Branch looked for Test key but not production key.
So actually my gradle shoud looks like:
buildTypes {
debug {
resValue "bool", "branch_io_test_mode", "true"
resValue 'string', 'branch_key', '"key_test_*"'
...
}
release {
resValue "bool", "branch_io_test_mode", "false"
resValue 'string', 'branch_key', '"key_live_*"'
....
}

Related

Default Activity Not Found with two different dimensions

I needed to use two different dimensions in the project. But after this usage, whatever I do, Android Studio tells me "Default Activity Not Found". Actually there's no changes in the src folder because I don't need to modify any classes in the flavors.
flavorDimensions "device", "backend"
productFlavors {
dev {
buildConfigField "String", "API_VERSION", "\"1.1\""
...extra configs
dimension "backend"
}
staging {
buildConfigField "String", "API_VERSION", "\"1.1\""
...extra configs
dimension "backend"
}
prod {
buildConfigField "String", "API_VERSION", "\"1.1\""
...extra configs
dimension "backend"
}
android {
buildConfigField "String", "DEVICE_TYPE", "\"ANDROID\""
dimension "device"
}
huawei {
buildConfigField "String", "DEVICE_TYPE", "\"ANDROID_HW\""
versionCode 10000 + defaultConfig.versionCode
dimension "device"
}
}
main/AndroidManifest.xml:
<application
android:name=".XApplication"
...
<activity
android:name=".ui.SplashActivity"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
In AndroidManifest.xml, change the android:name attribute of your activity to the fully-qualified class name of your Activity, instead of using the .ui.SplashActivity notation. When you prefix the name with ., it will append that to the package annotation of your <manifest> attribute, which may or may not match the package of your actual Activity class. Make sure your Activity class has the correct package declaration at the top of the file and is located in the right src directory.
The same goes for your Application class name. I avoid using the . notation at all costs.

Facebook setup with staging and prod version in my Android project

I have 2 versions of my App defined into Facebook (a prod version and a staging version):
In the manifest I have this official setup:
<!-- https://developers.facebook.com/docs/android/getting-started -->
<meta-data
android:name="com.facebook.sdk.ApplicationId"
tools:replace="android:value"
android:value="#string/facebook_app_id" />
In my Gradle:
// Facebook app id
resValue "string", "facebook_app_id", FACEBOOK_APP_ID
resValue "string", "facebook_app_id_staging", FACEBOOK_APP_ID_STAGING
In my Gradle.properties:
# Facebook identifier (app ID)
FACEBOOK_APP_ID="XXXXXXXX"
FACEBOOK_APP_ID_STAGING="YYYYYYYY"
So how can I switch to facebook App prod <-> staging easily during the project building, because currently it's fixed to always prod version (see the manifest extract).
Thank you very much guys!
You can move the properties inside the app build.gradle file in this way.
defaultConfig {
//this will be valid for release and debug buildTypes
manifestPlaceholders = [facebook_app_id:"RELEASE_KEY_XXXX"]
...
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
staging {
initWith debug
manifestPlaceholders = [facebook_app_id:"STAGING_KEY_XXXX"]
}
}
In the AndroidManifest.xml then you can use the placeholder:
<meta-data
android:name="com.facebook.sdk.ApplicationId"
tools:replace="android:value"
android:value="${facebook_app_id}" />
You can read more here about configuring build variants if you want to perform more advanced configurations

Android Gradle: Install all build types on one device

How do I configure my project to be able to install the debug version alongside the release version when using GCM, ContentProvider, AccountType? (without the use of flavors)
I keep getting errors such as: INSTALL_FAILED_CONFLICTING_PROVIDER or INSTALL_FAILED_DUPLICATE_PERMISSION
Installing a debug apk and the release apk on the same device is tricky if you are only using build types and not flavors (Why Build types and not flavors)
Most blog post are either outdated (talking about packageName) or force you to use flavors because the solution they propose does not support applicationIdSuffix and a build type cannot declare applicationId therefore you need to use a flavors
The solution I propose uses
an authority per build type
an account type per build type
a GCM permission per build type
For this to work I use applicationIdSuffix, manifest placeholders, BuildConfigField and resValue in the Gradle file.
The only problem left is when you want to have a different name for app and per language the string is not set as translatable (bug aosp tracker)
This forces you to set abortOnError false otherwise you won't be able to make a release build.
build.gradle
project.ext {
defaultApplicationId = "com.myapp.package"
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId defaultApplicationId
manifestPlaceholders = [ applicationIdWithSuffix: "${applicationId}" ]
buildConfigField "String", "ACCOUNT_TYPE", "\"${applicationId}\""
buildConfigField "String", "AUTHORITY", "\"${applicationId}.provider\""
resValue "string", "account_type", "${applicationId}"
resValue "string", "authority", "${applicationId}.provider"
}
buildTypes {
debug {
applicationIdSuffix ".debug"
debuggable true
manifestPlaceholders = [ applicationIdWithSuffix: defaultApplicationId + ".debug" ]
buildConfigField "String", "ACCOUNT_TYPE", "\"${defaultApplicationId}.debug\""
buildConfigField "String", "AUTHORITY", "\"${defaultApplicationId}.debug.provider\""
resValue "string", "account_type", "${defaultApplicationId}.debug"
resValue "string", "authority", "${defaultApplicationId}.debug.provider"
}
}
lintOptions {
abortOnError false
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mypackage" >
<permission
android:name="${applicationIdWithSuffix}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationIdWithSuffix}.permission.C2D_MESSAGE" />
<application
android:label="#string/app_name" >
<provider
android:name=".MyContentProvider"
android:authorities="${applicationIdWithSuffix}.provider"
android:exported="false"
android:multiprocess="true" />
</application>
</manifest>
Sync adapter xml
<sync-adapter
xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="#string/authority"
android:accountType="#string/account_type"/>
Account authenticator
<account-authenticator
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="#string/account_type"
.../>
ContentProvider
I have a constant for Authority which takes it from the BuildConfig.
AUTHORITY = BuildConfig.AUTHORITY
Account type
To get the account type you take it from the BuildConfig too.
BuildConfig.ACCOUNT_TYPE
Multi language app name
If you want different names per app & language:
debug/values-en/strings.xml
<resources>
<string name="app_name">MyApp debug EN</string>
</resources>
debug/values-fr/strings.xml
<resources>
<string name="app_name">MyApp debug FR</string>
</resources>
main/values-en/strings.xml
<resources>
<string name="app_name">MyApp EN</string>
</resources>
main/values-fr/strings.xml
<resources>
<string name="app_name">MyApp FR</string>
</resources>

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.

How to change app name per Gradle build type

I am trying to figure out a way to be able to change my application's app name per build type in gradle.
For instance, I would like the debug version to have <APP_NAME>-debug and the qa version to have <APP-NAME>-QA.
I am familiar with:
debug {
applicationIdSuffix '.debug'
versionNameSuffix '-DEBUG'
}
However, I can't seem to find a gradle command to apply the change of the app when in the launcher.
If by "app name", you mean android:label on <application>, the simplest solution is to have that point at a string resource (e.g., android:label="#string/app_name"), then have a different version of that string resource in a src/debug/ sourceset.
You can see that in this sample project, where I have a replacement for app_name in src/debug/res/values/strings.xml, which will be applied for debug builds. release builds will use the version of app_name in src/main/.
You can use something like this
buildTypes {
debug {
applicationIdSuffix '.debug'
versionNameSuffix '-DEBUG'
resValue "string", "app_name", "AppName debug"
}
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
zipAlignEnabled true
resValue "string", "app_name", "AppName"
}
}
You can use #string/app_name in AndroidManifest.xml files.
Make sure you remove app_name from values/ folder (no entry by this name).
You can do this with gradle:
android {
buildTypes {
release {
manifestPlaceholders = [appName: "My Standard App Name"]
}
debug {
manifestPlaceholders = [appName: "Debug"]
}
}
}
Then in your AndroidManifest.xml put:
<application
android:label="${appName}"/>
<activity
android:label="${appName}">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Note: it also works with productFlavors.
To support translations make this:
1. remove string "app_name"
2. add to gradle
buildTypes {
admin {
resValue "string", "app_name", "#string/app_name_admin"
}
release {
resValue "string", "app_name", "#string/app_name_release"
}
debug {
resValue "string", "app_name", "#string/app_name_debug"
}
}
3. Set app name in Manifest as "#string/app_name"
4. Add to strings.xml values
<string name="app_name_admin">App Admin</string>
<string name="app_name_release">App release</string>
<string name="app_name_debug">App debug</string>
The app name is user-visible, and that's why Google encourages you to keep it in your strings.xml file. You can define a separate string resource file that contains strings that are specific to your buildTypes. It sounds like you might have a custom qa buildType. If that's not true, ignore the qa part below.
└── src
├── debug
│   └── res
│   └── buildtype_strings.xml
├── release
│   └── res
│   └── buildtype_strings.xml
└── qa
   └── res
   └── buildtype_strings.xml
We need a solution to support app name with localization (for multi language).
I have tested with #Nick Unuchek solution, but building is failed (not found #string/) . a little bit change to fix this bug:
build.gradle file:
android {
ext{
APP_NAME = "#string/app_name_default"
APP_NAME_DEV = "#string/app_name_dev"
}
productFlavors{
prod{
manifestPlaceholders = [ applicationLabel: APP_NAME]
}
dev{
manifestPlaceholders = [ applicationLabel: APP_NAME_DEV ]
}
}
values\strings.xml:
<resources>
<string name="app_name_default">AAA prod</string>
<string name="app_name_dev">AAA dev</string>
</resources>
values-en\strings.xml:
<resources>
<string name="app_name_default">AAA prod en</string>
<string name="app_name_dev">AAA dev en</string>
</resources>
Manifest.xml:
<application
android:label="${applicationLabel}" >
</application>
For a more dynamic gradle based solution (e.g. set a base Application name in main's strings.xml once, and avoid repeating yourself in each flavor / build type combination's strings.xml), see my answer here: https://stackoverflow.com/a/32220436/1128600
There are multiple ways you can do.
you can create manifestPlaceholders OR resValue in app level build.gradle. e.g.
buildTypes {
release {
...
manifestPlaceholders = [appLabel: "My App"]
//resValue "string", "appLabel", '"My App"'
}
debug {
...
manifestPlaceholders = [appLabel: "My App - Debug"]
//resValue "string", "appLabel", '"My App - Debug"'
}
}
OR
If you have productFlavors, you can create there
flavorDimensions "env"
productFlavors {
dev {
dimension "env"
...
manifestPlaceholders = [appLabel: "My App - Development"]
//resValue "string", "appLabel", '"My App - Development"'
}
prod {
dimension "env"
...
manifestPlaceholders = [appLabel: "My Awesome App"]
//resValue "string", "appLabel", '"My Awesome App"'
}
}
Then in AndroidManifest.xml if you are using manifestPlaceholders, just change android:label="${appLabel}" as below OR if you are using resValue, just change android:label=#string/appLabel
<application
...
android:label="${appLabel}"> //OR `android:label=#string/appLabel`
<activity
...
android:label="${appLable}">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
NOTE: Make sure to change android:lable as well in <activity> of LAUNCHER category. If it doesn't require to use android:label in <activity>, just remove this.
If you do not want to add in build.gradle directly, you can add in values/string.xml of selected ProductFlavors. e.g.
Add
<string name="appLabel">My App - Development</string>
in app/src/dev/res/values/string.xml
and
<string name="appLabel">My Awesome App</string>
in app/src/prod/res/values/string.xml
You can use strings.xml in different folders, see Android separate string values for release and debug builds.
So, create this file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Your app name</string>
</resources>
Then paste it to app\src\debug\res\values\ and app\src\release\res\values\ folders. Replace "Your app name" in debug and release files. Remove app_name item from strings.xml in app\src\main\res\values\ folder.
In AndroidManifest you will have the same
<application
android:label="#string/app_name"
...
No changes at all. Even if you added a library with it's AndroidManifest file and strings.xml.
As author asks to do this in Gradle, we can assume he want to do it in the script and not in the configuration files. Since both Android Studio and Gradle has been heavily updated and modified in the last year (~2018) all other answers above, seem overly contorted. The easy-peasy way, is to add the following to your app/build.gradle:
android {
...
buildTypes {
...
// Rename/Set default APK name prefix (app*.apk --> AwesomeApp*.apk)
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
def appName = "AwesomeApp"
outputFileName = appName+"-${output.baseName}-${variant.versionName}.apk"
}
}
}

Categories

Resources