Showing posts with label android-gradle. Show all posts
Showing posts with label android-gradle. Show all posts

Thursday, October 4, 2018

How to sign android app with platform keys using gradle?

Leave a Comment

I saw couple similar questions like:

but I feel my problem is different.

First of all I use:

android:sharedUserId="android.uid.system"

so I need to sign my app with platform key. I'm able to do that in this way:

cd $ANDROID_ROOT/out/host/linux-x86/framework java -Djava.library.path=$ANDROID_ROOT/out/host/linux-x86/lib64 -jar signapk.jar $ANDROID_ROOT/build/target/product/security/platform.x509.pem $ANDROID_ROOT/build/target/product/security/platform.pk8 $APP_DIR/app/build/outputs/apk/debug/app-debug.apk $APP_DIR/MyApp-signed.apk 

However I want to do signing from gradle, so I have generated jks file in this way:

./keytool-importkeypair -k my_keystore.jks -p my_password -pk8 $ANDROID_ROOT/build/target/product/security/platform.pk8 -cert $ANDROID_ROOT/build/target/product/security/platform.x509.pem -alias platform 

and I've modified app/build.gradle to have:

 signingConfigs {      release {          storeFile file("my_keystore.jks")          storePassword "my_password"          keyAlias "platform"          keyPassword "my_password"      }  }   buildTypes {      release {          minifyEnabled false          proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'           signingConfig signingConfigs.release      }  } 

I've checked that my_keystore.jks has platform alias with:

keytool -list -v -keystore my_keystore.jks | grep Alias Alias name: platform 

but when I try to do:

./gradlew assembleRelease 

or:

./gradlew signingReport 

I get:

Failed to read key platform from store "(...)/my_keystore.jks": Invalid keystore format

Update: I've tried following dr_g tips and I'm able to sign app using Android Studio (Build -> Generate Signed APK), so I guess keystore is ok, but still I get the same error when using assembleRelease. I've also tried generating my own keystore as suggested by deadfish and indeed keystore generated by Android Studio is fine for gradle and assembleRelease works, but it's not platform key, so I can't use it unfortunately.

3 Answers

Answers 1

Please try using the .keystore variant. There could be ways to fix the java keystore (.jks) format but it is likely to take more time.

1) Generate your .keystore file from your separate key files

$ openssl pkcs8 -inform DER -nocrypt -in \   $ANDROID_ROOT/build/target/product/security/platform.pk8 -out platform.key $ openssl pkcs12 -export -in \   $ANDROID_ROOT/build/target/product/security/platform.x509.pem -inkey \   platform.key -name platform -out platform.pem -password pass:password $ keytool -importkeystore -destkeystore platform.keystore -deststorepass \   password -srckeystore platform.pem -srcstoretype PKCS12 -srcstorepass    password 

2) Test your new keystore:

$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore \   platform.keystore -storepass password your-app.apk platform 

3) Deploy keystore in your gradle build:

signingConfigs {  debug {     storeFile     file('debug.keystore')     storePassword 'android'     keyAlias      'androiddebugkey'     keyPassword   'android'  }  release {     storeFile     file('platform.keystore')     storePassword 'password'     keyAlias      'platform'     keyPassword   'password'  }  } 

The above build.gradle is also showing an example of using the android debug keystore as standard for debug builds.

Answers 2

use the .keystore file not the .jks when you generate you app,Android studio will notice you create a keyStore, try this key.

Answers 3

After chat with deadfish and following his suggestions (thanks for help!) I've come up with following workaround in app/build.gradle (inside android {}):

applicationVariants.all { variant ->     variant.assemble.doLast {         exec {             commandLine 'sh', '../mySigningScript.sh'         }     } } 

This will run my script everytime when assembleDebug or assembleRelease is finished. I will not accept my answer because it's not answering my question and it forces me to remove signingConfigs from gradle but at least it's a workaround which potentially could be used if no better solution is proposed.

Read More

Saturday, September 22, 2018

Problem with gradle build flavour and packagingOptions

Leave a Comment

I have been developing for a while a library (in aar format) that is compatible with x86, armeabi-v7a and arm64-v8a abis. The library works as expected but, in order to reduce the final size, we want to develop two different libraries: one with arm64-v8a abi and one without it. The library depends on openCV (used in C++ language) and we have the following project structure:

src  |_ main      |_ jniLibs            |    | arm64-v8a            |----| armeabi-v7a                 | x86 

Each abi folder contains libopencv_java3.so.

I have created two product flavours, each one with the abiFilters needed to work properly.

flavorDimensions "default" productFlavors {     v7a {         externalNativeBuild {             cmake {                 abiFilters 'x86', 'armeabi-v7a'             }         }     }     v8a {         externalNativeBuild {             cmake {                 abiFilters 'x86', 'armeabi-v7a', 'arm64-v8a'             }         }     } } 

Now I have two build variants to select and both compile without errors. However, the v7a aar still contains the arm64-v8a folder and library inside it. To solve this, I have added to v7a flavour the following:

packagingOptions {     exclude 'lib/arm64-v8a/libopencv_java3.so' } 

Now, v7a aar does not contain the arm64-v8a folder inside it but when I select v8a flavour, the folder exists but no libopencv_java3.so is placed inside it!

Should not this option only affect to v7a? What am I doing wrong? Any help will be appreciated.

Notes: gradle version tested: 3.1.2 and 3.1.4.

1 Answers

Answers 1

try to split differently, instead of using product favors -

alike this one can load armeabi-v7a assembly on arm64-v8a:

splits {     abi {         enable true         reset()         include "armeabi", "x86"         universalApk true     } } 

this would expect the (32bit version of the) library at armeabi/libopencv_java3.so.

externalNativeBuild only considers the libraries, which are being built (aka "your code"). if you insist on using the packagingOptions, you should not define them globally, but per product flavor.

v7a {     ...     packagingOptions {         exclude 'lib/arm64-v8a/libopencv_java3.so'     } } 
Read More

Saturday, July 28, 2018

Program type already present: android.support.v4.media.MediaBrowserCompat$CustomActionCallback

Leave a Comment

I completely new to Android Development and can't seem to resolve this error: "Error: Program type already present: android.support.v4.media.MediaBrowserCompat$CustomActionCallback"

This is my dependencies:

dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.0.0-alpha1' implementation 'androidx.constraintlayout:constraintlayout:1.1.2' implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0-alpha1' implementation 'androidx.legacy:legacy-support-v4:1.0.0-alpha1' implementation "android.arch.navigation:navigation-fragment:1.0.0-alpha01" implementation "android.arch.navigation:navigation-ui:1.0.0-alpha01"   androidTestImplementation 'androidx.test:runner:1.1.0-alpha3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha3' testImplementation 'junit:junit:4.12' } 

I've googled some and ended up on the developer page about "Resolve duplicate class errors", but I'm still not able to fix this. Help would be very much appriciated!

4 Answers

Answers 1

Option 1

Following worked for me Add the following in your gradle.properties file

android.useAndroidX = true android.enableJetifier = false 

Option 2 (if above does't work)

  1. Android studio > Navigate -> Class
  2. Check include non-project classes
  3. Copy full class path android.support.v4.accessibilityservice.AccessibilityServiceInfoCompat
  4. See where it is used. You may need to remove, one of them.

Option 3 you might be including package which is including modules as well so exclude the support-v4 module with following method

implementation ('org.eclipse.paho:org.eclipse.paho.android.service:1.0.2') {       exclude group: 'com.android.support', module:'support-v4' } 

Answers 2

At least for me the issue was with the implementation 'androidx.legacy:legacy-support-v4:1.0.0-alpha1' dependency. I went into the menu in Android Studio to create a Blank Fragment in Kotlin just to see what that would look like and the dependency above was added.

Once i removed that dependency the error went away.

Answers 3

It is seen that Android studio wrongly show the error.

Try clearing cache. File -> Invalidate Caches / Restart -> Invalidate and Restart

Answers 4

Some of your existing dependencies are using older versions of support library, try this

implementation 'androidx.legacy:legacy-support-v4:1.0.0-alpha1' {   exclude group: 'com.android.support'   exclude module: 'support-v4' } 
Read More

Friday, July 27, 2018

Discrepancy building project in Android Studio vs Gradle

Leave a Comment

I have a complex Android project consisting of multiple Java and C++ modules and using several build tools (e.g. CMake, swig). The project builds just fine when built from the command line using ./gradlew clean assembleDebug but fails to build when built from Android Studio. I cleaned, invalidated caches, synced, etc to no avail.

Important to note: this project builds fine in Android Studio too on other systems like Ubuntu (17.* and 18.*) but fails on MacOS (10.13 but also earlier if I remember correctly).

Here is the error reported by Android Studio:

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':IndoorsLocator:runSwig'.     at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:84)     at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:55)     at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)     at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)     at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88)     at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:46)     at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)     at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)     at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)     at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)     at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:236)     at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:228)     at org.gradle.internal.Transformers$4.transform(Transformers.java:169)     at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)     at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)     at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:228)     at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:215)     at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:77)     at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:58)     at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:32)     at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:113)     at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)     at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)     at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)     at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)     at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)     at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)     at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)     at org.gradle.initialization.DefaultGradleLauncher$3.execute(DefaultGradleLauncher.java:196)     at org.gradle.initialization.DefaultGradleLauncher$3.execute(DefaultGradleLauncher.java:193)     at org.gradle.internal.Transformers$4.transform(Transformers.java:169)     at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)     at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)     at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:193)     at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:119)     at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:102)     at org.gradle.launcher.exec.GradleBuildController.run(GradleBuildController.java:71)     at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:50)     at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)     at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:43)     at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:40)     at org.gradle.internal.Transformers$4.transform(Transformers.java:169)     at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)     at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)     at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)     at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:75)     at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)     at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)     at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)     at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)     at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)     at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:44)     at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:29)     at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)     at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)     at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:47)     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)     at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)     at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)     at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)     at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)     at org.gradle.util.Swapper.swap(Swapper.java:38)     at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)     at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)     at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)     at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)     at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)     at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)     at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)     at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)     at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)     at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)     at java.lang.Thread.run(Thread.java:745) Caused by: org.gradle.process.internal.ExecException: A problem occurred starting process 'command 'swig''     at org.gradle.process.internal.DefaultExecHandle.setEndStateInfo(DefaultExecHandle.java:198)     at org.gradle.process.internal.DefaultExecHandle.failed(DefaultExecHandle.java:329)     at org.gradle.process.internal.ExecHandleRunner.run(ExecHandleRunner.java:86)     ... 5 more Caused by: net.rubygrapefruit.platform.NativeException: Could not start 'swig'     at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:27)     at net.rubygrapefruit.platform.internal.WrapperProcessLauncher.start(WrapperProcessLauncher.java:36)     at org.gradle.process.internal.ExecHandleRunner.run(ExecHandleRunner.java:68)     ... 5 more Caused by: java.io.IOException: Cannot run program "swig" (in directory "/Users/tom/workspace/indoors-scripts/setup-scripts/workspace-android/IndoorsAndroid/IndoorsLocator"): error=2, No such file or directory     at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)     at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:25)     ... 7 more Caused by: java.io.IOException: error=2, No such file or directory     at java.lang.UNIXProcess.forkAndExec(Native Method)     at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)     at java.lang.ProcessImpl.start(ProcessImpl.java:134)     at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)     ... 8 more 

build failing in Android Studio

On the command line: build going through via command line (note we are passed "IndoorsLocator:runSwig" already)

Here is what the definition of "runSwig"-task looks like:

task runSwig(type: Exec) {     commandLine 'swig'      doFirst {         coreWrapperDir.mkdirs()     }      def swigFileCore = "${projectDir}/src/" + "swig.i"     def headerFiles = "${projectDir}/include"     def swigWrapFile = 'src/swig_wrap.cxx'      inputs.file swigFileCore     inputs.dir headerFiles     outputs.dir coreWrapperDir.absolutePath     outputs.file swigWrapFile      // this write the generated swig C++ file to "${projectDir}/src"     args '-c++', '-java', '-package', javaPackage, '-noexcept', '-outdir', coreWrapperDir.absolutePath, "-I${headerFiles}", '-o', swigWrapFile, swigFileCore } 

The log indicates that Android Studio is looking for swig in the current working directory instead of looking it up inside $PATH, but I am clueless about how to tell Android Studio where to look instead. Any ideas?

Cannot run program "swig" (in directory "/Users/tom/workspace/indoors-scripts/setup-scripts/workspace-android/IndoorsAndroid/IndoorsLocator") 

3 Answers

Answers 1

Have you added this line in your build.gradle?

tasks.withType(JavaCompile) {     compileTask -> compileTask.dependsOn runSwig } 

Anyway you can refer to this github's project that uses swig: https://github.com/sureshjoshi/android-ndk-swig-example

Answers 2

There is a need for some debugging to get more info about the problem. Add the code below to your build.gradle file of IndoorsLocator module and run it again. This should print the path environment variable and also run a java command which I'm assuming is also within the path. Then perform a gradle sync and compile or run the code. Open the build window as in your first image and when the build stops, find the testPath within the Run tasks list and share it's output. Or more preferably, switch the Build to text view as in the image below and share the complete log. Testing it from the command would also help to make sure that it's running as expected.

tasks.whenTaskAdded { addedTask ->     if (addedTask.name.startsWith("preDebugBuild")) {         addedTask.dependsOn 'testPath'     } }  task testPath {     mustRunBefore 'checkDebugManifest'     doLast {         exec {             commandLine 'echo', '$PATH'         }         exec {             commandLine 'java', '-version'         }     } } 

enter image description here

Update 1

Based on your first comment, this is a weird outcome! Java is supposed to be in the path, so $PATH must've been set somehow yet echo $PATH didn't work. Updated the code to further go down the rabbit hole.

tasks.whenTaskAdded { addedTask ->     if (addedTask.name.startsWith("preDebugBuild")) {         addedTask.dependsOn 'testPath'     } }  task testPath {     doLast {         exec {             commandLine 'printenv'         }         exec {             commandLine 'which', 'java'         }         exec {             commandLine 'which', 'swig'         }     } } 

PS: my mistake on the mustRunBefore, it doesn't exist and I added it accident!

Answers 3

Turns out this is due to a "bug" in OSX: https://github.com/gradle/gradle/issues/5631#issuecomment-401775152

I did not find a way to easily fix it for the latest version of OSX (https://apple.stackexchange.com/questions/106355/setting-the-system-wide-path-environment-variable-in-mavericks) but worked around it by hardcoding the path in build.gradle:

task runSwig(type: Exec) {     // workaround for OSX, see https://stackoverflow.com/q/51383822/198996     File testFile = new File('/usr/local/bin/swig');     if (testFile.isFile()) {         commandLine '/usr/local/bin/swig'     } else {         commandLine 'swig'     } } 

That's an awful workaround if you ask me, so I would be happy to award the bounty to whoever comes up with a cleaner solution.

Read More

Sunday, May 27, 2018

Gradle: Using setIgnore on a local library based on the apps build.gradle flavor.

Leave a Comment

How do I use setIgnore on a local library either from the apps build.gradle or the library build.gradle based on the apps flavor. I am not sure if I can reference the apps build.gradle flavor/dimension from the library build.gradle. I also don't know if I can reference a library from the apps build.gradle and use lib.setIgnore(true). Any solution to solving this issue?

I am currently only using one dimension for the application and multiple flavors.

This is how it is typically done; but I need to set Ignore on a library based on the apps flavor.

android {     ...     variantFilter { variant ->         if(variant.buildType.name == 'release' && variant.getFlavors().get(0).name == 'vanilla') {             variant.setIgnore(true)         }     } }  

2 Answers

Answers 1

Maybe you can use the library only when you need.

dependencies {    // use "mylib" for debug    debugImplementation project(path: ':mylib')    // all the flavors    implementation "com.android.support:appcompat-v7:28.0.0' } 

Answers 2

You can try to wait for the task graph to be assembled and then removes the undesired name pattern as follows:

gradle.taskGraph.whenReady { graph ->   graph.allTasks.findAll { it.name ==~ /.*vanilla.*/ }*.enabled = false } 
Read More

Monday, March 26, 2018

Add folder to srcDir except for one file in gradle

Leave a Comment

I'm developing an android app with multiple flavors like so:

sourceSets {     main {         res.srcDirs += ["headend/ott/res"]     }      flavor1 {         res.srcDirs += ["src/module1/res-splash"]     }      flavor2 {         java.srcDirs += ["src/module1/java"]         res.srcDirs += ["src/module1/res"]         res.srcDirs += ["src/module2/res"]         assets.srcDirs += ["src/module1/assets"]     }      test {         res.srcDirs += ["src/test/resources"]     }     ... 

My problem is that, in flavor2, some of the module2 resources are supposed to be replacements of ones already present in module1, but with my current approach it causes the build to fail with duplicate resources.

So what I need is a way to add "src/module1/res" to flavor2 but without including one specific file.

I've tried

res{     srcDirs += ["src/module1/res"]     res.srcDirs += ["src/module1/res"]             exclude 'src/module1/res/drawable/specific_file.xml' } 

But to no avail.

Is this possible at all?

2 Answers

Answers 1

After looking at multiple answers like this, the code that you have looks correct to me. However, this bug stating that exclude paths are not implemented is still open.

This alternate approach which references these docs may work for you instead. I suggest adding a resource directory inside your flavour2 directory/module and using it to include a discard file.

sourceSets {     flavor2 {         res {             srcDirs += ["src/module1/res"]             srcDirs += ["src/module2/res"]         }     }  } 

Then add resources_discard.xml to module2/res/raw with the following:

<?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools"           tools:discard="@drawable/specific_file.xml" /> 

Answers 2

Try doing this. In one of my projects, I was able to exclude java file from compiling by not using the srcDir path in the exclude path. exclude usually works without appending the srcDir path.

res{     srcDirs += ["src/module1/res"]     res.srcDirs += ["src/module1/res"]             exclude 'drawable/specific_file.xml' } 
Read More

Sunday, February 25, 2018

Android studio | Dependency Management

Leave a Comment

Can anyone suggest, how can we add a dependency at build time in android gradle based on some condition like:

dependencies{        if(someCondition){            // add dependency        }     } 

Thanks in advance!!

1 Answers

Answers 1

I found a solution for this:

Step1: Declare a boolean variable in gradle at root level.

like: def someDependencyEnabled = true //This could be dynamically set. 

Step2: Using this boolean variable we can apply a check like:

if(someDependencyEnabled){     //Add some dependency } else {     //Add some other dependency } 
Read More

Wednesday, January 10, 2018

Compile or build Library’s build.gradle file when we compile or build Main project

Leave a Comment

I am having one Library Project which is developed by me, inside Library, in gradle file I have mentioned one specific task, like show the root project and library project path.

Now when I am adding this Library to my other project and when I build the project, I wanted to build the Library gradle file so that it performs the task which I have mentioned in Library gradle file.

There is one library inside that library, I have one plugin,

// automatic code generation apply plugin: 'jsonschema2pojo'  // automatic code generation buildscript {     repositories {         jcenter()         mavenLocal()      }     dependencies {         classpath 'org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:0.5.1'         //classpath 'org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:latest.integration'      } }  // automatic code generation // Each configuration is set to the default value jsonSchema2Pojo {     generateBuilders = false     usePrimitives = false     source = files("${rootProject.projectDir}/schema/schema/")     targetPackage = 'com.model'     propertyWordDelimiters = [] as char[]     useLongIntegers = false     useDoubleNumbers = true     includeHashcodeAndEquals = true     includeToString = true     annotationStyle = 'gson'     customAnnotator = 'org.jsonschema2pojo.NoopAnnotator'     includeJsr303Annotations = true     sourceType = 'json'     boolean removeOldOutput = true     String outputEncoding = 'UTF-8'     boolean useJodaDates = false     boolean useCommonsLang3 = false     boolean initializeCollections = true }   dependencies {     compile fileTree(include: ['*.jar'], dir: 'libs')     androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {         exclude group: 'com.android.support', module: 'support-annotations'     })      //  code generation     compile 'org.glassfish:javax.annotation:10.0-b28'     compile 'commons-lang:commons-lang:2.6'     compile 'javax.validation:validation-api:1.1.0.CR2'      testCompile 'junit:junit:4.12' } 

Now, I want this code or Gradle to build while I add this library to my other project.

0 Answers

Read More

Saturday, December 16, 2017

Duplicate value fo resource 'attr/tint'

Leave a Comment

I do not know how this error started to happen, I simply closed the android studio yesterday and I turned off the pc, today, I turned on the pc and opened the android studio, then this error appeared soon after opening the android studio.

What have I tried?

invalidate cache

rename and delete files that look like duplicates.

delete .gradle and clear / rebuild project

C:\Users\joaoa.gradle\caches\transforms-1\files-1.1\appcompat-v7-27.0.1.aar\70b6446a0ad42e67664086d0c5dca4d5\res\values\values.xml

C:\Users\joaoa\Desktop\MyPast\myProjects\project001\app\build\intermediates\incremental\mergeDebugResources\merged.dir\values\values.xml

Error:java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details

Error:Execution failed for task ':app:mergeDebugResources'. Error: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details

4 Answers

Answers 1

Please open show log in files and delete all the files where you located and please restart your android studio.

if not solved then Again restart with option like InvalidDate Cache and Restart.

Hope this helps you.

Answers 2

check dependencies in gradle file.

2 or more libraries use in project conflict resource file.

example:

in library A,B in variables in arrts.xml or color.xml

Answers 3

I don't think this is a gradle version issue... I am using Android Studio 3.0 with Gradle Plugin Version 3.0.1 (which uses Gradle 4.1) THE LATEST. And I am getting this same issue. Just rename whatever attribute you've named tint to something like libTint or lib_tint or even more obscure ili_lib_tint so the issue can be resolved. I really want to use this lib and not look else where, please.

This is the xml element causing the issue

ImageLetterIcon/imageletter/src/main/res/values/attrs.xml

 <declare-styleable name="TintableImageView"> 

Answers 4

Android studio creates many files that are not part of the normal source code. If you reboot without saving your project things may get whacked out but this could happen for no apparent reason. You have already cleaned your project so it regenerates some of these files. The .metadata file in the root of your workspace can be deleted but you will need to import all projects already in the workspace. I suggest you check the directory structure of your project using something other than android studio and even delete any generated folders as they will rebuild on the next compile. Perhaps even use a new workspace and copy source code over. First thing you should do is backup everything you want to keep as these suggestions could cause disaster if you are not careful. Consider version control, git repositories or github to save your project in the future as you can roll back to a previous state in the future

Read More

Friday, December 15, 2017

Gradle buildSrc and buildscript

Leave a Comment

We have a Gradle build that includes a buildSrc with some custom plugins. Those plugins apply yet other plugins. For example, our plugin applies com.android.tools.build:gradle. For annotation processing that library needs to be on Gradle's classpath during compilation. So, putting this in our main build.gradle works:

buildscript {     repositories {         google()     }     dependencies {        classpath "com.android.tools.build:gradle:$gToolsVersion"     } } 

However, that means that for a user to apply this plugin they must (1) apply our plugin and (2) add that buildscript boilerplate. It seems like that shouldn't be necessary. We can also add a project.buildscript block inside our plugin but that too seems unnecessary and, due to this bug is problematic: https://developer.android.com/studio/build/gradle-plugin-3-0-0.html?utm_source=android-studio#known_issues.

I added the com.android.tools.build:gradle dependency to buildSrc/build.gradle as a runtime dependency. It seems like that should work: I thought that tells Gradle that in order to run my plugin that library (and its dependencies) need to be on the classpath. However, gradle buildEnvironment (and the fact that our build fails) makes it clear that's not the case.

So, questions:

  1. What's the difference between a runtime dependency specified in buildSrc/build.gradle and a classpath dependency specified in a buildscript block in a regular build.gradle?
  2. How can I arrange things so that users can apply the plugin from buildSrc and not have to also add the buildscript block to their build.gradle?

0 Answers

Read More

Monday, December 4, 2017

Download and commit gradle dependencies and plugins in Android Studio

Leave a Comment

This is an excerpt from a build.gradle file for one of my modules. I'm using android-studio-1.5.1 and gradle 2.10.

dependencies {     compile fileTree(dir: 'libs', include: ['*.jar'])     testCompile 'junit:junit:4.12'     compile 'com.android.support:appcompat-v7:23.2.1'     compile 'com.android.support:design:23.2.1'     compile 'com.google.android.gms:play-services-gcm:9.0.0'     compile 'com.squareup.picasso:picasso:2.5.2' } 

I also have classpath 'com.google.gms:google-services:3.0.0' in the project level build.gradle file.

I'm trying to gather all the associated jars into a directory which I can commit to my git repo. Something like:

task copyRuntimeLibs(type: Copy) {     into "${projectDir}/libs"     from configurations.compile } 

(This does not work) Also, I'm not trying to download the sources or javadocs.

I need to be able to commit all dependencies so that the project can be shared on an intranet without internet access.

1 Answers

Answers 1

I've written a plugin which will download all jars and poms. See the code here to download all jars and all poms from a Gradle Configuration

Note: There's a failing test here which shows that the parent pom's are not being downloaded. I've raised an issue here on Gradle's github.

I will likely improve the plugin to invoke the Maven Model Builder APIs to get the parent poms.

FYI - I've already integrated the ModelBuilder APIs successfully with Gradle (see here and here) so shouldn't be too difficult.

Read More

Tuesday, October 31, 2017

Cannot build for android using react-native

Leave a Comment

I'm trying to run react-native run-android but I continuously get this error.I am running on emulator . I started the app using react-native init.

PS: I am running on proxy.

When I am trying to run

react-native run-android

I get:

FAILURE: Build failed with an exception.  *  What went wrong:  A problem occurred configuring root project 'AwesomeProject'.  > Could not resolve all dependencies for configuration ':classpath'.  > Could not resolve com.android.tools.build:gradle:2.2.3.  Required by:      :AwesomeProject:unspecified   > Could not resolve com.android.tools.build:gradle:2.2.3.      > Could not get resource 'https://jcenter.bintray.com/com/android/tool /build/gradle/2.2.3/gradle-2.2.3.pom'.         > Could not GET 'https://jcenter.bintray.com/com/android/tools/buil  /gradle/2.2.3/gradle-2.2.3.pom'. Received status code 407 from server:   Proxy Authentication Required 

When I am trying to run

directly in Android Studio

I get:

Error:Could not GET  'https://jcenter.bintray.com/com/android/tools/build/gradle/2.2.3/gradle- 2.2.3.pom'. Received status code 407 from server: Proxy Authentication   Required <a href="toggle.offline.mode">Enable Gradle 'offline mode' and sync  project</a> 

I have my node_modules installed and I'm not sure what else to try, I've been googling for the last 4 hours and have come up with nothing.

4 Answers

Answers 1

your problem is not related to npm and node. you have some gradle problems.check if you can access the URL from browser?

https://jcenter.bintray.com/com/android/tools/build/gradle/2.2.3/gradle- 2.2.3.pom

Answers 2

set your proxy details Inside sdk manager

AndroidStudio->tools->Android->SDKManager->system settings->Http Proxy

Answers 3

It clearly says <a href="toggle.offline.mode">Enable Gradle 'offline mode' and sync project</a>. Have you tried enabling offline mode? If not, try this:

Go to File -> Settings.

And open the 'Build,Execution,Deployment',Then open the 'Build Tools' -> 'Gradle'.

Then uncheck "Offline work" on the right.

Click the 'OK' button.

Then Rebuild the Project.

For Mac go to AndroidStudio -> Preferences, rest is same.

ref.: https://stackoverflow.com/a/30794890/2895571

Answers 4

Try adding these in your gradle.properties:

systemProp.http.proxyHost=proxyURL systemProp.http.proxyPort=proxyPort systemProp.http.proxyUser=USER systemProp.http.proxyPassword=PASSWORD systemProp.https.proxyHost=proxyUrl  systemProp.https.proxyPort=proxyPort systemProp.https.proxyUser=USER systemProp.https.proxyPassword=PASSWORD 
Read More

Tuesday, October 17, 2017

Where can I find latest gradle version in android studio?

Leave a Comment

When I try to build the Project 1, I get the following error. It seems that both gradle-3.0.0-beta6 and gradle-3.0.0-beta9 are unavailable.

Where can I find latest gradle version in android studio? Could you tell me a URL which can list all available gradle versions?

Error:Could not find com.android.tools.build:gradle:3.0.0-beta6. Searched in the following locations:     file:/E:/Android_Studio_3.1/gradle/m2repository/com/android/tools/build/gradle/3.0.0-beta6/gradle-3.0.0-beta6.pom     file:/E:/Android_Studio_3.1/gradle/m2repository/com/android/tools/build/gradle/3.0.0-beta6/gradle-3.0.0-beta6.jar     https://jcenter.bintray.com/com/android/tools/build/gradle/3.0.0-beta6/gradle-3.0.0-beta6.pom     https://jcenter.bintray.com/com/android/tools/build/gradle/3.0.0-beta6/gradle-3.0.0-beta6.jar 

Project 1

buildscript {     ext.support_version =  '26.0.0'     ext.kotlin_version = '1.1.4-3'     ext.anko_version = '0.10.1'       repositories {         jcenter()     }     dependencies {         classpath 'com.android.tools.build:gradle:gradle-3.0.0-beta6'         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"     } }  allprojects {     repositories {         jcenter()         maven { url 'https://maven.google.com' }     } } 

3 Answers

Answers 1

Use + sign instead of version no. It will automatically picks the latest one available

dependencies {     classpath 'com.android.tools.build:gradle:+'     classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } 

See here for release/version information of gradle android plugin: https://bintray.com/android/android-tools/com.android.tools.build.gradle/view


But if you want to install a specific version.Check the url below.

https://services.gradle.org/distributions/

Here you can found the one you required. FYI beta versions are not available. enter image description here

Inside your Android Studio's project tree, open the file gradle/wrapper/gradle-wrapper.properties. Change this entry to the one you need:

distributionUrl=http://services.gradle.org/distributions/gradle-2.1-all.zip

Answers 2

As per official documents : You should not use dynamic dependencies in version numbers, such as 'com.android.tools.build:gradle:2.+'. Using this feature can cause unexpected version updates and difficulty resolving version differences.

If the specified plugin version has not been downloaded, Gradle downloads it the next time you build your project or click Tools > Android > Sync Project with Gradle Files from the Android Studio menu bar.

Update Gradle

When you update Android Studio, you may receive a prompt to also update Gradle to the latest available version. You can choose to accept the update or manually specify a version based on your project's build requirements.

The following table lists which version of Gradle is required for each version of the Android plugin for Gradle. For the best performance, you should use the latest possible version of both Gradle and the Android plugin.

Plugin version      Required Gradle version 1.0.0 - 1.1.3       2.2.1 - 2.3 1.2.0 - 1.3.1       2.2.1 - 2.9 1.5.0               2.2.1 - 2.13 2.0.0 - 2.1.2       2.10 - 2.13 2.1.3 - 2.2.3       2.14.1+ 2.3.0+              3.3+ 

For More information Click here

Answers 3

This error is for Android Plugin Version for gradle, not Gradle Version!

Gradle Version

You can find all gradle release versions at its github release page( Read Upgrade Instructions section)

You should set gradle version in gradle-wrapper.properties file:

distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip 

Or from Android Studio: file>Project Structure>Project>gradle version

enter image description here

Android plugin version

But Android plugin version for gradle depends on Android Studio & Gradle version and Android Studio prompt you to update it ( if you open an old project or if you update your android studio)

You can find its version at Android Plugin for Gradle Release Notes

You can specify the Android plugin for Gradle version in either the File > Project Structure > Project menu in Android Studio, or the top-level build.gradle file. The following example sets the Android plugin for Gradle to version 2.3.3 from the build.gradle file:

buildscript {  ...    dependencies {        classpath 'com.android.tools.build:gradle:2.3.3'    } } 

Plugin version & Required Gradle version

enter image description here

Read More

Tuesday, August 15, 2017

How to exclude res folder from gradle build flavours?

Leave a Comment

I have a requirement to remove a specific res folder from a flavour.

sourceSets {     main {         manifest.srcFile 'AndroidManifest.xml'         java.srcDirs = ['src']         res.srcDirs = ['res']         aidl.srcDirs = ['src']         assets.srcDirs = ['assets']     } }  productFlavors {     flavor1 {         sourceSets {             flavor1 {                 resources {                     exclude 'res/drawable-mdpi/*'                 }             }         }     }     flavorDimensions "flavor" } 

But still drawable-mdpi folder is coming to the apk.

So could anyone please specify what mistake am I making.

Thanks Vivek

2 Answers

Answers 1

I finally solved this problem!

I have found this link.

And did this:

  1. add an xml file to res/raw folder. I named it resources_discard.xml, here is it:

    <?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:discard="@raw/hd/*" /> 
  2. this file is placed in a correct directory structure for my flavor called lite "scr/lite/res/raw"

This way, contents of res/hd folder are not included in lite builds, effectively reducing my lite build apk size by 50%

UPD: to exclude some images from different flavors, u have to put the images in assets folder, and in gradle declare:

    flavor {         aaptOptions {             ignoreAssetsPattern '/folder:*.jpg:*.png' //use : as delimiter          }     } 

also i learned that you cant have subfolders in /raw folder.

Answers 2

You could try using splits.

Example (Right from the android SDK webpage):

android {   ...   splits {      // Configures multiple APKs based on screen density.     density {        // Configures multiple APKs based on screen density.       enable true        // Specifies a list of screen densities Gradle should not create multiple APKs for. Here you should add all the densities except MDPI.       exclude "ldpi", "xxhdpi", "xxxhdpi"        // Specifies a list of compatible screen size settings for the manifest.       compatibleScreens 'small', 'normal', 'large', 'xlarge'     }   } } 

If that does not work, you could separate your res/MDPI and the rest of the res/Density folders into two separate modules (let's call them, layoutMdpi and layoutAll). Both modules need to have the same package name so their R classes are identical and interchangeable (essentially the same that happens between different versions of the android SDK). Then, create at least two specific dependency configurations for your flavors, one for the ones who should use MDPI, and one for those who should not.

configurations {     mdpiCompile     allCompile }  dependencies {     ...     mdpiCompile project(':layoutMdpi')     allCompile project(':layoutAll') } 

And then, since MDPI resources aren't present in layoutAll, you are good to go.

Read More

Thursday, July 27, 2017

Force to use same certificate to sign different “buildTypes” that are configured for a particular “productFlavor”?

Leave a Comment

Background:

I am generating builds using build variant. Below are the configurations:

signingConfigs {     production {         storeFile file("some_path/buildsystem/keystore/some.release.keystore.jks")         storePassword "somepassword"         keyAlias "somekeyalias"         keyPassword "some"         v2SigningEnabled false     }      develop {         storeFile file(".some_path./buildsystem/keystore/someother.debug.keystore.jks")         storePassword "someother"         keyAlias "someotherkeyalias"         keyPassword "someother"         v2SigningEnabled false     } }  productFlavors {     production {         signingConfig signingConfigs.production       }      develop {         applicationIdSuffix ".develop"         signingConfig signingConfigs.develop      } }  buildTypes {     debug {         minifyEnabled false     }      release {         minifyEnabled false         proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'     } } 

Problem

As, of now for example if I talk about flavour production then productionRelease uses signingConfigs.production to sign the apk. But, productionDebug doesn't uses signingConfigs.production.

Expected output

When I generate the signed apk I want the gradle to do the following for me:

  1. developRelease and developDebug should be signed with only signingConfigs.develop

  2. productionRelease and productionDebug should be signed with only signingConfigs.production

Another question that is similar to this which led me to do the above: SHA-1 different for buildTypes (debug and release) for same productFlavors Firebase?

1 Answers

Answers 1

Remove the signingConfig signingCongigs.develop elsewhere in the code block

And add new property within the buildTypes like

  • production
  • develop

Now add signingConfig to it

Thereby your updated gradle file look like as below

signingConfigs {     production {         storeFile file("some_path/buildsystem/keystore/some.release.keystore.jks")         storePassword "somepassword"         keyAlias "somekeyalias"         keyPassword "some"         v2SigningEnabled false     }      develop {         storeFile file(".some_path./buildsystem/keystore/someother.debug.keystore.jks")         storePassword "someother"         keyAlias "someotherkeyalias"         keyPassword "someother"         v2SigningEnabled false     } } productFlavors {     production {     }      develop {         applicationIdSuffix ".develop"     } } buildTypes {     /* NOTE: the debug block is not required because it is a default  * buildType configuration; all of its settings are defined implicitly  * by Gradle behind the scenes.  */     debug {         minifyEnabled false     }      release {         minifyEnabled false         proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'         signingConfig signingConfigs.production     }      production {         minifyEnabled false         proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'         signingConfig signingConfigs.production     }      develop {         minifyEnabled false         signingConfig signingConfigs.develop     } } 

In the terminal use the below gradle commmand: gradle assembleProduction to generate build with production certificates similarly gradle assembleDevelop or you can also use gradle assemble

You cannot force gradle to choose the certificates for debug property rather you could create own buildTypes

As per documentation

Automate signing your applications. Debug build variants are, by default, signed with a debug key for installation on development devices. Declare additional signing configurations for publication to the Google Play store.

Read More

Saturday, July 22, 2017

Android Studio Gradle failing during build

Leave a Comment

Here is my problem scenario:

I am not able to build and run my app within android studio. It seems to fail before installing the apk with the error below. However when I build the app through command line with the gradle wrapper, things go smoothly. Obviously this isn't ideal, as other team members need to use the project, and the IDE UI for android studio should be enough.

When I build and run my app in Android Studio I am getting an error during build steps:

transformClassesAndResourcesWithProguardForRelease FAILED   path may not be null or empty: path='null' 

However when I invoke command:

./gradlew cleanRelease assembleRelease installRelease, 

This builds and installs the working version on the device.

I can also Build->Generate Signed Apk and this works.

So pressing the Run Button (>) on android studio is the only thing that doesn't work ... Weird thing is it works when I specify only one abi, but when I put all three it doesn't work.

My questions are :

Why is this message showing up ?? What path is null ?? And how to fix this.

apply plugin: 'com.android.application'  ////Grab location of opencv sdk String systemHome = System.getenv('HOME'); File libDir = new File(systemHome + "/Library/Android/sdk/OpenCV-android-sdk");  //If home directory exists choose this path, otherwise we're doing CI  //with jenkins so we can hardcode this ... String opencvSdkPath =     (libDir != null && libDir.isDirectory()) ?             systemHome + "/Library/Android/sdk/OpenCV-android-sdk/sdk/native/libs"             :             "/Users/userx/Library/Android/OpenCV-android-sdk/sdk/native/libs";  println("Look for opencv within " + opencvSdkPath)  android { signingConfigs {     XSigningCredentials {         keyAlias 'asdfsdf'         keyPassword 'asdfasdf'         storeFile file('asdfsdf.jks')         storePassword 'asdfsdf'     } } compileSdkVersion 25 buildToolsVersion '25.0.2' //Give the default configurations for gradles build defaultConfig {     //Package name     applicationId "a.b.c"      //Minimum working sdk     minSdkVersion 19      //Target sdk with support     targetSdkVersion 25      //Actual version ID     versionCode vrsCode as Integer      //Google play visible version string     versionName vrsCustomerFacingCode      multiDexEnabled true      ndk {         abiFilters 'armeabi', 'armeabi-v7a', 'x86'     }     externalNativeBuild {         cmake {             cppFlags "-std=c++11" ,                     "-latomic",                     "-DASSIMP_BUILD_NO_X_IMPORTER",                     "-DASSIMP_BUILD_NO_3DS_IMPORTER",                     "-DASSIMP_BUILD_NO_MD3_IMPORTER",                     "-DASSIMP_BUILD_NO_MDL_IMPORTER",                     "-DASSIMP_BUILD_NO_MD2_IMPORTER",                     "-DASSIMP_BUILD_NO_PLY_IMPORTER",                     "-DASSIMP_BUILD_NO_ASE_IMPORTER",                     "-DASSIMP_BUILD_NO_HMP_IMPORTER",                     "-DASSIMP_BUILD_NO_SMD_IMPORTER",                     "-DASSIMP_BUILD_NO_MDC_IMPORTER",                     "-DASSIMP_BUILD_NO_MD5_IMPORTER",                     "-DASSIMP_BUILD_NO_STL_IMPORTER",                     "-DASSIMP_BUILD_NO_LWO_IMPORTER",                     "-DASSIMP_BUILD_NO_DXF_IMPORTER",                     "-DASSIMP_BUILD_NO_NFF_IMPORTER",                     "-DASSIMP_BUILD_NO_RAW_IMPORTER",                     "-DASSIMP_BUILD_NO_OFF_IMPORTER",                     "-DASSIMP_BUILD_NO_AC_IMPORTER",                     "-DASSIMP_BUILD_NO_BVH_IMPORTER",                     "-DASSIMP_BUILD_NO_IRRMESH_IMPORTER",                     "-DASSIMP_BUILD_NO_IRR_IMPORTER",                     "-DASSIMP_BUILD_NO_Q3D_IMPORTER",                     "-DASSIMP_BUILD_NO_B3D_IMPORTER",                     "-DASSIMP_BUILD_NO_COLLADA_IMPORTER",                     "-DASSIMP_BUILD_NO_TERRAGEN_IMPORTER",                     "-DASSIMP_BUILD_NO_CSM_IMPORTER",                     "-DASSIMP_BUILD_NO_3D_IMPORTER",                     "-DASSIMP_BUILD_NO_LWS_IMPORTER",                     "-DASSIMP_BUILD_NO_OGRE_IMPORTER",                     "-DASSIMP_BUILD_NO_MS3D_IMPORTER",                     "-DASSIMP_BUILD_NO_COB_IMPORTER",                     "-DASSIMP_BUILD_NO_Q3BSP_IMPORTER",                     "-DASSIMP_BUILD_NO_NDO_IMPORTER",                     "-DASSIMP_BUILD_NO_IFC_IMPORTER",                     "-DASSIMP_BUILD_NO_XGL_IMPORTER",                     "-DASSIMP_BUILD_NO_FBX_IMPORTER",                     "-DASSIMP_BUILD_NO_C4D_IMPORTER",                     "-DASSIMP_BUILD_NO_OPENGEX_IMPORTER",                     "-DASSIMP_BUILD_NO_ASSBIN_IMPORTER",                     "-DASSIMP_BUILD_NO_BLEND_IMPORTER",                     "-DASSIMP_BUILD_NO_GEO_IMPORTER",                     "-DANDROID -fPIC",                     "-DANDROID -fsigned-char",                     "-mstackrealign",                     "-O2",                     "-fexceptions",                     "-frtti"              cFlags "-latomic",                     "-DASSIMP_BUILD_NO_X_IMPORTER",                     "-DASSIMP_BUILD_NO_3DS_IMPORTER",                     "-DASSIMP_BUILD_NO_MD3_IMPORTER",                     "-DASSIMP_BUILD_NO_MDL_IMPORTER",                     "-DASSIMP_BUILD_NO_MD2_IMPORTER",                     "-DASSIMP_BUILD_NO_PLY_IMPORTER",                     "-DASSIMP_BUILD_NO_ASE_IMPORTER",                     "-DASSIMP_BUILD_NO_HMP_IMPORTER",                     "-DASSIMP_BUILD_NO_SMD_IMPORTER",                     "-DASSIMP_BUILD_NO_MDC_IMPORTER",                     "-DASSIMP_BUILD_NO_MD5_IMPORTER",                     "-DASSIMP_BUILD_NO_STL_IMPORTER",                     "-DASSIMP_BUILD_NO_LWO_IMPORTER",                     "-DASSIMP_BUILD_NO_DXF_IMPORTER",                     "-DASSIMP_BUILD_NO_NFF_IMPORTER",                     "-DASSIMP_BUILD_NO_RAW_IMPORTER",                     "-DASSIMP_BUILD_NO_OFF_IMPORTER",                     "-DASSIMP_BUILD_NO_AC_IMPORTER",                     "-DASSIMP_BUILD_NO_BVH_IMPORTER",                     "-DASSIMP_BUILD_NO_IRRMESH_IMPORTER",                     "-DASSIMP_BUILD_NO_IRR_IMPORTER",                     "-DASSIMP_BUILD_NO_Q3D_IMPORTER",                     "-DASSIMP_BUILD_NO_B3D_IMPORTER",                     "-DASSIMP_BUILD_NO_COLLADA_IMPORTER",                     "-DASSIMP_BUILD_NO_TERRAGEN_IMPORTER",                     "-DASSIMP_BUILD_NO_CSM_IMPORTER",                     "-DASSIMP_BUILD_NO_3D_IMPORTER",                     "-DASSIMP_BUILD_NO_LWS_IMPORTER",                     "-DASSIMP_BUILD_NO_OGRE_IMPORTER",                     "-DASSIMP_BUILD_NO_MS3D_IMPORTER",                     "-DASSIMP_BUILD_NO_COB_IMPORTER",                     "-DASSIMP_BUILD_NO_Q3BSP_IMPORTER",                     "-DASSIMP_BUILD_NO_NDO_IMPORTER",                     "-DASSIMP_BUILD_NO_IFC_IMPORTER",                     "-DASSIMP_BUILD_NO_XGL_IMPORTER",                     "-DASSIMP_BUILD_NO_FBX_IMPORTER",                     "-DASSIMP_BUILD_NO_C4D_IMPORTER",                     "-DASSIMP_BUILD_NO_OPENGEX_IMPORTER",                     "-DASSIMP_BUILD_NO_ASSBIN_IMPORTER",                     "-DASSIMP_BUILD_NO_BLEND_IMPORTER",                     "-DASSIMP_BUILD_NO_GEO_IMPORTER",                     "-DANDROID -fPIC",                     "-DANDROID -fsigned-char",                     "-mstackrealign",                     "-O2",                     "-fexceptions",                     "-frtti"              arguments "-DANDROID_STL=gnustl_shared"          }     } } splits {      // Configures screen ABI split settings      abi {          // Enable ABI APK splits         enable true          // Resets the list of ABIs that Gradle should create APKs for to none         reset()          // Specifies a list of ABIs that Gradle should create APKs for         include "armeabi", "armeabi-v7a", "x86"          // Specify that we do not want to also generate a universal APK that includes all ABIs         universalApk false     }  } buildTypes {     release {         proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'         signingConfig signingConfigs.XSigningCredentials         minifyEnabled true     }     debug {         debuggable true         minifyEnabled false     } } packagingOptions {     exclude 'META-INF/services/javax.annotation.processing.Processor'     pickFirst 'META-INF/maven/org.bytedeco.javacpp-presets/opencv/pom.properties'     pickFirst 'META-INF/maven/org.bytedeco.javacpp-presets/opencv/pom.xml'     pickFirst 'META-INF/maven/org.bytedeco.javacpp-presets/ffmpeg/pom.properties'     pickFirst 'META-INF/maven/org.bytedeco.javacpp-presets/ffmpeg/pom.xml' } dexOptions {     javaMaxHeapSize "2g" } externalNativeBuild {     cmake {         path 'CMakeLists.txt'     } } sourceSets {     main {         jniLibs.srcDirs opencvSdkPath, 'src/main/jni/ffmpeg'     }     } } // map for the version code that gives each ABI a value ext.versionCodes = ['armeabi': 1, 'armeabi-v7a': 2, 'x86': 3]  // For each APK output variant, override versionCode with an ABI value  schema android.applicationVariants.all { variant ->     // assign different version code for each output     variant.outputs.each { output ->         output.versionCodeOverride =((project.versionCodes.get(output.getFilter(com.android.build.OutputFile.ABI)) * 1000000)                     + android.defaultConfig.versionCode) } }  repositories {     mavenCentral() }  configurations { all*.exclude group: 'org.bytedeco', module: 'javacpp-presets' }  dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile project(':openCVLibrary310') compile 'org.bytedeco.javacpp-presets:opencv:3.1.0-1.2' compile 'org.bytedeco.javacpp-presets:ffmpeg:3.0.2-1.2' compile 'com.squareup.okhttp3:okhttp:3.5.0' compile 'org.bytedeco.javacpp-presets:opencv:3.1.0-1.2' compile 'org.bytedeco.javacpp-presets:ffmpeg:3.0.2-1.2' compile 'com.squareup.okhttp3:okhttp:3.5.0' compile 'org.bytedeco:javacv:1.2' compile 'org.bytedeco:javacpp:1.2.4' compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support:design:25.3.1' compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.android.support:support-v4:25.3.1' compile 'com.facebook.android:facebook-android-sdk:[4,5)' compile 'com.android.support:multidex:1.0.1' compile 'com.google.firebase:firebase-core:11.0.2' compile 'com.google.firebase:firebase-crash:11.0.2' compile 'com.google.firebase:firebase-auth:11.0.2' compile 'com.google.android.gms:play-services-auth:11.0.2' compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4' compile 'com.desk:sdk:1.3.1' compile 'se.akerfeldt:okhttp-signpost:1.1.0' compile 'oauth.signpost:signpost-core:1.2.1.2' compile 'com.jakewharton.timber:timber:4.5.1' compile 'org.slf4j:slf4j-api:1.7.21' compile 'com.github.tony19:logback-android-core:1.1.1-6' compile 'com.github.tony19:logback-android-classic:1.1.1-6' testCompile 'junit:junit:4.12' }  apply plugin: 'com.google.gms.google-services' 

2 Answers

Answers 1

To debug why one of the Gradle tasks fail when pressing the Run button, you can enable command-line options in Android Studio -> Settings -> Build, Execution, Deployment -> Compiler. Set the Command-line options to --stacktrace --debug. Press the Run button and check the output in the Gradle Console window.

Possibly you have some dependency between the three ABIs that gets reset and affects the others, but it's hard to know without more logs.

Answers 2

I don't have reputation to comment. I would like to know if you are using Instant Run? Don't keep Instant run enabled when trying to build a release apk

Check here for more on Android studio - Instant run & Proguard

Read More

Wednesday, May 24, 2017

IllegalAccessError with CountingIdlingResource

Leave a Comment

The app contains a splash screen that displays briefly, and that activity is being tested with an instrumented test, using an IdlingResource so the test knows when the splash screen closes. The problem is that SplashActivity throws what looks like a dependency-related exception during test on devices running API 19:

import android.support.test.espresso.idling.CountingIdlingResource; ... private CountingIdlingResource espressoTestIdlingResource = new CountingIdlingResource("Splash_Delay"); // <-- Exception here line 22 ... 

app/build.gradle:

dependencies {     compile fileTree(dir: 'libs', include: ['*.jar'])     androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {         exclude group: 'com.android.support', module: 'support-annotations'         exclude group: 'com.google.code.findbugs'         exclude module: 'espresso-idling-resource'         exclude group: "javax.inject"     })     compile 'com.android.support.test.espresso:espresso-idling-resource:2.2.2'      compile 'com.google.dagger:dagger:2.10'     annotationProcessor 'com.google.dagger:dagger-compiler:2.10'     compile 'com.google.dagger:dagger-android:2.10'     compile 'com.google.dagger:dagger-android-support:2.10'     annotationProcessor 'com.google.dagger:dagger-android-processor:2.10'      compile "com.android.support:appcompat-v7:$supportLibraryVersion"     compile "com.android.support:design:$supportLibraryVersion"     compile "com.android.support.constraint:constraint-layout:1.0.2"      compile "com.jakewharton.timber:timber:4.5.1"     compile "com.squareup.phrase:phrase:1.1.0"     compile "com.squareup.retrofit2:retrofit:2.2.0"     compile "com.squareup.retrofit2:converter-gson:2.2.0"     compile "com.squareup.okhttp3:logging-interceptor:3.7.0"     compile 'net.danlew:android.joda:2.9.9'      testCompile 'junit:junit:4.12'     compile 'com.google.firebase:firebase-crash:10.2.4'     androidTestCompile 'junit:junit:4.12' } 

Exception:

java.lang.IllegalAccessError java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation     at com.myapp.android.ui.splash.SplashActivity.<init>(SplashActivity.java:22)     at java.lang.Class.newInstanceImpl(Native Method)     at java.lang.Class.newInstance(Class.java:1208)     at android.app.Instrumentation.newActivity(Instrumentation.java:1061)     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2101)     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)     at android.app.ActivityThread.accessX800(ActivityThread.java:135)     at android.app.ActivityThreadXH.handleMessage(ActivityThread.java:1196)     at android.os.Handler.dispatchMessage(Handler.java:102)     at android.os.Looper.loop(Looper.java:136)     at android.app.ActivityThread.main(ActivityThread.java:5001)     at java.lang.reflect.Method.invokeNative(Native Method)     at java.lang.reflect.Method.invoke(Method.java:515)     at com.android.internal.os.ZygoteInitXMethodAndArgsCaller.run(ZygoteInit.java:785)     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)     at dalvik.system.NativeStart.main(Native Method) 

The exception occurs on an API level 19 Nexus 4 physical device in Firebase Test Lab. It does not occur on any other platforms we are testing on, including a local API 19 emulated Nexus S.

I understood the exception to mean there are ambiguous/duplicate (transitive) dependencies, but I cannot see any in gradlew dependencies, only Espresso Idling Resources v2.2.2. The dependency is "compile" not "androidTestCompile" as CountingIdlingResource is referenced in the Activity.

How do I identify the cause and resolve it?

UPDATE: The exception also occurs with API 19 on a Nexus 5 and Nexus 7. Here are the parts of the output of "./gradlew dependencies" relating to the idling resource library:

_debugApk - ## Internal use, do not manually configure ## +--- com.android.support.test.espresso:espresso-idling-resource:2.2.2 +--- com.google.dagger:dagger:2.10 ... _debugCompile - ## Internal use, do not manually configure ## +--- com.android.support.test.espresso:espresso-idling-resource:2.2.2 +--- com.google.dagger:dagger:2.10 ... _releaseApk - ## Internal use, do not manually configure ## +--- com.android.support.test.espresso:espresso-idling-resource:2.2.2 +--- com.google.dagger:dagger:2.10 ... _releaseCompile - ## Internal use, do not manually configure ## +--- com.android.support.test.espresso:espresso-idling-resource:2.2.2 +--- com.google.dagger:dagger:2.10 ... compile - Classpath for compiling the main sources. +--- com.android.support.test.espresso:espresso-idling-resource:2.2.2 +--- com.google.dagger:dagger:2.10 

1 Answers

Answers 1

As I understand Google Samples the dependency:

com.android.support.test.espresso:espresso-idling-resource:2.2.2 

is only needed when you are implementing custom IdlingResource. Even in IdlingResourceSample README there is a sentence:

Consider using the CountingIdlingResource class from the espresso-contrib package

And as I understand your code you are trying to use CountingIdlingResource from espresso-contrib package, so try to organise your test dependencies as written in other Google sample.

Read More

Monday, February 6, 2017

How to exclude certain files from Android Studio gradle builds?

Leave a Comment

I am using Android Studio with Google Drive, which makes hidden system files visible (such as Icon and desktop.ini), causing errors, as described here. Rather than run scripts to delete these files, I'd like to instruct gradle 2.14 to ignore them.

In an attempt to figure out how to exclude files, I created files named "excludeme.txt" in the directories \app\src\main\res\values and in \app\src\main\java\com\hfad\stopwatch\. I unsuccessfully tried various modifications to the two build.gradle files in my project. None successfully excluded the file.

Specifically, I made the following modification to the build.gradle file for Module: app, per this question:

dependencies {     compile fileTree(dir: 'libs', include: ['*.jar'], excludes: ['**/excludeme.txt'])                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^     androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {         exclude group: 'com.android.support', module: 'support-annotations'     })     testCompile 'junit:junit:4.12'  } 

I also added this to the android section of the same build.gradle file, per this question:

aaptOptions {     ignoreAssetsPattern "!excludeme.txt" } 

I also added:

sourceSets {     main {         java {             srcDir "src"                [I also tried w/o this line]             exclude "**/excludeme.txt"         }     } } 

When I selected Build > Clean Project, which triggered a build, I got this output, which shows that the file in the resources folder was not ignored:

Information:Gradle tasks [clean, :app:generateDebugSources, :app:mockableAndroidJar, :app:prepareDebugUnitTestDependencies, :app:generateDebugAndroidTestSources] C:\Users\Ellen\GoogleDrive\Ellen-CS115\AndroidStudioProjects\Stopwatch\app\src\main\res\values\excludeme.txt Error:(1, 1) Error: Premature end of file. Error:Execution failed for task ':app:mergeDebugResources'. > C:\Users\Ellen\GoogleDrive\Ellen-CS115\AndroidStudioProjects\Stopwatch\app\src\main\res\values\excludeme.txt:1:1: Error: Premature end of file. 

The results were the same if I removed the exclamation point:

aaptOptions {     ignoreAssetsPattern "!excludeme.txt" } 

How do I properly instruct gradle to ignore files containing a certain pattern when building Android projects?

0 Answers

Read More

Monday, September 19, 2016

Gradle exclude file from sourceSet not working

Leave a Comment

I've got a project where I'm trying to include a single file from a tree of java source files into a library project. Whatever I do I am not able to include only that file. I have had success in another project excluding all files except the one, but that only worked when running gradle from the library project only. When it was run from the application directory, all files were included. While trying to create a simple project that reproduces the issue, that same exclude all does not work either.

The sample file tree is simple:

application - android app that includes the two libraries library1/   build.gradle   src/main/AndroidManifest.xml library2/   build.gradle   src/main/AndroidManifest.xml java/src/com/company/product/   /pkg1     Source1.java, Source2.java, Source3.java     libraryoneonly/Library1Source.java   /pkg2     Source1.java, Source2.java, Source3.java 

The library1 build.gradle looks like this. Neither of the includes or excludes work below.

library1/build.gradle

apply plugin: 'com.android.library' android {     sourceSets {         main.jni.srcDirs = []         main.jniLibs.srcDir 'src/main/libs'         main.java {             srcDir "../../java/src"             exclude  {  FileTreeElement elem ->                 println "Searching for files, found: " + elem.relativePath                 !(elem.isDirectory() || elem.name.equals('Library1Source.java'))             }             //include ("**/libraryoneonly/**")             //include ('com/company/product/pkg1/libraryoneonly/Library1Source.java')         }     } dependencies {     compile project(':library2') } 

And library2 build.gradle. Surprisingly, the uncommented exclude below does work.

library2/build.gradle

apply plugin: 'com.android.library'  android {         sourceSets {             main.jni.srcDirs = []             main.jniLibs.srcDir 'src/main/libs'             main.java {                 srcDir "../../java/src"                 //exclude  {  FileTreeElement elem -> ((elem.path.contains('/libraryoneonly/')) ) }                 exclude ('com/company/product/pkg1/libraryoneonly/Library1Source.java')             }         } 

Just to note, I never see the "Searching for files, found" text when library1 is building. I'm not sure why. I do see it in the larger project this test was modeled from, depending on where the build was run from.

If you'd like to pull the sample project and try it out, here is a link: https://github.com/gbak/gradleTest

2 Answers

Answers 1

Gradle'e SourceDirectorySet seems to be missing features. docs has a very telling note:

TODO - configure includes/excludes for individual source dirs, and sync up with CopySpec TODO - allow add FileTree

The lack of features on par with CopySpec means there isn't a logical way to do what you're asking. The include pattern first adds a list of files to the sourceSet and then you can exclude a few files from that set. Except,

  1. The main.java sourceset implicitly adds **\*.java
  2. There is no exclude everything that is not

means you are SOL.

You can declare a separate main.somethingElse source set and use include just that one file, but I wasn't able to figure out how to add the new sourceset to the compile path. The hack suggested here, using compiler args doesn't work anymore, java complains about invalid flags.

The only workaround I can think of is to use a path that excludes that files you do not want in main.java.srcDir for library1

    main.java {         srcDir '../../java/src/com/company/product/pkg1/libraryoneonly'     } 

Answers 2

Your code seems to be correct to me, it's just that FileCollections like sourceFiles are lazily evaluated, i.e. your println statement is not executed until the contents of the source set are actually being requested.

Adding something like

main.java.sourceFiles.each { println "File in source set: " + it } 

after the main.java {...} closure should actually make the println work.

Read More

Tuesday, May 3, 2016

Android App Users Get “App not installed” When Attempting to Update

Leave a Comment

UPDATE: To those who asked about which error codes the users are receiving: there are no error codes. It just opens a blank, post-installation page that says "The app was not installed" with a big 'X' next to it. It's possible different versions of Android could have different messages. There is no indication for what went wrong during the installation.

UPDATE 2: Some users reported that they receive error code "-504" when they try to install/update from the Play Store, and the "app not installed" message when manually trying to install the .apk. I don't know what correlation this error has with users being unable to install, but the solutions from the only 2 questions on SO on this topic did not fix anything for me. I've included the updated manifests and build files.

UPDATE 3: It appears as users report this issue in versions after IAB has been successfully installed, which further de-legitimatizes the concept that this issue is caused by introducing IAB.

UPDATE 4: It looks like the problem is with old users trying to update to a new version, and not with new users. With that in mind, there is a high likelihood that this issue is result of INSTALL_FAILED_UID_CHANGED. Looking through the version history, the significant change I made in the problematic version that users cannot update from is removing drawables that I no longer intended of using.

Asking users to go through the procedure to fix this isn't plausible. If there is a solution that I can enforce which would fix it for faulty users, wonderful... if not, the least I can do at this point is damage control and ensure this doesn't happen in the future.

NOTE: Below is the original post speculating that the problem is the result of introducing IAB into the app. Since then, it has become more and more unlikely for that to be the cause. Regardless, the post still has relevant information.

------------------------------------------------------------------------------------------

Original Title: Android App Users Get "App not installed" After Introducing IAB

I recently introduced IAB in my app that was published on Google Play. After a while, I've started to get reports from some users that they get an "installation unsuccessful" error when they try to install or update it. What makes me think it's caused by introducing IAB is that one particular long-time user e-mailed me that when he's attempting to update to the version with IAB, the installer mentions that new permissions were introduced and requires the user's permission. Once granted, it says that the app failed to install.

I've done some Googling and it appears to be a problem from their end, one user even tried to manually install an .apk with said permissions removed without any success. I wan't to make sure that it's not something I've done wrong, but an inevitability that I have to accept with some users.

Note that the vast majority has no problem of installing the app, and I haven't received any reports of this until after IAB was introduced. It wouldn't bother me so much were it a small amount of lost users, but the problem is, those users hurt my app's rating. Users have also mentioned that they can install apps, excluding my own, perfectly well.

I don't rule out the possibility that users may have been getting these errors even before IAB was introduced, and the linkage could be a mistaken one.

Here is my manifest:

<?xml version="1.0" encoding="utf-8"?> <manifest package = "com.jjsoftware.fullscientificcalculator"       xmlns:android = "http://schemas.android.com/apk/res/android">  <uses-permission android:name = "android.permission.VIBRATE"/> <uses-permission android:name = "com.android.vending.BILLING"/>  <application     android:allowBackup = "true"     android:fullBackupContent = "true"     android:icon = "@drawable/logo"     android:label = "@string/app_name">     <activity         android:name = ".MainActivity"         android:hardwareAccelerated = "false"         android:label = "@string/app_name"         android:screenOrientation = "portrait"         android:theme="@style/AppTheme">         <intent-filter>             <action android:name = "android.intent.action.MAIN"/>             <category android:name = "android.intent.category.LAUNCHER"/>         </intent-filter>     </activity>     <activity         android:name = ".SettingsActivity"         android:theme = "@style/PreferencesTheme">         <intent-filter>             <action android:name = ".SettingsActivity"/>             <category android:name = "android.intent.category.PREFERENCE"/>         </intent-filter>     </activity> </application> 

Here is the Gradle file:

apply plugin: 'com.android.application'  android {     compileSdkVersion 23     buildToolsVersion "23.0.1"      defaultConfig {         applicationId "com.jjsoftware.fullscientificcalculator"         minSdkVersion 14         targetSdkVersion 23         versionCode 102         versionName "1.679"     }      sourceSets { main { assets.srcDirs = ['src/main/assets', 'src/main/assets/'] } } }  dependencies {     compile 'com.android.support:appcompat-v7:23.1.1'     compile 'com.google.android.gms:play-services-ads:8.4.0'     compile 'com.android.support:gridlayout-v7:23.2.1'     compile files('libs/exp4j-0.4.5.jar')     compile files('libs/EJML-core-0.28.jar')     compile files('libs/EJML-dense64-0.28.jar')     compile files('libs/Jama-1.0.3.jar')     compile files('libs/EJML-simple-0.28.jar') } 

And, if need be, the top-level build:

// Top-level build file where you can add configuration options common to all sub-projects/modules.  buildscript {     repositories {         jcenter()     }     dependencies {         classpath 'com.android.tools.build:gradle:1.5.0'          // NOTE: Do not place your application dependencies here; they belong         // in the individual module build.gradle files     } }  allprojects {     repositories {         jcenter()     } } 

4 Answers

Answers 1

There is a typo in the manifest file on line android:largeHeap="true">>. xml line ends with >>. This may be causing the error.

Answers 2

Remember that the latest installment of Android (Marshmallow version) has changed the permissions to give more access to permissions to the user. Hence it is not enough to define the permissions in the manifest anymore.

Through code you need to make sure that the billing permission is enabled by the users when they use the app. The simplest way to go around this is to set the target SDK to v-22. This should temporarily solve your issue.

The real solution however is to handle the new permissions introduced in Marshmallow. Here is how to do it:

@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {      switch(requestCode) {         case BILLING_REQUEST:             if (canAccessBilling()) {                 callBillingPerms();             }             break;     } }  private void callBillingPerms() {     Toast.makeText(this, "We need your permission to access Billing", Toast.LENGTH_SHORT).show(); }  private boolean canAccessSMS() {     return(hasPermission(Manifest.vending.BILLING)); }  @TargetApi(Build.VERSION_CODES.M) private boolean hasPermission(String perm) {     return(PackageManager.PERMISSION_GRANTED==this.checkSelfPermission(perm)); } 

Hope this helps :)

Answers 3

it could be the phones have a lower version of the Google play services than the minimum you defined in the APK.

There is nothing much you can do if that is the case, other than for the users to upgrade their google services (https://play.google.com/store/apps/details?id=com.google.android.gms&hl=en) or you reduce your version.

also you may need to add the following to your manifest. (i think this is used to compare the versions installed in the phones with the versions required by the apk)

<application ...>      <!-- This meta-data tag is required to use Google Play Services. -->     <meta-data         android:name="com.google.android.gms.version"         android:value="@integer/google_play_services_version" />   </application> 

Answers 4

Perhaps the error is on the user's side.

This article states the following:

Google Play - Error 504

Problem

App could not be downloaded due to an error.

First solution

The usual, please: go to Settings > Apps > All > Google Play Store and Clear cache and Clear data. Also Clear cache and Clear data for Google Services Framework.

Second solution

Try removing your GMail account

This Stack Exchange answer discussed similar ideas.

According to the list of status codes at Wikipedia, a 504 error means the following:

504 Gateway Timeout
The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.

Ask your users if doing the above solves their issue.

Read More