Reference build.gradle versionName attribute in xml layout - android

I'd like to have a layout file which references the versionName attribute in my gradle file:
...
defaultConfig {
applicationId "se.test.myapp"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
....
Something like
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/versionName"
/>
Is there a neat way to to this, without having to set up the layout in my code?

According to http://tools.android.com/tech-docs/new-build-system you can create resources directly from gradle, so putting
android {
...
defaultConfig {
applicationId "se.test.myapp"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
...
applicationVariants.all { variant ->
variant.resValue "string", "versionName", variant.versionName
}
...
}
in your build.gradle will do the trick
It creates resource file generated.xml during compilation in generated/res folder which is included alongside with resources provided by you in values folder. So you can use android:text="#string/versionName" to reference this value. Unfortunately, sometimes IDE can't resolve this reference, so it'll look like an error in your layout resource (while it's a valid statement and will be resolved at runtime).
You can suppress the error by clicking inside the "#string/versionName", then Alt+Enter, in the menu select "Create string value resource 'versionName", then "Suppress for tag".

Edit: You should not use Jack only for this. As per the official announcement Jack is deprecated (for everything except Java 8 features).
I used a string resource:
<resources>
<string name="app_ver" translatable="false">1.0.2</string>
...
</resources>
in the app's build.gradle:
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
...
versionName "#string/app_ver"
jackOptions {
enabled true
}
}
...
}
And like this:
<Preference
android:title="Version"
android:summary="#string/app_ver"/>
This project in GitHub contains a working version of this.

I use variables in my projects for versionName and versionCode
for example, in the app's build.gradle:
final VERSION_NAME = '2.2.3'
final VERSION_CODE = 15
android {
defaultConfig {
resValue "string", "version_code", VERSION_NAME + " (build " + VERSION_CODE + ")"
versionCode VERSION_CODE
versionName VERSION_NAME
...
}
...
}
Android Studio automatically generates an untranslatable string resource:
<string name="version_code" translatable="false">2.2.3 (build 15)</string>
which I can use in xml:
<Preference
android:selectable="false"
android:title="#string/version"
android:summary="#string/version_code" />
hope it will be useful

I believe you can set the VersionName in your android manifest with a string resource, too. Like this:
AndroidManifest.xml
android:versionName="#string/versionName"
Your Layout xml
android:text="#string/versionName"
But I do not know how compatible this is to gradle.

Related

Set androidTest.apk version code

I use ./gradlew assembleAndroidTest to create app-debug-androidTest.apk, but the versionCode for apk is always 0. Is there any to set the versionCode for app-debug-androidTest.apk.
Thanks!
For normal apk, I can set in AndroidManifest.xml:
android:versionCode="110"
android:versionName="3.0.17 alpha"
or in build.gralde:
defaultConfig {
applicationId "com.android.searchui"
minSdkVersion 18
targetSdkVersion 22
versionCode 84
versionName "9.4"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
But when during instrumented tests, there are generated two .apk files. And the smaller one is app-debug-androidTest-unaligned.apk and it's versionCode is 0.
Updated on 2017/8/4:
I think it's very difficult to do this because the com.android.application gradle plugin didn't provider androidTest apk versionCode setting.
So I just put a version.xml to src/androidTest/res/values folder:
<resources>
<integer name="versionCode">111</integer>
</resources>
Use this to fake versionCode.
Just add this to your manifest
android:versionCode="110"
android:versionName="3.0.17 alpha"
you can set your desired version code and name
Go to /app/build.gradle.
There you can give versionCode and versionName
For eg
defaultConfig {
applicationId "your package name"
minSdkVersion 17
targetSdkVersion 25
versionCode 2
versionName "1.0.1"
}
you can copy the src/main/AndroidManifest.xml to src/androidTest/AndroidManifest.xml
then add android:versionCode and android:versionName in src/androidTest/AndroidManifest.xml
dump test apk
java -jar ~/apktool_2.4.0.jar d ./app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk
copy AndroidManifest.xml to androidTest
cp app-debug-androidTest/AndroidManifest.xml app/src/androidTest/
add android:versionCode and android:versionName in AndroidManifest.xml
rebuild test apk

Android build flavor sqlite database

I'd like to create a demo from my application, so I tried to build another flavor, but if I try to run it, I get this exception:
attempt to write a readonly database (code 1032)
Original Gradle
defaultConfig {
minSdkVersion 9
targetSdkVersion 24
applicationId 'com.myapp.foo'
versionCode 518
versionName '4.3.2'
}
and this is my gradle with the two flavors
defaultConfig {
minSdkVersion 9
targetSdkVersion 24
}
productFlavors {
baz {
applicationId 'com.myapp.baz'
versionCode 1
versionName '1.0.0'
}
foo {
applicationId 'com.myapp.foo'
versionCode 518
versionName '4.3.2'
}
}
Are you sure you have your flavor specific source segmented correctly so that you only have one SQLiteOpenHelper? Meaning you have one under src/baz/java and one under src/foo/java but not one under src/main/java? Or just a single one under src/main/java?
In your AndroidManifest.xml provider section, it should be like the below one.
<provider
android:name="com.zoho.invoice.provider.ZInvoiceProvider"
android:authorities="${applicationId}"
android:writePermission="${applicationId}.permission.WRITE_SCHEDULE" />
So that the appropriate application id will be replaced while build process.
Also, in your whole project where ever, you use your application id, should be replace with the placeholder.
In your Java file, it can be accessed as
BuildConfig.APPLICATION_ID

Android flavors with different applicationId broke application behavior and look

I am using following build.gradle
apply plugin: 'com.android.application'
def final appId = "com.example.app"
android {
compileSdkVersion 23
buildToolsVersion '24.0.1'
defaultConfig {
vectorDrawables.useSupportLibrary = true
applicationId appId
buildConfigField "String", "DBNAME", "\"mydb.db\""
}
testOptions {
unitTests.returnDefaultValues = true
}
buildTypes {
release {
minifyEnabled false
proguardFile 'proguard-rules.pro'
}
}
productFlavors {
rel {
minSdkVersion 14
applicationId = "${appId}"
buildConfigField "String", "DBNAME", "\"mydb.db\""
targetSdkVersion 23
versionCode 33
versionName '1.4'
}
dev {
minSdkVersion 14
applicationId = "${appId}.dev"
buildConfigField "String", "DBNAME", "\"mydb_dev.db\""
targetSdkVersion 3
versionCode 1
versionName '1.4-beta'
}
}
}
...
I have not copied code from main to rel and dev source sets, and I have just created separate files for each flavor: res/values/strings.xml, res/values/colors.xml, google-service.json.
The application builds well, with different applicationId and installs as separate on the same device.
For the rel flavor everything works well, and it has applicationId = 'com.example.app' equal to original package name and to actual source package name.
But I obtain very strange behavior and look for the dev flavor, which becomes applicationId = 'com.example.app.dev'
Firstly, I see that animations are not working properly, because it seems that they become wrong coordinates.
Secondary, I have many fragments with dynamically inflating views and they are showing partly or not showing at all - differently at different run.
I suggest that the issue is that I have the same package name for classes and probably there emerges so ambiguous class identification.
I see that getContext() returns the same class 'com.example.app.MainActivity' for both flavors and I think this is matter.
I wouldn't like to copy all sources under each source set because i don't need to make changes there - code still the same.
What is a solution?
It was a mistyping that kills many hours to resolve...
I had pointed targetSdkVersion 3 rather targetSdkVersion 23
(I am surprised that it was building at all)
The Issue is solved, Android Flavors are magnificent!

Android apk version name

Following is my build.gradle file:
...
defaultConfig {
applicationId "app.com.foo.player"
minSdkVersion 18
targetSdkVersion 23
versionCode 1 // increment with every release
versionName "Foo-1.0" // change with every release
setProperty("archivesBaseName", "$versionName")
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
...
I have few question related to version name of android apk:
When I build the project, the generated apk name is Foo-1.0-debug.apk. Where from is 'debug' coming from, what does it signify, and how do I avoid/change that ?
How do I generate different names for dev and prod version of apps ?
Is there a way I can automatically increment my version number and version name for each build ?
Thanks in advance.
To generate different name for developmen and product, u can use productFlavors,refer the below link.
https://developer.android.com/studio/build/build-variants.html
In gradle ,
productFlavors{
releaseBuild{
buildConfigField "String", "APP_NAME", '"SAMPLE_APP_PRODUCT"'
}
debugBuild{
buildConfigField "String", "APP_NAME", '"SAMPLE_APP_DEBUG"'
}
}
After setting in gradle, change the BuiltVariant and run the program
With question 1 and 2 you can goto Project Structure select tab Flavors and Build Type to setup config for build.
With question 3 you can make a script in build.gradle in project then use in module. Here I use current time in second as a example:
in project:
ext{
minSdk = 14
targetSdk = 23
verCode = getVersion();
verName = "Foo-1.0"
}
def getVersion() {
return new Date().getTime() / 1000;
}
In module
defaultConfig {
minSdkVersion minSdk
targetSdkVersion targetSdk
versionCode verCode
versionName verName + verCode
}

Possible to set dynamic values for versionCode in defaultConfig?

By default, Gradle build.gradle usually looks like this
apply plugin: 'com.android.application'
android {
compileSdkVersion 19
buildToolsVersion "20.0.0"
defaultConfig {
applicationId "com.xyz.android"
minSdkVersion 15
targetSdkVersion 20
versionCode 1
versionName "1.0"
}
buildTypes {
release {
...
Is there a way to make defaultConfig.versionCode and defaultConfig.versionName dynamic, instead of static?
By dynamic I meant to bind them to the Manifest so these two values update when the same Manifest values update.
It seems that in Gradle we don't have to touch Manifest. All we have to do is to set Gradle and it will set Manifest. That is the main reason why Gradle projects don't have set these values in Manifest by default.

Categories

Resources