What does formString(System.getenv("...")) mean? - android

In build.gradle, the following is under a product flavor:
buildConfigField 'String', 'API_URL', formString(System.getenv("DEV_API_URL"))
What does formString(System.getenv("DEV_API_URL")) mean?
I am used to seeing the formString as a static value (and I can reference it in code as BuildConfig.API_URL") but am having a hard time figuring out what this code means as well as where "DEV_API_URL" is defined. Guidance and links are appreciated!

1) formString must be a custom function defined somewhere in your build.gradle as there is no such function in Groovy or Java. If you cant figure out where it is, use a text search tool like ag (https://github.com/ggreer/the_silver_searcher)
2) System.getenv is a call that retrieves an environment variable defined on your machine, more here: https://docs.oracle.com/javase/7/docs/api/java/lang/System.html#getenv(java.lang.String).

Related

Pass custom variable to Bitrise flow through the API

I am setting up a Bitrise on an Android app. I have everything set that is related to the flow, the thing is that I have a custom python builder which requires a parameter. My build-flow is triggered through API, which is working as expected - the only thing missing is passing that parameter to the build script.
What I have currently:
I have added an env-variable; named PARAM
My JSON body, that triggers the build
{
"hook_info":{
"type":"bitrise"
},
"build_params":{
"branch":"master",
"workflow_id":"test_args_script",
"commit_message":"Triggered from postman",
"environments":[
{
"mapped_to":"PARAM",
"value":"123456",
"is_expand":true
}
]
}
}
On the Bitrise flow I have a script step which is actually calling the python script as follows: python builder.py $PARAM
EXPECTATIONS:
My expectations are that the value that will be passed to the script will be the same as the one in the API payload (123456).
If anyone has recently worked on something similar, or if any of you guys can point me out to documentation that will help me to achieve the above I will be really thankful!
I actually found the way. The problem on my end was that I had an env-variable already named the same as the one variable that has been passed from the API. After changing the name to a different one, I was able to get the parameter and pass it to the build script. If anyone needs more info, give me a shout and I can post the payload along with the flow settings.

Access a variable in Java or string.xml from Gradle

I have a value for a String in String.xml
<string name="id">4</string>
and I have a class which contains a variable
public static int Id=1;
Now what I need is I want to get either of these two values in the gradle, which will check a condition and based on the condition it will rename my app. Below given is the part of the gradle code
def identifier //here i need to get value from the java or xml
switch(identifier)
{
case 1:
temp="ApplicationNewName";break;
}
newName=newName.replace("-release",temp);
output.output.File=new File(output.outputFile.parent,newName);
My question is that, Can i access the variables initialised in the java file or string xml in gradle file ?
You're approaching this problem backwards, Gradle gives you the ability to set those variables within the script itself and then you can further access those variables throughout your Android code. Here's a relevant answer for how you can set build configuration variables: https://stackoverflow.com/a/17201265/2168085
It also sounds like you are trying to build different apps from a single code base, or build variations of those apps. If that's the case then you should really look into build flavors to solve this problem. Essentially a build flavor allows you build different apps from a single main code base and apply variations or new functionality to the different flavors. This can be as basic as having a free and paid version of an app or a full white label code base where you can build very different apps from the same master code base. In Android these are more commonly known as build variants and the developer documentation gives plenty of good information on how to get started: https://developer.android.com/studio/build/build-variants.html

ApplicationId conditioned by build type and flavour dimension

I have an application which has 2 flavour dimensions. First dimension, lets call it "brand" has two types:
"strawberry", "cyan"
Both have different applicationIds, but we can focus only on one of those. Lets say "cyan" has applicationId "com.cyan.app".
The second flavour dimension is called say "environment". It has two values:
"prod", "test".
I also have two build types:
"debug", "release"
Now what I'm interested in, is how can I go about configuring the gradle script such that whenever I'm building debug versions there will be applicationIdSuffix which will contain both "debug" string and environment name string. So in the above example it would be:
com.cyan.app.debug.prod and com.cyan.app.debug.test
But if I build release version of an app I want to leave the main applicationId, so com.cyan.app, no matter the environment flavour.
Is there any way I can achieve that with gradle and android gradle plugin?
Ok, I've sit down during the weekend and was able to achieve that (and more). Sharing here so that others can benefit who would like to achieve the same thing as I posted in the question.
So first of all we have to attach ourselves to the applicationVariants.all task like so:
applicationVariants.all { variant ->
//We tweak the package name and application name depending on the variants (so that we can have multiple applications installed on the phone, depending on the
tweakPackageName(variant);
replaceInManifest(variant, 'android:label=\"#string/app_name\"', 'android:label=\"#string/
}
I've separated the logic to other methods so that the code is not clogged. The tweakPackageName method looks pretty simple (as it turned out):
/**
* Method that alters the package name in order to have many different variants of application installed simultanously on a device.
*/
ext.tweakPackageName = { variant ->
def envFlavor = getFlavorOfDimension(variant, flavorDimEnvironmentName);
variant.mergedFlavor.applicationId = variant.mergedFlavor.applicationId + ".${envFlavor.name.toLowerCase()}";
}
getFlavorOfDimension is a simple method to get the flavor of particular dimension I'm interested in (not a biggie so I won't spam with this code here). When we get the flavor we add it to the package name of the mergedFlavor object and we're done.
I also managed to not only change the package name but also to dynamically change the application launcher name, but there are plenty of solutions of that on StackOverflow so I won't be redundant here. All in all the solution to alter the package name works. Hopefully it will help someone like it helped me.

Adding conditional statements in Android Manifest

I need a way to assign different Shared User ID(during installation) to the same Android App(same APK) based on the device model during installation.
I couldn't find any documentation about conditional statements being supported in the manifest file.
Any help would be greatly appreciated.
Though this is a pretty old question, but I stumbled upon a similar problem recently and this might help someone who's still searching for a solution. My case was that I had to assign some key in AndroidManifest.xml at runtime based on a condition.
While I couldn't find a way to define conditions in Manifest, I was able to pass the way to Manifest from build.gradle. If the condition can be checked in build.gradle, then you can pass value to Manifest in the following way
android {
defaultConfig {
manifestPlaceholders = [hostName:"www.example.com"]
}
...
}
And then access it in Manifest as -
<intent-filter ... >
<data android:scheme="https" android:host="${hostName}" ... />
...
</intent-filter>
Documentation - https://developer.android.com/studio/build/manifest-build-variables
Furthermore, you can generate strings, bool and other values from build.gradle which can then be used app-wide.
buildConfigField "int", "FOO", "42"
resValue "string", "app_name", "My App Name Debug"
The closest you can get to conditionality in the manifest is to not include a value as a constant, but rather use a redirect to the resources. You then provide different resources for different languages, devices etc.
The documentation for the manifest element states that the Shared User id should be a string, but for example the Shared User label must be a string resource (since you would typically need to translate it). Whether you can get away with making the id a resource as well is hard to guess - the documentation is often inaccurate about this, but be aware that what works on one version of Android may not be true for all versions.

Using mock data in eclipse which doesn't produce warnings

How can I create a layout file with data and fill them with some example data so that I can see what I have done without producing warnings.
Here is an example:
If I remove the text (which wants Android Lint) I have a plain blue screen, which is not helpful at all.
By the way this is the warning:
[I18N] Hardcoded string "Foobar", should use #string resource example.xml /Example/res/layout Line 42 Android Lint Problem
Create an entry in your strings.xml for each of your example Strings.
On the other hand, this is a Lint warning. You can safely ignore this without causing immediate harm to your app, as these are only meant to guide you in best practices.
Go to the Eclipse preferences, into the Android submenu, then into the Lint Error Checking menu and disable the HardcodedText warning.
Second Method
Instead of setting the example text through XML, use the setText() through Java code, and enclose it in an if condition as follows:
if(BuildConfig.DEBUG) {
view.setText("My example text");
}
BuildConfig.DEBUG was added in ADT 17, and is true whenever you do a debug build. When you export the apk, it is set to false. As the variable is set to false and never reassigned, the Java compiler will optimize your code and remove these statements. They will not be compiled into a production app.

Categories

Resources