116

After updating Android Studio from Canary 3 to Canary 4, the following error is thrown at the build time.

Android dependency 'com.android.support:support-support-v4' has different version for the compile (25.2.0) and runtime (26.0.0-beta2) classpath. You should manually set the same version via DependencyResolution.

I ran a complete search throughout the project and the version 25.1.0 is no where used.

App-build.gradle

android {
compileSdkVersion 26
buildToolsVersion '26.0.0'


defaultConfig {
    applicationId "com.xxx.xxxx"
    minSdkVersion 14
    targetSdkVersion
    versionCode 1
    versionName "1.0"
    multiDexEnabled true

}


buildTypes {
    debug {
        debuggable true
    }
    release {
        debuggable false
        minifyEnabled true
        shrinkResources true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }

    lintOptions {
        abortOnError false
    }

}}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation project(':core')
implementation com.google.android.gms:play-services-gcm:9.0.0'

implementation('com.crashlytics.sdk.android:crashlytics:2.6.5@aar') {
    transitive = true
}
implementation 'com.android.support:multidex:1.0.1'
implementation 'com.flurry.android:analytics:7.0.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
implementation 'com.jakewharton:butterknife:8.6.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}

Library-build.gradle:

apply plugin: 'com.android.library'
android {
compileSdkVersion 26
buildToolsVersion '26.0.0'

defaultConfig {
    minSdkVersion 14
    targetSdkVersion
    versionCode 1
    versionName "1.0"
}

}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation files('libs/model.jar')
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:percent:26.0.0-beta2'
implementation 'com.android.support:appcompat-v7:26.0.0-beta2'
implementation 'com.android.support:support-core-utils:26.0.0-beta2'

implementation 'com.squareup.retrofit2:retrofit:2.0.2'
implementation 'com.squareup.picasso:picasso:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
implementation 'com.squareup.okhttp3:logging-interceptor:3.2.0'
implementation 'uk.co.chrisjenx:calligraphy:2.2.0'
implementation 'com.google.code.gson:gson:2.2.4'
implementation 'com.android.support:design:26.0.0-beta2'
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.1'

}

Note: Project was building fine in Canary 3

Zoe
  • 27,060
  • 21
  • 118
  • 148
DroidLearner
  • 2,115
  • 5
  • 31
  • 50

18 Answers18

139

Use this code in your buildscript (build.gradle root):

subprojects {
  project.configurations.all {
     resolutionStrategy.eachDependency { details ->
        if (details.requested.group == 'com.android.support'
              && !details.requested.name.contains('multidex') ) {
           details.useVersion "version which should be used - in your case 26.0.0-beta2"
        }
     }
  }
}
user3908686
  • 1,583
  • 1
  • 9
  • 4
  • 8
    It worked for me, remember to change details.useVersion to a version number, if you just copy & paste it will fail – John Starr Dewar May 04 '18 at 07:32
  • 1
    Making sure to include the `!details.requested.name.contains('multidex')` really helped me out. – Jonah Starling May 14 '18 at 16:53
  • 2
    I tried this, but it only worked for the com.android.support conflict. It didn't work for the com.google.firebase:firebase-analytics conflict. The 'contains' seems to match too many packages. I used the simpler solution in [this post](https://stackoverflow.com/questions/44404308/android-force-gradle-to-include-only-one-version-of-a-library) instead for all of the conflicts and it worked perfectly. – Jacob Joel Jul 11 '18 at 17:23
  • 4
    @user3908686 solved the problem but please explain , why we need to add this?? – ArgaPK Nov 08 '18 at 11:24
  • This works perfectly with flutter projects with lots of plugins that have their own dependencies. – Ricardo Gonçalves Nov 12 '18 at 03:52
  • 1
    `ERROR: Failed to resolve: com.android`. Sadly, doesn't resolve my issue. – Mike S. Jan 18 '19 at 17:53
  • Worked for me, don't forget to 'details.useVersion "26.0.0-beta2"' – VoidMain Apr 11 '19 at 20:56
84

I had the same error, what solve my problem was. In my library instead of using compile or implementation i use "api". So in the end my dependencies:

dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
api files('libs/model.jar')
testApi 'junit:junit:4.12'
api 'com.android.support:percent:26.0.0-beta2'
api 'com.android.support:appcompat-v7:26.0.0-beta2'
api 'com.android.support:support-core-utils:26.0.0-beta2'

api 'com.squareup.retrofit2:retrofit:2.0.2'
api 'com.squareup.picasso:picasso:2.4.0'
api 'com.squareup.retrofit2:converter-gson:2.0.2'
api 'com.squareup.okhttp3:logging-interceptor:3.2.0'
api 'uk.co.chrisjenx:calligraphy:2.2.0'
api 'com.google.code.gson:gson:2.2.4'
api 'com.android.support:design:26.0.0-beta2'
api 'com.github.PhilJay:MPAndroidChart:v3.0.1'
}

You can find more info about "api", "implementation" in this link https://stackoverflow.com/a/44493379/3479489

Yayo Arellano
  • 3,575
  • 23
  • 28
  • 37
    All of android studio recommends using implementation.. And this offbeat solution works. Google engineers at android studios need a lesson to learn from the world. What a frustrating tool – Siddharth Apr 03 '18 at 17:39
  • 3
    it doesn´t solve the problem , the message says: "Android dependency '...............' has different version for the compile" – Jorgesys Jun 19 '18 at 17:38
  • @KeithLoughnane This is not bad practice, is the correct way to do it and the way the documentation recommend – Yayo Arellano Dec 19 '18 at 12:29
  • 1
    @YayoArellano implementation is what is recommended with judicious use of api where absolutely required. This is throw everything at the wall and see what sticks programming. Some of those may need api but not all of them. You are exposing far too much. – Keith Loughnane Dec 19 '18 at 13:49
  • While it may prevent the error, this is a *hacky workaround* and not a proper solution! The only thing that using `api` over `implementation` does is to *expose your library dependencies* to the app project _even if the app project does not need the dependency at all_ (and as a side-effect pinning the dependencies to that version). Use the dependency resolution strategy instead! – friederbluemle Mar 15 '19 at 11:36
  • @Siddharth In rather practical terms... using `api` in a library/feature module makes sense, when the main module used `implementation`, which then has to become `api` there, too. It's merely good for sharing dependencies among different modules. – Martin Zeitler Nov 18 '19 at 09:48
27

You should be able to see exactly which dependency is pulling in the odd version as a transitive dependency by running the correct gradle -q dependencies command for your project as described here:

https://docs.gradle.org/current/userguide/userguide_single.html#sec:listing_dependencies

Once you track down what's pulling it in, you can add an exclude to that specific dependency in your gradle file with something like:

implementation("XXXXX") {
    exclude group: 'com.android.support', module: 'support-compat'
}
jdonmoyer
  • 1,245
  • 1
  • 18
  • 28
  • Hi,I ran the gradle dependency command and I'm posting the screenshot url here, imgur.com/dL35BaN. I never use Firebase in my project. Added that line in gcm, it didn't work though – DroidLearner Jun 21 '17 at 12:55
  • @DroidLearner I might be missing something, but I don't see any reference to com.android.support:support-compat in the screenshot you posted. Also there is a warning in that screen shot that refers to a 'compile' configuration which I don't see present in your gradle file in the OP. it's likely that it's coming from the :core submodule. Can you post the relevant gradle information from there? – jdonmoyer Jun 21 '17 at 15:51
  • Hi, posting you the entire gradle files with dependency tree here.. app gradle file -> https://gist.github.com/anonymous/93affc0d75eb96b59f9fde51332b9716 core gradle file ->https://gist.github.com/anonymous/5c85031f26ff766109061ab1f00b833d dependency tree ->https://gist.github.com/anonymous/71dd33b6fa4dc63dd357889e8aff01ee Hope this helps. – DroidLearner Jul 13 '17 at 02:58
  • 1
    It looks like the older version of the library is being pulled in by firebase, which in turn is a transitive dependency of gms. You can likely get this working by adding: implementation 'com.android.support:support-v4:26.0.0-beta2' before any other dependency. Long term turning off transitive dependencies in favor of being explicit or using a resolutionStrategy (https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html) is likely a better approach. – jdonmoyer Jul 13 '17 at 14:05
  • 1
    Thanks. Somehow managed to fix the transitive dependency. Gradle build succeeded. At runtime its showing errors with all library classes. error: package retrofit2 does not exist error: package android.support.v7.app does not exist error: package com.google.gson does not exist. At compile time it didn't show any errors. – DroidLearner Jul 14 '17 at 02:16
16

After a lot of time and getting help from a friend who knows a lot more than me about android: app/build.gradle

android {
    compileSdkVersion 27

    // org.gradle.caching = true

    defaultConfig {
        applicationId "com.cryptoviewer"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 196
        versionName "16.83"
        // ndk {
        //     abiFilters "armeabi-v7a", "x86"
        // }
    }

and dependencies

dependencies {
    implementation project(':react-native-camera')
   //...
    implementation "com.android.support:appcompat-v7:26.1.0" // <= YOU CARE ABOUT THIS
    implementation "com.facebook.react:react-native:+"  // From node_modules
}

in build.gradle

allprojects {
   //...
    configurations.all {
        resolutionStrategy.force "com.android.support:support-v4:26.1.0"
    }

in gradle.properties

android.useDeprecatedNdk=true
android.enableAapt2=false
org.gradle.jvmargs=-Xmx4608M
8

The answer for me was to also add this to my build.gradle file:

configurations.all {
  resolutionStrategy.eachDependency { details ->
      if (details.requested.group == 'com.android.support'
              && !details.requested.name.contains('multidex') ) {
          details.useVersion "26.1.0"
      }
  }
}

In my case, it was nessisary to enclose the resolution strategy in a configurations.all { .. } block. I placed the configurations.all block directly into my app/build.gradle file (ie configurations.all was not nested in anything else)

Dacre Denny
  • 29,664
  • 5
  • 45
  • 65
6

I had the same error and I fixed it by adding this code to the gradle.properties file.

android.enableJetifier=true
hassan bazai
  • 424
  • 6
  • 9
5

This worked for me:

Add the follow line in app/build.gradle in dependencies section:

implementation "com.android.support:appcompat-v7:27.1.0"

or :27.1.1 in my case

Erik Cederstrand
  • 9,643
  • 8
  • 39
  • 63
ALEXANDER LOZANO
  • 1,874
  • 3
  • 22
  • 31
4

Add this code in your project level build.gradle file.

subprojects {
    project.configurations.all {
        resolutionStrategy.eachDependency { details ->
            if (details.requested.group == 'com.android.support'
                    && !details.requested.name.contains('multidex') ) {
                details.useVersion "version which should be used - in your case 28.0.0-beta2"
            }
        }
    }
}

Sample Code :

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    repositories {
        google()
        jcenter()
        maven { url 'https://maven.fabric.io/public' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.0'
        classpath 'io.fabric.tools:gradle:1.31.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files

    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


subprojects {
    project.configurations.all {
        resolutionStrategy.eachDependency { details ->
            if (details.requested.group == 'com.android.support'
                    && !details.requested.name.contains('multidex') ) {
                details.useVersion "28.0.0"
            }
        }
    }
}
dileep krishnan
  • 326
  • 4
  • 7
3

If anyone getting this dependency issue in 2019, update Android Studio to 3.4 or later

Atul Vasudev A
  • 463
  • 3
  • 22
3

I solved it by upgrading my gradle dependency in the android/build.gradle file: classpath 'com.android.tools.build:gradle:3.3.1' (I was previously on version 3.2.

2

I resolved it by following what Eddi mentioned above,

 resolutionStrategy.eachDependency { details ->
            if (details.requested.group == 'com.android.support'
                    && !details.requested.name.contains('multidex') ) {
                details.useVersion "26.1.0"
            }
        }
DILIP KOSURI
  • 455
  • 5
  • 10
2

Switching my conflicting dependencies from implementation to api does the trick. Here's a good article by mindorks explaining the difference.

https://medium.com/mindorks/implementation-vs-api-in-gradle-3-0-494c817a6fa

Edit:

Here's my dependency resolutions as well

 subprojects {
        project.configurations.all {
            resolutionStrategy.eachDependency { details ->
                if (details.requested.group == 'com.android.support'
                        && !details.requested.name.contains('multidex')) {
                    details.useVersion "28.0.0"
                }
                if (details.requested.group == 'com.google.android.gms'
                        && details.requested.name.contains('play-services-base')) {
                    details.useVersion "15.0.1"
                }
                if (details.requested.group == 'com.google.android.gms'
                        && details.requested.name.contains('play-services-tasks')) {
                    details.useVersion "15.0.1"
                }
            }
        }
    }
i am E
  • 110
  • 7
2

See in your library projects make the compileSdkVersion and targetSdkVersion version to same level as your application is

android {
    compileSdkVersion 28

    defaultConfig {
        consumerProguardFiles 'proguard-rules.txt'
        minSdkVersion 14
        targetSdkVersion 28
    }
}

also make all dependencies to same level

Ali Imran
  • 8,927
  • 3
  • 39
  • 50
1

I comment out //api 'com.google.android.gms:play-services-ads:15.0.1' it worked for me after sync

1

Just add these lines in your build.gradle file

resolutionStrategy.force "com.android.support:support-media-compat:26.0.0-beta2"

resolutionStrategy.force "com.android.support:support-v4:26.0.0-beta2"

tushar
  • 36
  • 4
1

In my case, I was having two different versions of the below implementation in two different modules, So i changed both implementation to versions ie : 6.0.2 and it worked. You may also need to write dependency resolution see the accepted answer.

app module

implementation 'com.karumi:dexter:5.0.0'

commons module

implementation 'com.karumi:dexter:6.0.2'
Divyanshu Kumar
  • 1,272
  • 15
  • 15
0

    configurations.all {
        resolutionStrategy.force
        //"com.android.support:appcompat-v7:25.3.1"
        //here put the library that made the error with the version you want to use
    }

add this to gradle (project) inside allprojects

Farido mastr
  • 464
  • 5
  • 12
-7

Replace a hard coded version to + example:

implementation 'com.google.android.gms:play-services-base:+'
implementation 'com.google.android.gms:play-services-maps:+'
Sarmad Shah
  • 3,725
  • 1
  • 20
  • 42
  • 7
    Not exactly best practice as this can cause a library to kind of run away from you. Ex. They change the way things are done in a new version and all of a sudden your code doesn't work. While you should strive to use the latest version, you should manually set the version number after testing it first to prevent unwanted crashes and bugs. – Jonah Starling May 14 '18 at 16:55
  • 1
    Not a good practice. In addition to what @JonahStarling said, it will also affect Gradle build performance if the offline feature is turned off. – Ankit Batra Oct 14 '18 at 08:16