Please don't mark this as duplicate. I've spent two days scouring Github, Stack, Android Studio docs, RN docs, and Gradle docs looking for an answer.
The Problem
Our React Native project won't build on Android. One build error is
Could not find com.github.wix-playground:ahbottomnavigation:2.4.9
The fix for this error is to add maven { url 'https://jitpack.io' } to the project build.gradle
After adding this, however, we get a second error, which is
Execution failed for task ':react-native-ble-plx:compileDebugJavaWithJavac'
The fix for this is adding maven { url 'https://maven.google.com' } to build.gradle
But after adding this second fix, we trigger the first error again.
The Question
Is there a way to list both maven { <url> }s in build.gradle in such a way the each maven { <url> } is used only for the specific dependency relying on it?
OR
Can we force the same support library version across all dependencies?
- I have tried numerous methods from these Gradle Docs
- I've tried the answer in this Stack Post
- I've updated to Android Studio 3.4.1
Any help would be greatly appreciated.
Our Files
Project level build.gradle
buildscript {
repositories {
google()
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
}
}
allprojects {
repositories {
google()
jcenter()
mavenCentral()
mavenLocal()
// maven { url 'https://maven.google.com' }
maven { url 'https://jitpack.io' }
maven {
url "$rootDir/../node_modules/react-native/android" // This URL still works
}
}
}
ext {
buildToolsVersion = "28.0.3"
minSdkVersion = 19
compileSdkVersion = 26
targetSdkVersion = 26
supportLibVersion = "28.0.0"
}
subprojects { subproject ->
afterEvaluate {
if ((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
android {
variantFilter { variant ->
def names = variant.flavors*.name
if (names.contains("reactNative51") || names.contains("reactNative56")) {
setIgnore(true)
}
}
}
}
}
}
app/build.gradle
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'io.fabric.tools:gradle:1.+'
}
}
apply plugin: "com.android.application"
apply plugin: "io.fabric"
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
repositories {
maven { url 'https://maven.fabric.io/public' }
}
import com.android.build.OutputFile
project.ext.react = [
entryFile: "index.js",
bundleInStaging: true,
devDisabledInStaging: true,
inputExcludes: ["ios/**", "__tests__/**", "bundle_out/**"]
]
apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-sentry/sentry.gradle"
def enableSeparateBuildPerCPUArchitecture = false
def enableProguardInReleaseBuilds = false
def debugKeystorePropertiesFile = rootProject.file("keystores/debug.keystore.properties");
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(debugKeystorePropertiesFile))
def releaseKeystorePropertiesFile = rootProject.file("keystores/release.keystore.properties");
def releaseKeystoreProperties = new Properties()
releaseKeystoreProperties.load(new FileInputStream(releaseKeystorePropertiesFile))
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "com.example"
missingDimensionStrategy "RNN.reactNativeVersion", "reactNative55"
minSdkVersion 21
targetSdkVersion 28
versionCode 177
versionName "2.0.4"
multiDexEnabled true
ndk {
abiFilters "armeabi-v7a", "x86"
}
manifestPlaceholders = [
FABRIC_API_KEY: project.env.get("FABRIC_API_KEY"),
FABRIC_SECRET: project.env.get("FABRIC_SECRET")
]
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
signingConfigs {
debug {
storeFile file(keystoreProperties['key.store'])
storePassword keystoreProperties['key.store.password']
keyAlias keystoreProperties['key.alias']
keyPassword keystoreProperties['key.alias.password']
}
release {
storeFile file(releaseKeystoreProperties['key.store'])
storePassword releaseKeystoreProperties['key.store.password']
keyAlias releaseKeystoreProperties['key.alias']
keyPassword releaseKeystoreProperties['key.alias.password']
}
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include "armeabi-v7a", "x86"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro", "proguard-devsupport.pro"
testProguardFile 'proguard-debug.pro'
}
staging {
signingConfig signingConfigs.debug
matchingFallbacks = ['release', 'debug']
}
debug {
signingConfig signingConfigs.debug
}
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
def versionCodes = ["armeabi-v7a":1, "x86":2]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
}
}
}
}
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support' && requested.name != 'multidex') {
details.useVersion "${rootProject.ext.supportLibVersion}"
}
}
}
dependencies {
compile('com.google.android.gms:play-services-gcm:11.8.0') {
force = true
}
compile project(':react-native-push-notification')
implementation project(':react-native-awesome-card-io')
implementation project(':react-native-fabric')
implementation project(':react-native-randombytes')
implementation project(':react-native-linear-gradient')
implementation project(':react-native-spinkit')
implementation project(':react-native-keychain')
implementation project(':react-native-vector-icons')
implementation project(':react-native-ble-plx')
implementation project(':react-native-config')
implementation project(':react-native-sentry')
implementation project(':react-native-device-info')
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.0.0-alpha3'
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
implementation "com.android.support:appcompat-v7:27.1.0"
implementation 'com.android.support:design:27.1.0'
implementation "com.facebook.react:react-native:+" // From node_modules
implementation('com.crashlytics.sdk.android:crashlytics:2.9.3@aar') {
transitive = true;
}
implementation project(':react-native-navigation')
implementation project(':react-native-tcp')
implementation 'com.android.support:design:25.4.0'
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
implementation 'com.android.support:multidex:1.0.3'
implementation ('com.github.wix-playground:ahbottomnavigation:2.4.9') {
exclude group: "com.android.support"
}
}
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:name="android.support.multidex.MultiDexApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="false"
android:fullBackupContent="false"
android:theme="@style/AppTheme">
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
android:value="YOUR NOTIFICATION CHANNEL NAME"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description"
android:value="YOUR NOTIFICATION CHANNEL DESCRIPTION"/>
<!-- Change the resource name to your App's accent color - or any other color you want -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_color"
android:resource="@android:color/white"/>
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/>
<!-- < Only if you're using GCM or localNotificationSchedule() > -->
<service
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerServiceGcm"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="io.fabric.ApiKey"
android:value="${FABRIC_API_KEY}"
/>
<meta-data
android:name="io.fabric.ApiSecret"
android:value="${FABRIC_SECRET}"
/>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>