Remove Mapbox SDK and use Mapbox HTTP API

pull/1369/head
Alex Baker 5 years ago
parent 14f5015fac
commit 9126c29aaa

@ -201,7 +201,6 @@ dependencies {
implementation("com.google.auth:google-auth-library-oauth2-http:0.23.0") implementation("com.google.auth:google-auth-library-oauth2-http:0.23.0")
implementation("androidx.work:work-runtime:${Versions.work}") implementation("androidx.work:work-runtime:${Versions.work}")
implementation("androidx.work:work-runtime-ktx:${Versions.work}") implementation("androidx.work:work-runtime-ktx:${Versions.work}")
implementation("com.mapbox.mapboxsdk:mapbox-sdk-services:5.8.0")
implementation("com.etesync:journalmanager:1.1.1") implementation("com.etesync:journalmanager:1.1.1")
implementation("com.etebase:client:2.3.2") implementation("com.etebase:client:2.3.2")
implementation("com.github.QuadFlask:colorpicker:0.0.15") implementation("com.github.QuadFlask:colorpicker:0.0.15")

@ -48,13 +48,6 @@
license: The Apache Software License, Version 2.0 license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: http://developer.android.com/tools/extras/support-library.html url: http://developer.android.com/tools/extras/support-library.html
- artifact: com.mapbox.mapboxsdk:mapbox-sdk-services:+
name: Mapbox services
copyrightHolder: Mapbox
license: MIT License
licenseUrl: http://www.opensource.org/licenses/mit-license.php
url: https://github.com/mapbox/mapbox-java
forceGenerate: true
- artifact: androidx.core:core:+ - artifact: androidx.core:core:+
name: Android Support Library compat name: Android Support Library compat
copyrightHolder: Android Open Source Project copyrightHolder: Android Open Source Project
@ -178,13 +171,6 @@
license: The Apache Software License, Version 2.0 license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: http://commons.apache.org/proper/commons-lang/ url: http://commons.apache.org/proper/commons-lang/
- artifact: com.mapbox.mapboxsdk:mapbox-sdk-geojson:+
name: Mapbox services-geojson
copyrightHolder: Mapbox
license: MIT License
licenseUrl: http://www.opensource.org/licenses/mit-license.php
url: https://github.com/mapbox/mapbox-java
forceGenerate: true
- artifact: androidx.loader:loader:+ - artifact: androidx.loader:loader:+
name: Android Support Library loader name: Android Support Library loader
copyrightHolder: Android Open Source Project copyrightHolder: Android Open Source Project
@ -318,13 +304,6 @@
license: The Apache Software License, Version 2.0 license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://developer.android.com/topic/libraries/architecture/index.html url: https://developer.android.com/topic/libraries/architecture/index.html
- artifact: com.mapbox.mapboxsdk:mapbox-sdk-core:+
name: Mapbox services-core
copyrightHolder: Mapbox
license: MIT License
licenseUrl: http://www.opensource.org/licenses/mit-license.php
url: https://github.com/mapbox/mapbox-java
forceGenerate: true
- artifact: androidx.lifecycle:lifecycle-process:+ - artifact: androidx.lifecycle:lifecycle-process:+
name: Android Lifecycle Process name: Android Lifecycle Process
copyrightHolder: Android Open Source Project copyrightHolder: Android Open Source Project
@ -404,11 +383,6 @@
copyrightHolder: Square, Inc. copyrightHolder: Square, Inc.
license: The Apache Software License, Version 2.0 license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
- artifact: com.squareup.retrofit2:retrofit:+
name: Retrofit
copyrightHolder: Square, Inc.
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
- artifact: org.slf4j:slf4j-api:+ - artifact: org.slf4j:slf4j-api:+
name: SLF4J API Module name: SLF4J API Module
copyrightHolder: QOS.ch copyrightHolder: QOS.ch
@ -433,11 +407,6 @@
license: The Apache Software License, Version 2.0 license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/JakeWharton/butterknife/ url: https://github.com/JakeWharton/butterknife/
- artifact: com.squareup.retrofit2:converter-gson:+
name: "Converter: Gson"
copyrightHolder: Square, Inc.
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
- artifact: com.squareup.okhttp3:logging-interceptor:+ - artifact: com.squareup.okhttp3:logging-interceptor:+
name: OkHttp Logging Interceptor name: OkHttp Logging Interceptor
copyrightHolder: Square, Inc. copyrightHolder: Square, Inc.
@ -629,18 +598,6 @@
copyrightHolder: Google LLC copyrightHolder: Google LLC
license: The Apache Software License, Version 2.0 license: The Apache Software License, Version 2.0
url: https://github.com/google/auto/tree/master/value url: https://github.com/google/auto/tree/master/value
- artifact: com.mapbox.mapboxsdk:mapbox-sdk-directions-refresh-models:+
name: mapbox-sdk-directions-refresh-models
copyrightHolder: Mapbox
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/mapbox/mapbox-java
- artifact: com.mapbox.mapboxsdk:mapbox-sdk-directions-models:+
name: mapbox-sdk-directions-models
copyrightHolder: Mapbox
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/mapbox/mapbox-java
- artifact: com.sun.mail:android-mail:+ - artifact: com.sun.mail:android-mail:+
name: android-mail name: android-mail
copyrightHolder: Oracle and/or its affiliates copyrightHolder: Oracle and/or its affiliates

@ -55,7 +55,7 @@ object TestUtilities {
private fun fromResource(path: String): at.bitfire.ical4android.Task = private fun fromResource(path: String): at.bitfire.ical4android.Task =
fromString(readFile(path)) fromString(readFile(path))
private fun readFile(path: String): String { fun readFile(path: String): String {
val uri = javaClass.classLoader?.getResource(path)?.toURI() val uri = javaClass.classLoader?.getResource(path)?.toURI()
?: throw IllegalArgumentException() ?: throw IllegalArgumentException()
val paths = Paths.get(uri) val paths = Paths.get(uri)

@ -23,13 +23,15 @@ internal class LocationModule {
@ApplicationContext context: Context, @ApplicationContext context: Context,
preferences: Preferences, preferences: Preferences,
playServices: PlayServices, playServices: PlayServices,
inventory: Inventory): PlaceSearchProvider { inventory: Inventory,
mapboxSearchProvider: MapboxSearchProvider
): PlaceSearchProvider {
return if (preferences.useGooglePlaces() return if (preferences.useGooglePlaces()
&& playServices.isPlayServicesAvailable && playServices.isPlayServicesAvailable
&& inventory.hasPro) { && inventory.hasPro) {
GooglePlacesSearchProvider(context) GooglePlacesSearchProvider(context)
} else { } else {
MapboxSearchProvider(context) mapboxSearchProvider
} }
} }

@ -122,20 +122,6 @@
"url": "http://developer.android.com/tools/extras/support-library.html", "url": "http://developer.android.com/tools/extras/support-library.html",
"libraryName": "Android Support AnimatedVectorDrawable" "libraryName": "Android Support AnimatedVectorDrawable"
}, },
{
"artifactId": {
"name": "mapbox-sdk-services",
"group": "com.mapbox.mapboxsdk",
"version": "+"
},
"copyrightHolder": "Mapbox",
"copyrightStatement": "Copyright © Mapbox. All rights reserved.",
"license": "MIT License",
"licenseUrl": "http://www.opensource.org/licenses/mit-license.php",
"normalizedLicense": "mit",
"url": "https://github.com/mapbox/mapbox-java",
"libraryName": "Mapbox services"
},
{ {
"artifactId": { "artifactId": {
"name": "core", "name": "core",
@ -427,20 +413,6 @@
"url": "http://commons.apache.org/proper/commons-lang/", "url": "http://commons.apache.org/proper/commons-lang/",
"libraryName": "Apache Commons Lang" "libraryName": "Apache Commons Lang"
}, },
{
"artifactId": {
"name": "mapbox-sdk-geojson",
"group": "com.mapbox.mapboxsdk",
"version": "+"
},
"copyrightHolder": "Mapbox",
"copyrightStatement": "Copyright © Mapbox. All rights reserved.",
"license": "MIT License",
"licenseUrl": "http://www.opensource.org/licenses/mit-license.php",
"normalizedLicense": "mit",
"url": "https://github.com/mapbox/mapbox-java",
"libraryName": "Mapbox services-geojson"
},
{ {
"artifactId": { "artifactId": {
"name": "loader", "name": "loader",
@ -749,20 +721,6 @@
"url": "https://developer.android.com/topic/libraries/architecture/index.html", "url": "https://developer.android.com/topic/libraries/architecture/index.html",
"libraryName": "Android Lifecycle-Common" "libraryName": "Android Lifecycle-Common"
}, },
{
"artifactId": {
"name": "mapbox-sdk-core",
"group": "com.mapbox.mapboxsdk",
"version": "+"
},
"copyrightHolder": "Mapbox",
"copyrightStatement": "Copyright © Mapbox. All rights reserved.",
"license": "MIT License",
"licenseUrl": "http://www.opensource.org/licenses/mit-license.php",
"normalizedLicense": "mit",
"url": "https://github.com/mapbox/mapbox-java",
"libraryName": "Mapbox services-core"
},
{ {
"artifactId": { "artifactId": {
"name": "lifecycle-process", "name": "lifecycle-process",
@ -954,19 +912,6 @@
"normalizedLicense": "apache2", "normalizedLicense": "apache2",
"libraryName": "OkHttp" "libraryName": "OkHttp"
}, },
{
"artifactId": {
"name": "retrofit",
"group": "com.squareup.retrofit2",
"version": "+"
},
"copyrightHolder": "Square, Inc.",
"copyrightStatement": "Copyright © Square, Inc. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"libraryName": "Retrofit"
},
{ {
"artifactId": { "artifactId": {
"name": "slf4j-api", "name": "slf4j-api",
@ -1023,19 +968,6 @@
"url": "https://github.com/JakeWharton/butterknife/", "url": "https://github.com/JakeWharton/butterknife/",
"libraryName": "ButterKnife Annotations" "libraryName": "ButterKnife Annotations"
}, },
{
"artifactId": {
"name": "converter-gson",
"group": "com.squareup.retrofit2",
"version": "+"
},
"copyrightHolder": "Square, Inc.",
"copyrightStatement": "Copyright © Square, Inc. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"libraryName": "Converter: Gson"
},
{ {
"artifactId": { "artifactId": {
"name": "logging-interceptor", "name": "logging-interceptor",
@ -1499,34 +1431,6 @@
"url": "https://github.com/google/auto/tree/master/value", "url": "https://github.com/google/auto/tree/master/value",
"libraryName": "AutoValue Annotations" "libraryName": "AutoValue Annotations"
}, },
{
"artifactId": {
"name": "mapbox-sdk-directions-refresh-models",
"group": "com.mapbox.mapboxsdk",
"version": "+"
},
"copyrightHolder": "Mapbox",
"copyrightStatement": "Copyright © Mapbox. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"url": "https://github.com/mapbox/mapbox-java",
"libraryName": "mapbox-sdk-directions-refresh-models"
},
{
"artifactId": {
"name": "mapbox-sdk-directions-models",
"group": "com.mapbox.mapboxsdk",
"version": "+"
},
"copyrightHolder": "Mapbox",
"copyrightStatement": "Copyright © Mapbox. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"url": "https://github.com/mapbox/mapbox-java",
"libraryName": "mapbox-sdk-directions-models"
},
{ {
"artifactId": { "artifactId": {
"name": "android-mail", "name": "android-mail",

@ -7,8 +7,6 @@ import android.net.Uri
import android.os.Parcel import android.os.Parcel
import android.os.Parcelable import android.os.Parcelable
import androidx.room.* import androidx.room.*
import com.mapbox.api.geocoding.v5.GeocodingCriteria
import com.mapbox.api.geocoding.v5.models.CarmenFeature
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.api.FilterListItem.NO_ORDER
import com.todoroo.astrid.helper.UUIDHelper import com.todoroo.astrid.helper.UUIDHelper
@ -212,30 +210,10 @@ class Place : Serializable, Parcelable {
longitude = geo.longitude.toDouble() longitude = geo.longitude.toDouble()
} }
@JvmStatic fun newPlace(mapPosition: MapPosition?): Place? { fun newPlace(mapPosition: MapPosition) = newPlace().apply {
if (mapPosition == null) {
return null
}
return newPlace().apply {
latitude = mapPosition.latitude latitude = mapPosition.latitude
longitude = mapPosition.longitude longitude = mapPosition.longitude
} }
}
@JvmStatic fun newPlace(feature: CarmenFeature): Place = newPlace().apply {
val types = feature.placeType()
name = if (types != null && types.contains(GeocodingCriteria.TYPE_ADDRESS)) {
"${feature.address()} ${feature.text()}"
} else {
feature.text()
}
address = feature.placeName()
latitude = feature.center()!!.latitude()
longitude = feature.center()!!.longitude()
}
@JvmStatic fun newPlace(): Place = Place().apply { uid = UUIDHelper.newUUID() } @JvmStatic fun newPlace(): Place = Place().apply { uid = UUIDHelper.newUUID() }
} }

@ -11,7 +11,6 @@ import org.tasks.data.LocationDao
import org.tasks.injection.BaseWorker import org.tasks.injection.BaseWorker
import org.tasks.location.Geocoder import org.tasks.location.Geocoder
import timber.log.Timber import timber.log.Timber
import java.io.IOException
@HiltWorker @HiltWorker
class ReverseGeocodeWork @AssistedInject constructor( class ReverseGeocodeWork @AssistedInject constructor(
@ -38,14 +37,14 @@ class ReverseGeocodeWork @AssistedInject constructor(
return Result.failure() return Result.failure()
} }
return try { return try {
val result = geocoder.reverseGeocode(place.mapPosition) val result = geocoder.reverseGeocode(place.mapPosition) ?: return Result.failure()
result.id = place.id result.id = place.id
result.uid = place.uid result.uid = place.uid
locationDao.update(result) locationDao.update(result)
localBroadcastManager.broadcastRefresh() localBroadcastManager.broadcastRefresh()
Timber.d("found $result") Timber.d("found $result")
Result.success() Result.success()
} catch (e: IOException) { } catch (e: Exception) {
firebase.reportException(e) firebase.reportException(e)
Result.failure() Result.failure()
} }

@ -21,11 +21,11 @@ class AndroidGeocoder @Inject constructor(@ApplicationContext context: Context)
val addresses = geocoder?.getFromLocation(mapPosition.latitude, mapPosition.longitude, 1) ?: emptyList() val addresses = geocoder?.getFromLocation(mapPosition.latitude, mapPosition.longitude, 1) ?: emptyList()
val place = newPlace(mapPosition) val place = newPlace(mapPosition)
if (addresses.isEmpty()) { if (addresses.isEmpty()) {
return@withContext place!! return@withContext place
} }
val address = addresses[0] val address = addresses[0]
if (address.maxAddressLineIndex >= 0) { if (address.maxAddressLineIndex >= 0) {
place!!.name = address.getAddressLine(0) place.name = address.getAddressLine(0)
val builder = StringBuilder(place.name) val builder = StringBuilder(place.name)
for (i in 1..address.maxAddressLineIndex) { for (i in 1..address.maxAddressLineIndex) {
builder.append(", ").append(address.getAddressLine(i)) builder.append(", ").append(address.getAddressLine(i))
@ -33,10 +33,10 @@ class AndroidGeocoder @Inject constructor(@ApplicationContext context: Context)
place.address = builder.toString() place.address = builder.toString()
} }
if (address.hasLatitude() && address.hasLongitude()) { if (address.hasLatitude() && address.hasLongitude()) {
place!!.latitude = address.latitude place.latitude = address.latitude
place.longitude = address.longitude place.longitude = address.longitude
} }
place!!.phone = address.phone place.phone = address.phone
place.url = address.url place.url = address.url
place place
} }

@ -3,5 +3,5 @@ package org.tasks.location
import org.tasks.data.Place import org.tasks.data.Place
interface Geocoder { interface Geocoder {
suspend fun reverseGeocode(mapPosition: MapPosition): Place suspend fun reverseGeocode(mapPosition: MapPosition): Place?
} }

@ -38,6 +38,7 @@ import org.tasks.billing.Inventory
import org.tasks.caldav.GeoUtils.toLikeString import org.tasks.caldav.GeoUtils.toLikeString
import org.tasks.data.LocationDao import org.tasks.data.LocationDao
import org.tasks.data.Place import org.tasks.data.Place
import org.tasks.data.Place.Companion.newPlace
import org.tasks.data.PlaceUsage import org.tasks.data.PlaceUsage
import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.DialogBuilder
import org.tasks.injection.InjectingAppCompatActivity import org.tasks.injection.InjectingAppCompatActivity
@ -232,7 +233,7 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC
val mapPosition = map.mapPosition ?: return val mapPosition = map.mapPosition ?: return
loadingIndicator.visibility = View.VISIBLE loadingIndicator.visibility = View.VISIBLE
lifecycleScope.launch { lifecycleScope.launch {
val place = geocoder.reverseGeocode(mapPosition) val place = geocoder.reverseGeocode(mapPosition) ?: newPlace(mapPosition)
loadingIndicator.visibility = View.GONE loadingIndicator.visibility = View.GONE
returnPlace(place) returnPlace(place)
} }

@ -1,48 +1,72 @@
package org.tasks.location package org.tasks.location
import android.content.Context import android.content.Context
import com.google.gson.GsonBuilder import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonParser import com.google.gson.JsonParser
import com.mapbox.api.geocoding.v5.MapboxGeocoding
import com.mapbox.geojson.Point
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.tasks.BuildConfig import okhttp3.OkHttpClient
import okhttp3.Request
import org.tasks.DebugNetworkInterceptor
import org.tasks.R import org.tasks.R
import org.tasks.data.Place import org.tasks.data.Place
import org.tasks.data.Place.Companion.newPlace import org.tasks.data.Place.Companion.newPlace
import timber.log.Timber import org.tasks.preferences.Preferences
import java.io.IOException
import javax.inject.Inject import javax.inject.Inject
class MapboxGeocoder @Inject constructor(@ApplicationContext context: Context) : Geocoder { class MapboxGeocoder @Inject constructor(
private val token: String = context.getString(R.string.mapbox_key) @ApplicationContext context: Context,
private val preferences: Preferences,
private val interceptor: DebugNetworkInterceptor,
) : Geocoder {
private val token = context.getString(R.string.mapbox_key)
override suspend fun reverseGeocode(mapPosition: MapPosition): Place = override suspend fun reverseGeocode(mapPosition: MapPosition): Place? =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
val response = MapboxGeocoding.builder() val builder = OkHttpClient().newBuilder()
.accessToken(token) if (preferences.isFlipperEnabled) {
.query(Point.fromLngLat(mapPosition.longitude, mapPosition.latitude)) interceptor.apply(builder)
.build()
.executeCall()
val body = response.body()
if (response.isSuccessful && body != null) {
Timber.d(prettyPrint(body.toJson()))
val features = body.features()
if (features.size > 0) {
return@withContext newPlace(features[0])
} }
val client = builder.build()
val url = "https://api.mapbox.com/geocoding/v5/mapbox.places/${mapPosition.longitude},${mapPosition.latitude}.json?access_token=$token"
val response = client.newCall(Request.Builder().get().url(url).build()).execute()
if (response.isSuccessful) {
response.body?.string()?.let { jsonToPlace(it) }
} else { } else {
Timber.e(response.errorBody()!!.string()) throw IOException("${response.code} ${response.message}")
} }
newPlace(mapPosition)!!
} }
companion object { companion object {
private fun prettyPrint(json: String): String { internal fun jsonToPlace(json: String): Place? =
return if (BuildConfig.DEBUG) { JsonParser
GsonBuilder().setPrettyPrinting().create().toJson(JsonParser().parse(json)) .parseString(json).asJsonObject.getAsJsonArray("features")
} else json .takeIf { it.size() > 0 }?.get(0)?.asJsonObject
?.let { toPlace(it) }
internal fun toPlace(feature: JsonObject): Place =
newPlace().apply {
val types = feature.get("place_type").asStringList
val text = feature.get("text").asString
name = if (types.contains("address")) {
"${feature.get("address").asString} $text"
} else {
text
}
address = feature.get("place_name").asString
feature.get("center").asCoordinates.let {
longitude = it.first
latitude = it.second
} }
} }
private val JsonElement.asStringList: List<String>
get() = asJsonArray.map { it.asString }
private val JsonElement.asCoordinates: Pair<Double, Double>
get() = asJsonArray.let { Pair(it[0].asDouble, it[1].asDouble) }
}
} }

@ -2,22 +2,26 @@ package org.tasks.location
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import com.mapbox.api.geocoding.v5.MapboxGeocoding import com.google.gson.JsonParser
import com.mapbox.api.geocoding.v5.models.CarmenFeature import dagger.hilt.android.qualifiers.ApplicationContext
import com.mapbox.api.geocoding.v5.models.GeocodingResponse
import com.mapbox.geojson.Point
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import org.tasks.DebugNetworkInterceptor
import org.tasks.R import org.tasks.R
import org.tasks.data.Place import org.tasks.data.Place
import org.tasks.data.Place.Companion.newPlace import org.tasks.location.MapboxGeocoder.Companion.toPlace
import retrofit2.Call import org.tasks.preferences.Preferences
import retrofit2.Response import java.io.IOException
import java.util.* import javax.inject.Inject
import kotlin.coroutines.suspendCoroutine
class MapboxSearchProvider(private val context: Context) : PlaceSearchProvider { class MapboxSearchProvider @Inject constructor(
private var builder: MapboxGeocoding.Builder? = null @ApplicationContext context: Context,
private val preferences: Preferences,
private val interceptor: DebugNetworkInterceptor,
) : PlaceSearchProvider {
val token = context.getString(R.string.mapbox_key)
override fun restoreState(savedInstanceState: Bundle?) {} override fun restoreState(savedInstanceState: Bundle?) {}
@ -27,41 +31,39 @@ class MapboxSearchProvider(private val context: Context) : PlaceSearchProvider {
override suspend fun search(query: String, bias: MapPosition?): List<PlaceSearchResult> = override suspend fun search(query: String, bias: MapPosition?): List<PlaceSearchResult> =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
suspendCoroutine { cont -> val builder = OkHttpClient().newBuilder()
if (builder == null) { if (preferences.isFlipperEnabled) {
val token = context.getString(R.string.mapbox_key) interceptor.apply(builder)
builder = MapboxGeocoding.builder().autocomplete(true).accessToken(token)
if (bias != null) {
builder?.proximity(Point.fromLngLat(bias.longitude, bias.latitude))
} }
val proximity = bias?.let {
"&proximity=${bias.longitude},${bias.latitude}"
} }
builder val client = builder.build()
?.query(query) val url = "https://api.mapbox.com/geocoding/v5/mapbox.places/$query.json?access_token=$token$proximity"
?.build() val response = client.newCall(Request.Builder().get().url(url).build()).execute()
?.enqueueCall( if (response.isSuccessful) {
object : retrofit2.Callback<GeocodingResponse> { response.body?.string()?.let { jsonToSearchResults(it) } ?: emptyList()
override fun onResponse( } else {
call: Call<GeocodingResponse>, response: Response<GeocodingResponse>) { throw IOException("${response.code} ${response.message}")
val results: MutableList<PlaceSearchResult> = ArrayList()
results.clear()
for (feature in response.body()!!.features()) {
results.add(toSearchResult(feature))
}
cont.resumeWith(Result.success(results))
}
override fun onFailure(call: Call<GeocodingResponse>, t: Throwable) {
cont.resumeWith(Result.failure(t))
}
})
} }
} }
override suspend fun fetch(placeSearchResult: PlaceSearchResult): Place = override suspend fun fetch(placeSearchResult: PlaceSearchResult): Place =
placeSearchResult.place placeSearchResult.place
private fun toSearchResult(feature: CarmenFeature): PlaceSearchResult { companion object {
val place = newPlace(feature) internal fun jsonToSearchResults(json: String): List<PlaceSearchResult> =
return PlaceSearchResult(feature.id(), place.name, place.displayAddress, place) JsonParser
.parseString(json).asJsonObject.getAsJsonArray("features")
.map { it.asJsonObject }
.map {
val place = toPlace(it)
PlaceSearchResult(
it.get("id").asString,
place.name,
place.displayAddress,
place
)
}
} }
} }

@ -0,0 +1,34 @@
package org.tasks.location
import org.junit.Assert.assertEquals
import org.junit.Test
import org.tasks.TestUtilities.readFile
import org.tasks.location.MapboxGeocoder.Companion.jsonToPlace
class MapboxGeocoderTest {
@Test
fun poiGeocode() {
val place = jsonToPlace(readFile("mapbox/poi.json"))!!
assertEquals("Guaranteed Rate Field", place.name)
assertEquals(-87.63380599999999, place.longitude, 0.0)
assertEquals(41.8299365, place.latitude, 0.0)
assertEquals(
"Guaranteed Rate Field, 333 W 35th St, Chicago, Illinois 60616, United States",
place.address
)
}
@Test
fun addressGeocode() {
val place = jsonToPlace(readFile("mapbox/address.json"))!!
assertEquals("120 East 13th Street", place.name)
assertEquals(40.7330031, place.latitude, 0.0)
assertEquals(-73.9888929, place.longitude, 0.0)
assertEquals(
"120 East 13th Street, New York, New York 10003, United States",
place.address
)
}
}

@ -0,0 +1,43 @@
package org.tasks.location
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.tasks.TestUtilities.readFile
import org.tasks.location.MapboxSearchProvider.Companion.jsonToSearchResults
class MapboxPlaceSearchTest {
@Test
fun searchWithMultipleResults() {
val results = jsonToSearchResults(readFile("mapbox/search.json"))
assertEquals(
listOf(
"poi.627065251624",
"poi.472446436443",
"poi.89343",
"poi.549755920662",
"poi.755914248504"
),
results.map { it.id }
)
}
@Test
fun validatePlace() {
val place = jsonToSearchResults(readFile("mapbox/search.json"))[1]
assertEquals("poi.472446436443", place.id)
assertEquals("Portillo's", place.name)
assertEquals(-87.962508, place.place.longitude, 0.0)
assertEquals(41.895473, place.place.latitude, 0.0)
assertEquals(
"155 S Il Route 83, Elmhurst, Illinois 60126, United States",
place.address
)
}
@Test
fun emptySearchResults() =
assertTrue(jsonToSearchResults(readFile("mapbox/empty_search.json")).isEmpty())
}

@ -0,0 +1,407 @@
{
"type": "FeatureCollection",
"query": [
-73.989,
40.733
],
"features": [
{
"id": "address.5326841146807324",
"type": "Feature",
"place_type": [
"address"
],
"relevance": 1,
"properties": {
"accuracy": "rooftop"
},
"text": "East 13th Street",
"place_name": "120 East 13th Street, New York, New York 10003, United States",
"center": [
-73.9888929,
40.7330031
],
"geometry": {
"type": "Point",
"coordinates": [
-73.9888929,
40.7330031
]
},
"address": "120",
"context": [
{
"id": "neighborhood.2103290",
"text": "Greenwich Village"
},
{
"id": "postcode.13482670360296810",
"text": "10003"
},
{
"id": "locality.12696928000137850",
"wikidata": "Q11299",
"text": "Manhattan"
},
{
"id": "place.15278078705964500",
"wikidata": "Q60",
"text": "New York"
},
{
"id": "district.12113562209855570",
"wikidata": "Q500416",
"text": "New York County"
},
{
"id": "region.17349986251855570",
"wikidata": "Q1384",
"short_code": "US-NY",
"text": "New York"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "neighborhood.2103290",
"type": "Feature",
"place_type": [
"neighborhood"
],
"relevance": 1,
"properties": {},
"text": "Greenwich Village",
"place_name": "Greenwich Village, Manhattan, New York, New York 10003, United States",
"bbox": [
-74.005282,
40.72586,
-73.98734,
40.73907
],
"center": [
-74.0029,
40.7284
],
"geometry": {
"type": "Point",
"coordinates": [
-74.0029,
40.7284
]
},
"context": [
{
"id": "postcode.13482670360296810",
"text": "10003"
},
{
"id": "locality.12696928000137850",
"wikidata": "Q11299",
"text": "Manhattan"
},
{
"id": "place.15278078705964500",
"wikidata": "Q60",
"text": "New York"
},
{
"id": "district.12113562209855570",
"wikidata": "Q500416",
"text": "New York County"
},
{
"id": "region.17349986251855570",
"wikidata": "Q1384",
"short_code": "US-NY",
"text": "New York"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "postcode.13482670360296810",
"type": "Feature",
"place_type": [
"postcode"
],
"relevance": 1,
"properties": {},
"text": "10003",
"place_name": "New York, New York 10003, United States",
"bbox": [
-73.9996058238451,
40.7229310019,
-73.9798620096375,
40.7396749960342
],
"center": [
-73.99,
40.73
],
"geometry": {
"type": "Point",
"coordinates": [
-73.99,
40.73
]
},
"context": [
{
"id": "locality.12696928000137850",
"wikidata": "Q11299",
"text": "Manhattan"
},
{
"id": "place.15278078705964500",
"wikidata": "Q60",
"text": "New York"
},
{
"id": "district.12113562209855570",
"wikidata": "Q500416",
"text": "New York County"
},
{
"id": "region.17349986251855570",
"wikidata": "Q1384",
"short_code": "US-NY",
"text": "New York"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "locality.12696928000137850",
"type": "Feature",
"place_type": [
"locality"
],
"relevance": 1,
"properties": {
"wikidata": "Q11299"
},
"text": "Manhattan",
"place_name": "Manhattan, New York, New York, United States",
"bbox": [
-74.047313153061,
40.679573,
-73.907,
40.8820749648427
],
"center": [
-73.9597,
40.7903
],
"geometry": {
"type": "Point",
"coordinates": [
-73.9597,
40.7903
]
},
"context": [
{
"id": "place.15278078705964500",
"wikidata": "Q60",
"text": "New York"
},
{
"id": "district.12113562209855570",
"wikidata": "Q500416",
"text": "New York County"
},
{
"id": "region.17349986251855570",
"wikidata": "Q1384",
"short_code": "US-NY",
"text": "New York"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "place.15278078705964500",
"type": "Feature",
"place_type": [
"place"
],
"relevance": 1,
"properties": {
"wikidata": "Q60"
},
"text": "New York",
"place_name": "New York, New York, United States",
"bbox": [
-74.2590879797556,
40.477399,
-73.7008392055224,
40.917576401307
],
"center": [
-73.9808,
40.7648
],
"geometry": {
"type": "Point",
"coordinates": [
-73.9808,
40.7648
]
},
"context": [
{
"id": "district.12113562209855570",
"wikidata": "Q500416",
"text": "New York County"
},
{
"id": "region.17349986251855570",
"wikidata": "Q1384",
"short_code": "US-NY",
"text": "New York"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "district.12113562209855570",
"type": "Feature",
"place_type": [
"district"
],
"relevance": 1,
"properties": {
"wikidata": "Q500416"
},
"text": "New York County",
"place_name": "New York County, New York, United States",
"bbox": [
-74.047227,
40.682932,
-73.907,
40.879278
],
"center": [
-74,
40.7167
],
"geometry": {
"type": "Point",
"coordinates": [
-74,
40.7167
]
},
"context": [
{
"id": "region.17349986251855570",
"wikidata": "Q1384",
"short_code": "US-NY",
"text": "New York"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "region.17349986251855570",
"type": "Feature",
"place_type": [
"region"
],
"relevance": 1,
"properties": {
"wikidata": "Q1384",
"short_code": "US-NY"
},
"text": "New York",
"place_name": "New York, United States",
"bbox": [
-79.8578350999901,
40.4771391062446,
-71.7564918092633,
45.0239286969073
],
"center": [
-75.4652471468304,
42.751210955
],
"geometry": {
"type": "Point",
"coordinates": [
-75.4652471468304,
42.751210955
]
},
"context": [
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "country.19678805456372290",
"type": "Feature",
"place_type": [
"country"
],
"relevance": 1,
"properties": {
"wikidata": "Q30",
"short_code": "us"
},
"text": "United States",
"place_name": "United States",
"bbox": [
-179.9,
18.8163608007951,
-66.8847646185949,
71.4202919997506
],
"center": [
-97.9222112121185,
39.3812661305678
],
"geometry": {
"type": "Point",
"coordinates": [
-97.9222112121185,
39.3812661305678
]
}
}
],
"attribution": "NOTICE: © 2021 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained. POI(s) provided by Foursquare."
}

@ -0,0 +1,8 @@
{
"type": "FeatureCollection",
"query": [
"xjiebrbcidksn"
],
"features": [],
"attribution": "NOTICE: © 2021 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained. POI(s) provided by Foursquare."
}

@ -0,0 +1,341 @@
{
"type": "FeatureCollection",
"query": [
-87.63380599999999,
41.8299365
],
"features": [
{
"id": "poi.128849020577",
"type": "Feature",
"place_type": [
"poi"
],
"relevance": 1,
"properties": {
"wikidata": "Q633613",
"category": "baseball stadium, baseball, leisure",
"landmark": true,
"address": "333 W 35th St",
"foursquare": "40dcbc80f964a52080011fe3"
},
"text": "Guaranteed Rate Field",
"place_name": "Guaranteed Rate Field, 333 W 35th St, Chicago, Illinois 60616, United States",
"center": [
-87.63380599999999,
41.8299365
],
"geometry": {
"coordinates": [
-87.63380599999999,
41.8299365
],
"type": "Point"
},
"context": [
{
"id": "neighborhood.33950",
"text": "Bridgeport"
},
{
"id": "postcode.11036815072354260",
"text": "60616"
},
{
"id": "place.1924128844701850",
"wikidata": "Q1297",
"text": "Chicago"
},
{
"id": "district.8754923997749290",
"wikidata": "Q108418",
"text": "Cook County"
},
{
"id": "region.10854263468358810",
"wikidata": "Q1204",
"short_code": "US-IL",
"text": "Illinois"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "neighborhood.33950",
"type": "Feature",
"place_type": [
"neighborhood"
],
"relevance": 1,
"properties": {},
"text": "Bridgeport",
"place_name": "Bridgeport, Chicago, Illinois 60616, United States",
"bbox": [
-87.665847,
41.823142,
-87.630759,
41.849457
],
"center": [
-87.6512,
41.8381
],
"geometry": {
"type": "Point",
"coordinates": [
-87.6512,
41.8381
]
},
"context": [
{
"id": "postcode.11036815072354260",
"text": "60616"
},
{
"id": "place.1924128844701850",
"wikidata": "Q1297",
"text": "Chicago"
},
{
"id": "district.8754923997749290",
"wikidata": "Q108418",
"text": "Cook County"
},
{
"id": "region.10854263468358810",
"wikidata": "Q1204",
"short_code": "US-IL",
"text": "Illinois"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "postcode.11036815072354260",
"type": "Feature",
"place_type": [
"postcode"
],
"relevance": 1,
"properties": {},
"text": "60616",
"place_name": "Chicago, Illinois 60616, United States",
"bbox": [
-87.6466359591625,
41.8272291061023,
-87.592612118742,
41.8674338954049
],
"center": [
-87.62,
41.86
],
"geometry": {
"type": "Point",
"coordinates": [
-87.62,
41.86
]
},
"context": [
{
"id": "place.1924128844701850",
"wikidata": "Q1297",
"text": "Chicago"
},
{
"id": "district.8754923997749290",
"wikidata": "Q108418",
"text": "Cook County"
},
{
"id": "region.10854263468358810",
"wikidata": "Q1204",
"short_code": "US-IL",
"text": "Illinois"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "place.1924128844701850",
"type": "Feature",
"place_type": [
"place"
],
"relevance": 1,
"properties": {
"wikidata": "Q1297"
},
"text": "Chicago",
"place_name": "Chicago, Illinois, United States",
"bbox": [
-87.9058109309507,
41.6299229800457,
-87.523686109734,
42.0234323628388
],
"center": [
-87.6244,
41.8756
],
"geometry": {
"type": "Point",
"coordinates": [
-87.6244,
41.8756
]
},
"context": [
{
"id": "district.8754923997749290",
"wikidata": "Q108418",
"text": "Cook County"
},
{
"id": "region.10854263468358810",
"wikidata": "Q1204",
"short_code": "US-IL",
"text": "Illinois"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "district.8754923997749290",
"type": "Feature",
"place_type": [
"district"
],
"relevance": 1,
"properties": {
"wikidata": "Q108418"
},
"text": "Cook County",
"place_name": "Cook County, Illinois, United States",
"bbox": [
-88.263641,
41.469705,
-87.523907,
42.154292
],
"center": [
-87.71667,
41.8
],
"geometry": {
"type": "Point",
"coordinates": [
-87.71667,
41.8
]
},
"context": [
{
"id": "region.10854263468358810",
"wikidata": "Q1204",
"short_code": "US-IL",
"text": "Illinois"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "region.10854263468358810",
"type": "Feature",
"place_type": [
"region"
],
"relevance": 1,
"properties": {
"wikidata": "Q1204",
"short_code": "US-IL"
},
"text": "Illinois",
"place_name": "Illinois, United States",
"bbox": [
-91.5130799991365,
36.9702970055306,
-87.0117177165746,
42.553081292589
],
"center": [
-89.2749461071049,
40.1492928594
],
"geometry": {
"type": "Point",
"coordinates": [
-89.2749461071049,
40.1492928594
]
},
"context": [
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "country.19678805456372290",
"type": "Feature",
"place_type": [
"country"
],
"relevance": 1,
"properties": {
"wikidata": "Q30",
"short_code": "us"
},
"text": "United States",
"place_name": "United States",
"bbox": [
-179.9,
18.8163608007951,
-66.8847646185949,
71.4202919997506
],
"center": [
-97.9222112121185,
39.3812661305678
],
"geometry": {
"type": "Point",
"coordinates": [
-97.9222112121185,
39.3812661305678
]
}
}
],
"attribution": "NOTICE: © 2021 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained. POI(s) provided by Foursquare."
}

@ -0,0 +1,305 @@
{
"type": "FeatureCollection",
"query": [
"portillos"
],
"features": [
{
"id": "poi.627065251624",
"type": "Feature",
"place_type": [
"poi"
],
"relevance": 1,
"properties": {
"foursquare": "4b5b4c55f964a5209ff228e3",
"landmark": true,
"address": "635 W North Ave",
"category": "burger joint"
},
"text": "Portillo's",
"place_name": "Portillo's, 635 W North Ave, Villa Park, Illinois 60181, United States",
"center": [
-87.994203,
41.904793
],
"geometry": {
"coordinates": [
-87.994203,
41.904793
],
"type": "Point"
},
"context": [
{
"id": "neighborhood.277661",
"text": "South Addison"
},
{
"id": "postcode.5355712630239150",
"text": "60181"
},
{
"id": "place.14963076574860490",
"wikidata": "Q1863204",
"text": "Villa Park"
},
{
"id": "district.7716179127556280",
"wikidata": "Q109626",
"text": "DuPage County"
},
{
"id": "region.10854263468358810",
"wikidata": "Q1204",
"short_code": "US-IL",
"text": "Illinois"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "poi.472446436443",
"type": "Feature",
"place_type": [
"poi"
],
"relevance": 1,
"properties": {
"foursquare": "4b099068f964a520811923e3",
"landmark": true,
"address": "155 S Il Route 83",
"category": "hot dog, fast food"
},
"text": "Portillo's",
"place_name": "Portillo's, 155 S Il Route 83, Elmhurst, Illinois 60126, United States",
"center": [
-87.962508,
41.895473
],
"geometry": {
"coordinates": [
-87.962508,
41.895473
],
"type": "Point"
},
"context": [
{
"id": "neighborhood.287059",
"text": "Elmhurst City Centre"
},
{
"id": "postcode.14277643230845500",
"text": "60126"
},
{
"id": "place.10834168015713210",
"wikidata": "Q579542",
"text": "Elmhurst"
},
{
"id": "district.7716179127556280",
"wikidata": "Q109626",
"text": "DuPage County"
},
{
"id": "region.10854263468358810",
"wikidata": "Q1204",
"short_code": "US-IL",
"text": "Illinois"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "poi.89343",
"type": "Feature",
"place_type": [
"poi"
],
"relevance": 1,
"properties": {
"foursquare": "4a293d31f964a52071951fe3",
"landmark": true,
"address": "1500 Butterfield Rd",
"category": "fast food",
"maki": "fast-food"
},
"text": "Portillo's",
"place_name": "Portillo's, 1500 Butterfield Rd, Downers Grove, Illinois 60515, United States",
"center": [
-88.022488,
41.834394
],
"geometry": {
"coordinates": [
-88.022488,
41.834394
],
"type": "Point"
},
"context": [
{
"id": "neighborhood.272377",
"text": "Highland Hills"
},
{
"id": "postcode.10443155941018200",
"text": "60515"
},
{
"id": "place.13768728440893640",
"wikidata": "Q1007011",
"text": "Downers Grove"
},
{
"id": "district.7716179127556280",
"wikidata": "Q109626",
"text": "DuPage County"
},
{
"id": "region.10854263468358810",
"wikidata": "Q1204",
"short_code": "US-IL",
"text": "Illinois"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "poi.549755920662",
"type": "Feature",
"place_type": [
"poi"
],
"relevance": 1,
"properties": {
"foursquare": "4ae88c30f964a52053b021e3",
"landmark": true,
"address": "235 E North Ave",
"category": "hot dog, fast food"
},
"text": "Portillo's",
"place_name": "Portillo's, 235 E North Ave, Glendale Heights, Illinois 60139, United States",
"center": [
-88.08045,
41.902269
],
"geometry": {
"coordinates": [
-88.08045,
41.902269
],
"type": "Point"
},
"context": [
{
"id": "neighborhood.32979",
"text": "Shorewood"
},
{
"id": "postcode.7546533656837130",
"text": "60139"
},
{
"id": "place.10354477397635860",
"wikidata": "Q912145",
"text": "Glendale Heights"
},
{
"id": "district.7716179127556280",
"wikidata": "Q109626",
"text": "DuPage County"
},
{
"id": "region.10854263468358810",
"wikidata": "Q1204",
"short_code": "US-IL",
"text": "Illinois"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
},
{
"id": "poi.755914248504",
"type": "Feature",
"place_type": [
"poi"
],
"relevance": 1,
"properties": {
"foursquare": "4b44c97ff964a5202cfc25e3",
"landmark": true,
"address": "100 W Lake St",
"category": "hot dog, fast food"
},
"text": "Portillo's",
"place_name": "Portillo's, 100 W Lake St, Addison, Illinois 60101, United States",
"center": [
-87.991471,
41.933674
],
"geometry": {
"coordinates": [
-87.991471,
41.933674
],
"type": "Point"
},
"context": [
{
"id": "neighborhood.287037",
"text": "Michael Lane Area"
},
{
"id": "postcode.16750824071334230",
"text": "60101"
},
{
"id": "place.12939236967422170",
"wikidata": "Q353080",
"text": "Addison"
},
{
"id": "district.7716179127556280",
"wikidata": "Q109626",
"text": "DuPage County"
},
{
"id": "region.10854263468358810",
"wikidata": "Q1204",
"short_code": "US-IL",
"text": "Illinois"
},
{
"id": "country.19678805456372290",
"wikidata": "Q30",
"short_code": "us",
"text": "United States"
}
]
}
],
"attribution": "NOTICE: © 2021 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained. POI(s) provided by Foursquare."
}

@ -348,37 +348,20 @@
+| +--- androidx.work:work-runtime:2.5.0 (*) +| +--- androidx.work:work-runtime:2.5.0 (*)
+| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.21 -> 1.4.30 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.21 -> 1.4.30 (*)
+| \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1 (*) +| \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1 (*)
++--- com.mapbox.mapboxsdk:mapbox-sdk-services:5.8.0
+| +--- com.mapbox.mapboxsdk:mapbox-sdk-core:5.8.0
+| | +--- com.google.code.gson:gson:2.8.6
+| | +--- com.squareup.retrofit2:retrofit:2.7.2
+| | | \--- com.squareup.okhttp3:okhttp:3.14.7 -> 4.8.1 (*)
+| | +--- com.squareup.retrofit2:converter-gson:2.7.2
+| | | +--- com.squareup.retrofit2:retrofit:2.7.2 (*)
+| | | \--- com.google.code.gson:gson:2.8.5 -> 2.8.6
+| | \--- com.squareup.okhttp3:logging-interceptor:3.12.7
+| | \--- com.squareup.okhttp3:okhttp:3.12.7 -> 4.8.1 (*)
+| +--- com.mapbox.mapboxsdk:mapbox-sdk-geojson:5.8.0
+| | \--- com.google.code.gson:gson:2.8.6
+| +--- com.mapbox.mapboxsdk:mapbox-sdk-directions-models:5.8.0
+| | +--- com.mapbox.mapboxsdk:mapbox-sdk-geojson:5.8.0 (*)
+| | \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
+| \--- com.mapbox.mapboxsdk:mapbox-sdk-directions-refresh-models:5.8.0
+| +--- com.mapbox.mapboxsdk:mapbox-sdk-directions-models:5.8.0 (*)
+| \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
++--- com.etesync:journalmanager:1.1.1 ++--- com.etesync:journalmanager:1.1.1
+| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71 -> 1.4.21 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71 -> 1.4.21 (*)
+| +--- com.madgag.spongycastle:core:1.54.0.0 +| +--- com.madgag.spongycastle:core:1.54.0.0
+| +--- com.madgag.spongycastle:prov:1.54.0.0 +| +--- com.madgag.spongycastle:prov:1.54.0.0
+| | \--- com.madgag.spongycastle:core:1.54.0.0 +| | \--- com.madgag.spongycastle:core:1.54.0.0
+| +--- com.squareup.okhttp3:logging-interceptor:3.12.1 -> 3.12.7 (*) +| +--- com.squareup.okhttp3:logging-interceptor:3.12.1
+| | \--- com.squareup.okhttp3:okhttp:3.12.1 -> 4.8.1 (*)
+| +--- com.google.code.gson:gson:1.7.2 -> 2.8.6 +| +--- com.google.code.gson:gson:1.7.2 -> 2.8.6
+| +--- org.apache.commons:commons-collections4:4.1 +| +--- org.apache.commons:commons-collections4:4.1
+| +--- org.apache.commons:commons-lang3:3.8.1 -> 3.9 +| +--- org.apache.commons:commons-lang3:3.8.1 -> 3.9
+| \--- commons-codec:commons-codec:1.7 -> 1.11 +| \--- commons-codec:commons-codec:1.7 -> 1.11
++--- com.etebase:client:2.3.2 ++--- com.etebase:client:2.3.2
+| +--- androidx.annotation:annotation:1.1.0 +| +--- androidx.annotation:annotation:1.1.0
+| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 -> 3.12.7 (*) +| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 (*)
++--- com.github.QuadFlask:colorpicker:0.0.15 ++--- com.github.QuadFlask:colorpicker:0.0.15
+| \--- androidx.appcompat:appcompat:1.1.0 -> 1.2.0 (*) +| \--- androidx.appcompat:appcompat:1.1.0 -> 1.2.0 (*)
+\--- com.github.openid:AppAuth-Android:0.8.0 +\--- com.github.openid:AppAuth-Android:0.8.0

@ -478,37 +478,20 @@
+| +--- androidx.work:work-runtime:2.5.0 (*) +| +--- androidx.work:work-runtime:2.5.0 (*)
+| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.21 -> 1.4.30 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.21 -> 1.4.30 (*)
+| \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1 (*) +| \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1 (*)
++--- com.mapbox.mapboxsdk:mapbox-sdk-services:5.8.0
+| +--- com.mapbox.mapboxsdk:mapbox-sdk-core:5.8.0
+| | +--- com.google.code.gson:gson:2.8.6
+| | +--- com.squareup.retrofit2:retrofit:2.7.2
+| | | \--- com.squareup.okhttp3:okhttp:3.14.7 -> 4.8.1 (*)
+| | +--- com.squareup.retrofit2:converter-gson:2.7.2
+| | | +--- com.squareup.retrofit2:retrofit:2.7.2 (*)
+| | | \--- com.google.code.gson:gson:2.8.5 -> 2.8.6
+| | \--- com.squareup.okhttp3:logging-interceptor:3.12.7
+| | \--- com.squareup.okhttp3:okhttp:3.12.7 -> 4.8.1 (*)
+| +--- com.mapbox.mapboxsdk:mapbox-sdk-geojson:5.8.0
+| | \--- com.google.code.gson:gson:2.8.6
+| +--- com.mapbox.mapboxsdk:mapbox-sdk-directions-models:5.8.0
+| | +--- com.mapbox.mapboxsdk:mapbox-sdk-geojson:5.8.0 (*)
+| | \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
+| \--- com.mapbox.mapboxsdk:mapbox-sdk-directions-refresh-models:5.8.0
+| +--- com.mapbox.mapboxsdk:mapbox-sdk-directions-models:5.8.0 (*)
+| \--- androidx.annotation:annotation:1.0.0 -> 1.1.0
++--- com.etesync:journalmanager:1.1.1 ++--- com.etesync:journalmanager:1.1.1
+| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71 -> 1.4.21 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71 -> 1.4.21 (*)
+| +--- com.madgag.spongycastle:core:1.54.0.0 +| +--- com.madgag.spongycastle:core:1.54.0.0
+| +--- com.madgag.spongycastle:prov:1.54.0.0 +| +--- com.madgag.spongycastle:prov:1.54.0.0
+| | \--- com.madgag.spongycastle:core:1.54.0.0 +| | \--- com.madgag.spongycastle:core:1.54.0.0
+| +--- com.squareup.okhttp3:logging-interceptor:3.12.1 -> 3.12.7 (*) +| +--- com.squareup.okhttp3:logging-interceptor:3.12.1
+| | \--- com.squareup.okhttp3:okhttp:3.12.1 -> 4.8.1 (*)
+| +--- com.google.code.gson:gson:1.7.2 -> 2.8.6 +| +--- com.google.code.gson:gson:1.7.2 -> 2.8.6
+| +--- org.apache.commons:commons-collections4:4.1 +| +--- org.apache.commons:commons-collections4:4.1
+| +--- org.apache.commons:commons-lang3:3.8.1 -> 3.9 +| +--- org.apache.commons:commons-lang3:3.8.1 -> 3.9
+| \--- commons-codec:commons-codec:1.7 -> 1.11 +| \--- commons-codec:commons-codec:1.7 -> 1.11
++--- com.etebase:client:2.3.2 ++--- com.etebase:client:2.3.2
+| +--- androidx.annotation:annotation:1.1.0 +| +--- androidx.annotation:annotation:1.1.0
+| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 -> 3.12.7 (*) +| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 (*)
++--- com.github.QuadFlask:colorpicker:0.0.15 ++--- com.github.QuadFlask:colorpicker:0.0.15
+| \--- androidx.appcompat:appcompat:1.1.0 -> 1.2.0 (*) +| \--- androidx.appcompat:appcompat:1.1.0 -> 1.2.0 (*)
+\--- com.github.openid:AppAuth-Android:0.8.0 +\--- com.github.openid:AppAuth-Android:0.8.0

Loading…
Cancel
Save