Could not get unknown property 'processReleaseGoogleServices' - android

I updated to use Android Studio 2.2 and Gradle 2.2.0. And now I have a problem building.
I followed this post https://medium.com/google-cloud/automatic-per-variant-google-services-json-configurations-with-gradle-d3d3e40abc0e#.g1p7c1tx2 to configure two "google-services.json" files to be used for dev vs prod builds and use the following method in my app/build.gradle file to toggle between the copying the two "google-services.json" files.
afterEvaluate {
processDebugGoogleServices.dependsOn switchToDebug
processReleaseGoogleServices.dependsOn switchToRelease
}
task switchToDebug(type: Copy) {
description = 'Switches to DEBUG google-services.json'
from "src/gcm-dev"
include "google-services.json"
into "."
}
task switchToRelease(type: Copy) {
description = 'Switches to RELEASE google-services.json'
from "src/gcm-prod"
include "google-services.json"
into "."
}
Gradle complies fine but when I click on the "Run app" (triangle "play" icon) or "Debug app" (triangle "play" icon with a bug behind) buttons in Android Studio, I get the following:
* What went wrong:
A problem occurred configuring project ':app'.
> Could not get unknown property 'processReleaseGoogleServices' for object of type com.android.build.gradle.AppExtension.
Please help, much appreciated.

I had the same issue and problem was in enabled instant run.Try to disable it and run again.

You should update Google Play Services gradle plugin as well, follow the documentation to set it up: https://developers.google.com/android/guides/google-services-plugin
The great thing is that you no longer need to write gradle tasks which create appropriate google-services.json files in your root directory. Build type specific google-services.json are now supported by the plugin:
"As of version 2.2.0 the plugin supports build type and product flavor
specific JSON files. All of the following directory structures are
valid"

An alternative way to this is to refer to the task in the following way:
tasks.whenTaskAdded { task ->
if (task.name == 'assembleDebug') {
task.dependsOn 'switchToDebug'
} else if (task.name == 'assembleRelease') {
task.dependsOn 'switchToRelease'
}
}
UPDATE
The problem you mentioned in comment is related to your google-services.json file. You need to place google-services.json into app/ dir. And for each build type there should be accordant director in app/src folder.
If file already exists check if correct package name inside it
"client_info": {
"mobilesdk_app_id": "1:6596814400689:android:65d6f25f5006145",
"android_client_info": {
"package_name": "com.my.app.package.name"
}

As described by #Singed, add a directory pr build type/flavor under src-directory and the corresponding google-services.jsonand Google Play gradle plugin will take care of the rest, e.g.:
src/
debug/google-services.json
release/google-services.json
During build the correct file will be processed, ending up in build/generated/res/google-services/debug|release/values/values.xml

Related

Android studio / Gradle javadoc task

I've been struggling to setup a gradle task to generate Javadocs for my Android library, but when there are external dependencies to other libraries, doc generation fails. This seems to be a common task, but somehow there doesn't seem to be an easy solution, as for example this answer will reveal (re-generating exploded-aar manually is a bit absurd, and also, on Android Studio 3.0 even that doesn't work anymore due to the new dependency directives).
However, I have noticed that generating Javadoc through the Android Studio GUI (Tools menu) works just fine - dependencies to other libraries are resolved etc. So how does this work - does this menu not utilize a gradle task for generating Javadoc?
Since I need to generate Javadoc using gradle as part of CI I find it very frustrating that there is no documented way of getting it to work, while there is a way that works through the menues. Doesn't the Android Studio Tools -> Generate Javadoc menu in turn use a gradle task? Since dependencies are listed with gradle files, and the Javadoc tools menu apparently is able to resolve those dependencies - how is it implemented? How does it source the jars embedded in the dependant aar libraries, etc? How can it be used stand-alone and not though the Android Studio GUI?
Maybe you have got the solution to this. Just in case not, below is how I generate API doc for my Jenkins CI.
task generateApiDoc() {
group "reporting"
description "Generates Javadoc."
}
android.libraryVariants.all { variant ->
// Only consider release
if (variant.buildType.name == "release") {
def task = project.tasks.create("generate${variant.name.capitalize()}Javadoc", Javadoc) {
group "ApiDoc"
description "Generates Javadoc for $variant.name."
// Source files from the variant
source = variant.javaCompiler.source
// Classpath from the variant + android.jar
classpath = variant.javaCompiler.classpath + files(prj.android.getBootClasspath()) + files("$buildDir/intermediates/classes/release")
/* add the excluded packages */
exclude "**/R**"
exclude "**/BuildConfig*"
options.windowTitle = "My Library"
options.memberLevel = JavadocMemberLevel.PROTECTED
options.linkSource false
options.author = true
//options.links("http://docs.oracle.com/javase/7/docs/api/", "http://d.android.com/reference");
failOnError false
}
task.dependsOn assemble
generateApiDoc.dependsOn task
}
}
Then run below gradle commands to get your api doc in place of "$buildDir/docs".
./gradlew assembleRelease
./gradlew generateApiDoc
Edit for Gradle Plugin 3.4.1
android.libraryVariants.all { variant ->
def task = project.tasks.create("generate${variant.name.capitalize()}Javadoc", Javadoc) {
title "API Documentation (${project.android.defaultConfig.versionName})"
group "ApiDoc"
description "Generates Javadoc for $variant.name."
// Source files from the variant
source = variant.sourceSets.collect { it.java.sourceFiles }.inject { m, i -> m + i }
// To fix issue: Error: Can not create variant 'android-lint' after configuration ': library: debugRuntimeElements' has been resolved
doFirst {
classpath = project.files(variant.javaCompileProvider.get().classpath.files,
project.android.getBootClasspath())
}
if (JavaVersion.current().isJava8Compatible()) {
options.addStringOption('Xdoclint:none', '-quiet')
}
exclude "**/R"
exclude "**/R.**"
exclude "**/R\$**"
exclude "**/BuildConfig*"
if (JavaVersion.current().isJava8Compatible()) {
options.addStringOption('Xdoclint:none', '-quiet')
}
options.windowTitle = "API Documentation (${project.android.defaultConfig.versionName})"
options.memberLevel = JavadocMemberLevel.PROTECTED
options.linkSource false
options.author = false
failOnError true
}
task.dependsOn "assemble${variant.name.capitalize()}"
generateApiDoc.dependsOn task
}
I use a gradle task that just executes a bash script file, with a single (pretty long) javadoc command.
What you can do is run the Javadoc generation from Android Studio once, then copy the executed javadoc command from the Studio log, with all the right parameters, and automate the execution of the same command in your gradle.
The tool to generate java style documentation is called javadoc and it comes installed in every JDK. You can configure which classes or packages you want to be included, which ones should be excluded and many other options. Type javadoc in a terminal where a JDK is available and you'll get an idea. See also https://docs.oracle.com/javase/9/javadoc/javadoc.htm#JSJAV-GUID-7A344353-3BBF-45C4-8B28-15025DDCC643
After you get to your optimal configuration, you can include a javadoc step in your CI.

How to change path for release APK artifact?

How can I configure a Gradle Android project so that a release APK built by the IDE is saved to a path of my choosing (eg the project root) rather than buried deep in the build folder?
I've added this to the defaultConfig section of the app build file to sensibly name the APK and it works well, but how can I specify where it goes, or move it post build completion?
archivesBaseName = "AppName-v$versionName" // AppName-v1.2.3-release.apk
UPDATE:
I created a task in the app-level Gradle build file that successfully copies the release APK, if I run the Gradle task manually:
task copyReleaseApk(type: Copy) {
from 'build/outputs/apk'
into '..' // project root, one-level above "app"
include '**/*release.apk'
}
But I have not yet found a way to make the task run automatically after the last build task. I tried this:
assembleRelease.finalizedBy(copySupportFiles)
But that results in "Could not get unknown property 'assembleRelease' for object of type com.android.build.gradle.AppExtension."
I also tried this:
assembleRelease.finalizedBy(copySupportFiles)
It appears not to do anything.
This worked (in the android tag of the app build.gradle file). The afterEvaluate seems to be required in order to refer to tasks like packageRelease that don't initially exist.
task copyReleaseApk(type: Copy) {
from 'build/outputs/apk'
into '..' // folder above the app folder
include '**/*release.apk'
}
afterEvaluate {
packageRelease.finalizedBy(copyReleaseApk)
}
It can be defined in the project's root build.gradle:
allprojects {
buildDir = "/path/to/build/${rootProject.name}/${project.name}"
}

Crashlytics NDK symbols and Gradle tasks

I have a question that mostly relates to gradle.
I'm using Crashlytics to report NDK crashes in my Android app.
I have a task in build.gradle that calls ndk-build and compiles the cpp files into an .so file.
At the end of this task I want to call a task that uploads generated symbols mapping to Crashlytics.
After installing the Fabric plugin in Android Studio, I saw there are some new tasks that were added to the Gradle tab. One of them is
crashlyticsUploadSymbols[buildType][flavour] where buildType and flavour indicate which buildtype and flavour is currently selected.
This task does seem to upload a symbols file.
My question is,
Is it possible to call this task from within build.gradle?
Currently I use a manual call in Android Studio's terminal tab in the form of:
./gradlew crashlyticsUploadSymbols[buildType][flavour]
Is it possible to call this task somehow from within build.gradle?
To call this task I use finalizedBy at the end of the buildNdk task, so once buildNdk has finished, the upload task will execute.
Also very important, how can I get the current buildType and flavour so I am able to add it to the crashlyticsUploadSymbols call?
Thank you!
Mike from Crashlytics and Fabric here.
This was also answered on the Twitter Community forum's, but sharing the same answer here.
Option 1:
If you only want or need to upload symbols for your release builds, then you can set crashlticsUploadSymbolsRelease as the finalizedBy task for your ndk-build task.
Option 2:
If you have multiple variant-based tasks, you can do something like:
android.applicationVariants.all { variant ->
def variantName = variant.name.capitalize()
def task = project.task ("ndkBuild${variantName}")
task.finalizedBy project.("crashlyticsUploadSymbols${variantName}")
}
The following did the job for me:
android {
...
afterEvaluate {
assembleDebug.finalizedBy(crashlyticsUploadSymbolsDebug)
assembleRelease.finalizedBy(crashlyticsUploadSymbolsRelease)
}
}

How to maintain two google-services.json, production and debug

I am including feature of gcm in my app, For that i need to maintain two google-services.json one for debug and one for release build. How to do that ?? can i configure gcm without using google-services.json ??
First, place the respective google_services.json for each buildType in the following locations:
app/src/debug/google_services.json
app/src/test/google_services.json
app/google_services.json
Note: Root app/google_services.json This file should be there according to the build variants copy the json code in the root json file
Now, let’s whip up some gradle tasks in your: app’s build.gradle to automate moving the appropriate google_services.json to app/google_services.json
copy this in the app/Gradle file
task switchToDebug(type: Copy) {
description = 'Switches to DEBUG google-services.json'
from "src/debug"
include "google-services.json"
into "."
}
task switchToRelease(type: Copy) {
description = 'Switches to RELEASE google-services.json'
from "src/release"
include "google-services.json"
into "."
}
Great — but having to manually run these tasks before you build your app is cumbersome. We would want the appropriate copy task above run sometime before: assembleDebug or :assembleRelease is run. Let’s see what happens when :assembleRelease is run: copy this one in the /gradlew file
Zaks-MBP:my_awesome_application zak$ ./gradlew assembleRelease
Parallel execution is an incubating feature.
.... (other tasks)
:app:processReleaseGoogleServices
....
:app:assembleRelease
Notice the :app:processReleaseGoogleServices task. This task is responsible for processing the root google_services.json file. We want the correct google_services.json to be processed, so we must run our copy task immediately beforehand.
Add this to your build.gradle. Note the afterEvaluate enclosing.
copy this in the app/Gradle file
afterEvaluate {
processDebugGoogleServices.dependsOn switchToDebug
processReleaseGoogleServices.dependsOn switchToRelease
}
Now, anytime :app:processReleaseGoogleServices is called, our newly defined :app:switchToRelease will be called beforehand. Same logic for the debug buildType. You can run :app:assembleRelease and the release version google_services.json will be automatically copied to your app module’s root folder.
Credit goes to the : Zak Taccardi
https://medium.com/google-cloud/automatic-per-variant-google-services-json-configurations-with-gradle-d3d3e40abc0e
The current plugin (com.google.gms:google-services:2.1.X) supports flavors but not types.
So if you create a productflavor you can put the json file in src/$flavorname
Example:
app/src/
flavor1/google-services.json
flavor2/google-services.json
Currently it doesn't work with types (debug, release...) but you can use somenthing like this:
app/src/release/google-services.json
app/google-services.json
In this case the plugin looks in the locations and stops when it finds a google-services.json file.
If you are using a flavor it becomes:
app/src/foo/release/google-services.json
app/src/foo/google-services.json
You can find updated info here.
I'm currently using the following versions: com.google.gms:google-services:4.3.3, com.google.firebase:firebase-messaging:20.2.0
Place your google-services.json file in your $projectName/app/src/$buildType directory. For example, place one json file in src/release and another in src/debug. You will likely need to create the release & debug folders.
Note: It's a common mistake to add these files in the app folder, be sure you add this in the src folder as described above.
The google-services plugin always looks for the google-services.json
file in two directories: First, on the
$projectName/app/src/$buildType/google-services.json. If it does not
find it here, it goes one level above, to the
$projectName/app/google-services.json. So, when you are building the
debug version of your app, it will search for the google-services.json
on the $projectName/app/src/debug/ directory.
At the link below, see David Ojeda's response.

How to export library to Jar in Android Studio?

I have downloaded some library sources and would like to export it as a Jar file using
Android Studio. Is there a way to export to jar file using Android studio ?
edit:
The library I want to export as jar is an Android library.
It's called "StandOut" and can be downloaded from GitHub.
https://github.com/pingpongboss/StandOut
It is not possible to export an Android library as a jar file. It is possible, however, to export it as aar file. Aar files being the new binary format for Android libraries. There's info about them in Google I/O, the New Build System video.
First, build the library in Android Studio or from command line issuing gradle build from your library's root directory.
This will result in <yourlibroot>/libs/build/yourlib.aar file.
This aar file is a binary representation of your library and can be added to your project instead of the library as a dependency project.
To add aar file as a dependency you have to publish it to the maven central or to your local maven repository, and then refer the aar file in your project's gradle.build file.
However, this step is a bit convoluted. I've found a good explanation how to do so here:
http://www.flexlabs.org/2013/06/using-local-aar-android-library-packages-in-gradle-builds
I was able to build a library source code to compiled .jar file, using approach from this solution:
https://stackoverflow.com/a/19037807/1002054
Here is the breakdown of what I did:
1. Checkout library repository
In may case it was a Volley library
2. Import library in Android Studio.
I used Android Studio 0.3.7. I've encountered some issues during that step, namely I had to copy gradle folder from new android project before I was able to import Volley library source code, this may vary depending on source code you use.
3. Modify your build.gradle file
// If your module is a library project, this is needed
//to properly recognize 'android-library' plugin
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.3'
}
}
apply plugin: 'android-library'
android {
compileSdkVersion 17
buildToolsVersion = 17
sourceSets {
main {
// Here is the path to your source code
java {
srcDir 'src'
}
}
}
}
// This is the actual solution, as in https://stackoverflow.com/a/19037807/1002054
task clearJar(type: Delete) {
delete 'build/libs/myCompiledLibrary.jar'
}
task makeJar(type: Copy) {
from('build/bundles/release/')
into('build/libs/')
include('classes.jar')
rename ('classes.jar', 'myCompiledLibrary.jar')
}
makeJar.dependsOn(clearJar, build)
4. Run gradlew makeJar command from your project root.
I my case I had to copy gradlew.bat and gradle files from new android project into my library project root.
You should find your compiled library file myCompiledLibrary.jar in build\libs directory.
I hope someone finds this useful.
Edit:
Caveat
Althought this works, you will encounter duplicate library exception while compiling a project with multiple modules, where more than one module (including application module) depends on the same jar file (eg. modules have own library directory, that is referenced in build.gradle of given module).
In case where you need to use single library in more then one module, I would recommend using this approach:
Android gradle build and the support library
Since Android Studio V1.0 the jar file is available inside the following project link:
debug ver: "your_app"\build\intermediates\bundles\debug\classes.jar
release ver: "your_app"\build\intermediates\bundles\release\classes.jar
The JAR file is created on the build procedure,
In Android Studio GUI it's from Build->Make Project and from CMD line it's "gradlew build".
Include the following into build.gradle:
android.libraryVariants.all { variant ->
task("generate${variant.name}Javadoc", type: Javadoc) {
description "Generates Javadoc for $variant.name."
source = variant.javaCompile.source
ext.androidJar = "${android.plugin.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar"
classpath = files(variant.javaCompile.classpath.files) + files(ext.androidJar)
}
task("javadoc${variant.name}", type: Jar) {
classifier = "javadoc"
description "Bundles Javadoc into a JAR file for $variant.name."
from tasks["generate${variant.name}Javadoc"]
}
task("jar${variant.name}", type: Jar) {
description "Bundles compiled .class files into a JAR file for $variant.name."
dependsOn variant.javaCompile
from variant.javaCompile.destinationDir
exclude '**/R.class', '**/R$*.class', '**/R.html', '**/R.*.html'
}
}
You can then execute gradle with: ./gradlew clean javadocRelease jarRelease which will build you your Jar and also a javadoc jar into the build/libs/ folder.
EDIT: With android gradle tools 1.10.+ getting the android SDK dir is different than before. You have to change the following (thanks Vishal!):
android.sdkDirectory
instead of
android.plugin.sdkDirectory
I was able to export a jar file in Android Studio using this tutorial:
https://www.youtube.com/watch?v=1i4I-Nph-Cw
"How To Export Jar From Android Studio "
I updated my answer to include all the steps for exporting a JAR in Android Studio:
1) Create Android application project, go to app->build.gradle
2) Change the following in this file:
modify apply plugin: 'com.android.application' to apply plugin: 'com.android.library'
remove the following: applicationId, versionCode and versionName
Add the following code:
// Task to delete old jar
task deleteOldJar(type: Delete){
delete 'release/AndroidPlugin2.jar'
}
// task to export contents as jar
task exportJar(type: Copy) {
from ('build/intermediates/bundles/release/')
into ('release/')
include ('classes.jar')
rename('classes.jar', 'AndroidPlugin2.jar')
}
exportJar.dependsOn(deleteOldJar, build)
3) Don't forget to click sync now in this file (top right or use sync button).
4) Click on Gradle tab (usually middle right) and scroll down to exportjar
5) Once you see the build successful message in the run window, using normal file explorer go to exported jar using the path: C:\Users\name\AndroidStudioProjects\ProjectName\app\release
you should see in this directory your jar file.
Good Luck :)
Here's yet another, slightly different answer with a few enhancements.
This code takes the .jar right out of the .aar. Personally, that gives me a bit more confidence that the bits being shipped via .jar are the same as the ones shipped via .aar. This also means that if you're using ProGuard, the output jar will be obfuscated as desired.
I also added a super "makeJar" task, that makes jars for all build variants.
task(makeJar) << {
// Empty. We'll add dependencies for this task below
}
// Generate jar creation tasks for all build variants
android.libraryVariants.all { variant ->
String taskName = "makeJar${variant.name.capitalize()}"
// Create a jar by extracting it from the assembled .aar
// This ensures that products distributed via .aar and .jar exactly the same bits
task (taskName, type: Copy) {
String archiveName = "${project.name}-${variant.name}"
String outputDir = "${buildDir.getPath()}/outputs"
dependsOn "assemble${variant.name.capitalize()}"
from(zipTree("${outputDir}/aar/${archiveName}.aar"))
into("${outputDir}/jar/")
include('classes.jar')
rename ('classes.jar', "${archiveName}-${variant.mergedFlavor.versionName}.jar")
}
makeJar.dependsOn tasks[taskName]
}
For the curious reader, I struggled to determine the correct variables and parameters that the com.android.library plugin uses to name .aar files. I finally found them in the Android Open Source Project here.
We can export a jar file for Android library project without resource files by Android studio. It is also requirement what I met recently.
1. Config your build.gradle file
// Task to delete old jar
task clearJar(type: Delete){
delete 'release/lunademo.jar'
}
// task to export contents as jar
task makeJar(type: Copy) {
from ('build/intermediates/bundles/release/')
into ('build/libs/')
include ('classes.jar')
rename('classes.jar', 'lunademo.jar')
}
makeJar.dependsOn(clearJar, build)
2. Run gradlew makeJar under your project root
You will see your libs under dir as build/libs/ if you are luckily.
============================================================
If you met issue as "Socket timeout exception" on command line as below,
You can follow this steps to open Gradle window in the right part and click "makeJar" on Android studio like this,
Then go to build/libs dir, you will see your jar file.
Hope that it is helpful for u.
Good Luck #.#
Luna

Categories

Resources