[해결방법] MapBox error, FusedLocationProviderClient

이번 프로젝트에 MapBox를 사용한 맵 기능을 개발하기 위해 스터디를 하고 있는중에 몇일간 괴롭히던 문제의 원인을 알게되어 기쁜마음에 블로그를 작성하게 되었습니다.

먼저, 아래와 같은 무시무시한 사이즈의 Exception인데요.

E/Mbgl-MapChangeReceiver(31392): Exception in onDidFinishLoadingStyle
E/Mbgl-MapChangeReceiver(31392): java.lang.IncompatibleClassChangeError: Found interface com.google.android.gms.location.FusedLocationProviderClient, but class was expected (declaration of 'com.google.android.gms.location.FusedLocationProviderClient' appears in /data/app/com.picple.ployee-58O7yV1MiB3dSAN0J5d5eQ==/base.apk)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.android.core.location.GoogleLocationEngineImpl.requestLocationUpdates(GoogleLocationEngineImpl.java:58)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.android.core.location.GoogleLocationEngineImpl.requestLocationUpdates(GoogleLocationEngineImpl.java:26)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.android.core.location.LocationEngineProxy.requestLocationUpdates(LocationEngineProxy.java:34)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxsdk.location.LocationComponent.onLocationLayerStart(LocationComponent.java:1439)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxsdk.location.LocationComponent.enableLocationComponent(LocationComponent.java:1568)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxsdk.location.LocationComponent.setLocationComponentEnabled(LocationComponent.java:551)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxgl.MapboxMapController.enableLocationComponent(MapboxMapController.java:274)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxgl.MapboxMapController.updateMyLocationEnabled(MapboxMapController.java:1563)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxgl.MapboxMapController.access$100(MapboxMapController.java:91)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxgl.MapboxMapController$1.onStyleLoaded(MapboxMapController.java:141)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxsdk.maps.MapboxMap.notifyStyleLoaded(MapboxMap.java:963)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxsdk.maps.MapboxMap.onFinishLoadingStyle(MapboxMap.java:225)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxsdk.maps.MapView$MapCallback.onDidFinishLoadingStyle(MapView.java:1383)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxsdk.maps.MapChangeReceiver.onDidFinishLoadingStyle(MapChangeReceiver.java:198)
E/Mbgl-MapChangeReceiver(31392): 	at com.mapbox.mapboxsdk.maps.NativeMapView.onDidFinishLoadingStyle(NativeMapView.java:1166)
E/Mbgl-MapChangeReceiver(31392): 	at android.os.MessageQueue.nativePollOnce(Native Method)
E/Mbgl-MapChangeReceiver(31392): 	at android.os.MessageQueue.next(MessageQueue.java:326)
E/Mbgl-MapChangeReceiver(31392): 	at android.os.Looper.loop(Looper.java:181)
E/Mbgl-MapChangeReceiver(31392): 	at android.app.ActivityThread.main(ActivityThread.java:7073)
E/Mbgl-MapChangeReceiver(31392): 	at java.lang.reflect.Method.invoke(Native Method)
E/Mbgl-MapChangeReceiver(31392): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
E/Mbgl-MapChangeReceiver(31392): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
W/System.err(31392): java.lang.IncompatibleClassChangeError: Found interface com.google.android.gms.location.FusedLocationProviderClient, but class was expected (declaration of 'com.google.android.gms.location.FusedLocationProviderClient' appears in /data/app/com.picple.ployee-58O7yV1MiB3dSAN0J5d5eQ==/base.apk)
W/System.err(31392): 	at com.mapbox.android.core.location.GoogleLocationEngineImpl.requestLocationUpdates(GoogleLocationEngineImpl.java:58)
W/System.err(31392): 	at com.mapbox.android.core.location.GoogleLocationEngineImpl.requestLocationUpdates(GoogleLocationEngineImpl.java:26)
W/System.err(31392): 	at com.mapbox.android.core.location.LocationEngineProxy.requestLocationUpdates(LocationEngineProxy.java:34)
W/System.err(31392): 	at com.mapbox.mapboxsdk.location.LocationComponent.onLocationLayerStart(LocationComponent.java:1439)
W/System.err(31392): 	at com.mapbox.mapboxsdk.location.LocationComponent.enableLocationComponent(LocationComponent.java:1568)
W/System.err(31392): 	at com.mapbox.mapboxsdk.location.LocationComponent.setLocationComponentEnabled(LocationComponent.java:551)
W/System.err(31392): 	at com.mapbox.mapboxgl.MapboxMapController.enableLocationComponent(MapboxMapController.java:274)
W/System.err(31392): 	at com.mapbox.mapboxgl.MapboxMapController.updateMyLocationEnabled(MapboxMapController.java:1563)
W/System.err(31392): 	at com.mapbox.mapboxgl.MapboxMapController.access$100(MapboxMapController.java:91)
W/System.err(31392): 	at com.mapbox.mapboxgl.MapboxMapController$1.onStyleLoaded(MapboxMapController.java:141)
W/System.err(31392): 	at com.mapbox.mapboxsdk.maps.MapboxMap.notifyStyleLoaded(MapboxMap.java:963)
W/System.err(31392): 	at com.mapbox.mapboxsdk.maps.MapboxMap.onFinishLoadingStyle(MapboxMap.java:225)
W/System.err(31392): 	at com.mapbox.mapboxsdk.maps.MapView$MapCallback.onDidFinishLoadingStyle(MapView.java:1383)
W/System.err(31392): 	at com.mapbox.mapboxsdk.maps.MapChangeReceiver.onDidFinishLoadingStyle(MapChangeReceiver.java:198)
W/System.err(31392): 	at com.mapbox.mapboxsdk.maps.NativeMapView.onDidFinishLoadingStyle(NativeMapView.java:1166)
W/System.err(31392): 	at android.os.MessageQueue.nativePollOnce(Native Method)
W/System.err(31392): 	at android.os.MessageQueue.next(MessageQueue.java:326)
W/System.err(31392): 	at android.os.Looper.loop(Looper.java:181)
W/System.err(31392): 	at android.app.ActivityThread.main(ActivityThread.java:7073)
W/System.err(31392): 	at java.lang.reflect.Method.invoke(Native Method)
W/System.err(31392): 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
W/System.err(31392): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
E/libc++abi(31392): terminating with uncaught exception of type jni::PendingJavaException
F/libc    (31392): Fatal signal 6 (SIGABRT), code -6 (SI_TKILL) in tid 31392 (m.picple.ployee), pid 31392 (m.picple.ployee)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

 

 

해당 문제의 원인은 Google Play Locaion Service의 버전이 20.0.0에서 21.0.0으로 업데이트 되는 과정에서 발생한 문제라고 합니다. (참고, https://github.com/mapbox/mapbox-maps-android/issues/1752

이 오류를 처음 봤을때는 어떻게 해결해야 할지 몰라서  새로운 프로젝트를 만들어서 MapBox만 올려서 해봤습니다. 새로 만든 프로젝트에서는 문제없이 잘 동작하더군요. 

 

그래서 다시 개발중이던 프로젝트에 새로 만든 프로젝트의 코드를 옮겨 심고 돌려봤더니 문제가 발생했습니다. ㅠ.ㅠ 

이것저것 확인해보니 아래와 android/build.gradle 파일에 같은 차이점이 있었습니다. (차이점 1, 차이점 2)

 

1. 신규 프로젝트 with MapBox (flutter 3.7.3) 

buildscript {
    ext.kotlin_version = '1.6.10'
    repositories {
        google()
        mavenCentral()
    }

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

allprojects {
    repositories {
        google()
        mavenCentral()

        maven {
            url 'https://api.mapbox.com/downloads/v2/releases/maven'
            authentication {
                basic(BasicAuthentication)
            }
            credentials {
                // Do not change the username below.
                // This should always be `mapbox` (not your username).
                username = "mapbox"
                // Use the secret token you stored in gradle.properties as the password
                password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: ""
            }
        }
    }
}

2. 기존 프로젝트 with MapBox and Others (flutter 3.7.3)

buildscript {
    ext.kotlin_version = '1.6.10'
    
    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:4.1.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.gms:google-services:4.3.13'  // 차이점 1
    }
}

. . .

allprojects {
    repositories {
        google()
        mavenCentral()

        maven {
            url 'https://api.mapbox.com/downloads/v2/releases/maven'
            authentication {
                basic(BasicAuthentication)
            }
            credentials {
                // Do not change the username below.
                // This should always be `mapbox` (not your username).
                username = "mapbox"
                // Use the secret token you stored in gradle.properties as the password
                password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: ""
            }
        }

        configurations.all { // 차이점 2
            resolutionStrategy {
                force "com.google.android.gms:play-services-location:21.0.1"
            }
        }
    }
}

 

기존 프로젝트에서는 디펜던시에 "classpath 'com.google.gms:google-services:4.3.13'" 를 사용하고 있어서 해당 오류가 발생한것으로 판단하고 allProjects/repositories의 conf 정보를 변경했더니 문제 없이 정상동작했습니다.

 

해결방법

차이점 2번의 버전 정보를 20.0.0 으로 수정하기!

configurations.all {
    resolutionStrategy {
        force "com.google.android.gms:play-services-location:20.0.0"
    }
}

 

다른분들은 시간 많이 안 뺐겼으면 좋겠네요 :)

 


 

728x90