androidkotlinopenstreetmaposmdroid

crash when i try to create a path between two points in osmdroid


I have recently started studying android and kotlin programming, I'm trying to create an application that allows you to create one or more routes on a map, save it and then retrieve it when necessary. I chose to use osmDroid and osmBonusPack because open source but I don't find much documentation online, I'm trying to visualize a path between two Markers, I was able to visualize two markers and draw a straight line between two other points, now I'm trying to make the path but I don't understand how to proceed. Following the tutorial:

https://github.com/MKergall/osmbonuspack/wiki/Tutorial_1

trying to put some println("check") i understand that the app crashes when it gets to the line:

val road: Road = roadManager.getRoad(waypoints)

what's my problem? what is the error:

E/AndroidRuntime: FATAL EXCEPTION: main Process: uk.co.lorenzopulcinelli.trackapp, PID: 28815 java.lang.NoClassDefFoundError: Failed resolution of: Lokhttp3/Request$Builder;

?

    package uk.co.lorenzopulcinelli.trackapp
    
    import android.Manifest
    import android.content.pm.PackageManager
    import android.os.Bundle
    import android.util.DisplayMetrics
    import androidx.appcompat.app.AppCompatActivity
    import androidx.core.app.ActivityCompat
    import androidx.preference.PreferenceManager
    import org.osmdroid.api.IMapController
    import org.osmdroid.bonuspack.routing.OSRMRoadManager
    import org.osmdroid.bonuspack.routing.Road
    import org.osmdroid.bonuspack.routing.RoadManager
    import org.osmdroid.config.Configuration
    import org.osmdroid.config.Configuration.*
    import org.osmdroid.tileprovider.tilesource.TileSourceFactory
    import org.osmdroid.util.GeoPoint
    import org.osmdroid.views.CustomZoomButtonsController
    import org.osmdroid.views.MapView
    import org.osmdroid.views.overlay.compass.CompassOverlay
    import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
    import org.osmdroid.views.overlay.*
    import org.osmdroid.views.overlay.gestures.RotationGestureOverlay
    import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider
    import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
    
    import org.osmdroid.views.overlay.Marker
    
    
    
    
    class MainActivity : AppCompatActivity() {
        private lateinit var mapView : MapView
        private lateinit var myLocationNewOverlay: MyLocationNewOverlay
        private lateinit var compassOverlay: CompassOverlay
        private lateinit var mapController: IMapController
        private lateinit var userAgent: String
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            
            requestPermission()
    
            
            getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this))
    
    
            
            setContentView(R.layout.activity_main)
            mapView = findViewById<MapView>(R.id.map)
            mapView.setTileSource(TileSourceFactory.MAPNIK)
            mapView.zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
    
    
            
            mapController = mapView.controller
            
            myLocationNewOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), mapView)
            myLocationNewOverlay.enableMyLocation()
            myLocationNewOverlay.enableMyLocation()
            myLocationNewOverlay.isDrawAccuracyEnabled = true
            myLocationNewOverlay.runOnFirstFix { runOnUiThread {
                mapController.animateTo(myLocationNewOverlay.myLocation)
                mapController.setZoom(9.5)
                }
            }
            mapView.overlays.add(myLocationNewOverlay)
    
            
            Configuration.getInstance().userAgentValue = "lolloMaps"
    
            
            println(myLocationNewOverlay.myLocation)
            println("creato")
    
    
            
            compassOverlay = CompassOverlay(this, InternalCompassOrientationProvider(this), mapView)
            compassOverlay.enableCompass()
            mapView.overlays.add(compassOverlay)
    
    
            // val overlay = LatLonGridlineOverlay2()
            // mapView.overlays.add(overlay)
    
            
            val rotationGestureOverlay = RotationGestureOverlay(mapView)
            rotationGestureOverlay.isEnabled
            mapView.setMultiTouchControls(true)
            mapView.overlays.add(rotationGestureOverlay)
    
            
            myLocationNewOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), mapView)
            myLocationNewOverlay.enableMyLocation()
            mapView.overlays.add(myLocationNewOverlay)
    
            
            val dm : DisplayMetrics = resources.displayMetrics
            val scaleBarOverlay = ScaleBarOverlay(mapView)
            scaleBarOverlay.setCentred(true)
            scaleBarOverlay.setScaleBarOffset(dm.widthPixels / 2, 10)
            mapView.overlays.add(scaleBarOverlay)
    
    
            mioMarker(55.45, 22.48, 1)
            mioMarker(47.22, 15.48, 2)
    
    
            val pnt1: GeoPoint = GeoPoint(52.50, 13.40)
            val pnt2: GeoPoint = GeoPoint(42.54, 27.40)
            val polyline: Polyline = Polyline(mapView)
            polyline.addPoint(pnt1)
            polyline.addPoint(pnt2)
            mapView.overlays.add(polyline)
            mapView.invalidate()
    
    
            val roadManager:RoadManager = OSRMRoadManager(this, )
            val waypoints = ArrayList<GeoPoint>()
            val startPoint: GeoPoint = GeoPoint(66.7, -14.6)
            waypoints.add(startPoint)
            val endPoint: GeoPoint = GeoPoint(48.4, -1.9)
            waypoints.add(endPoint)
            val road: Road = roadManager.getRoad(waypoints)
            val roadOverlay: Polyline = RoadManager.buildRoadOverlay(road)
            mapView.overlays.add(roadOverlay)
            mapView.invalidate()
    
        }
    
        override fun onResume() {
            super.onResume()
            mapView.onResume()
        }
    
        override fun onPause() {
            super.onPause()
            mapView.onPause()
        }
    
        
        private fun hasPermission() : Boolean {
            
            return ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
        }
    
    
    
        private fun requestPermission() {
    
            val permission = mutableListOf<String>()
    
            if (!hasPermission()) {
    
                permission.add(Manifest.permission.ACCESS_FINE_LOCATION)
            }
    
            if (permission.isNotEmpty()) {
                ActivityCompat.requestPermissions(this, permission.toTypedArray(), 0)
            }
        }
    
        // fun add Marker
        private fun mioMarker(lati: Double, longi: Double, i: Int) {
            val pinMarker = Marker(mapView)
            val geoPoint = GeoPoint(lati, longi)
            pinMarker.position = geoPoint
            pinMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER)
            pinMarker.title = "Title"
            pinMarker.subDescription = "i'm pin #$i, my coordinate $lati, $longi."
            pinMarker.isDraggable = true
            mapView.overlays.add(pinMarker)
            mapView.invalidate()
    
        }
    }

this is my manifest:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="uk.co.lorenzopulcinelli.trackapp">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-feature android:name="android.hardware.location.network" android:required="false" />
    <uses-feature android:name="android.hardware.location.gps" android:required="false" />
    <uses-feature android:name="android.hardware.telephony" android:required="false" />
    <uses-feature android:name="android.hardware.wifi" android:required="false" />


    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.TrackApp"
        tools:targetApi="31">



        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

and this is my buil.gradle:

        plugins {
        id 'com.android.application'
        id 'org.jetbrains.kotlin.android'
    }
    
    android {
        compileSdk 32
    
        defaultConfig {
            applicationId "uk.co.lorenzopulcinelli.trackapp"
            minSdk 21
            targetSdk 32
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
        kotlinOptions {
            jvmTarget = '1.8'
        }
    }
    
    dependencies {
        implementation 'androidx.preference:preference:1.2.0' //aggiunta per utilizzare import androidx.preference.PreferenceManager
        implementation 'com.google.android.gms:play-services-location:20.0.0' //aggiunta per richiedere permessi localizzazione
    
        implementation 'androidx.core:core-ktx:1.8.0'
        implementation 'androidx.appcompat:appcompat:1.4.2'
        implementation 'com.google.android.material:material:1.6.1'
        implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
        implementation files('/home/acer/AndroidStudioProjects/TrackApp/app/libs/osmbonuspack_6.9.0.aar')
        implementation files('/home/acer/AndroidStudioProjects/TrackApp/app/libs/osmdroid-android-6.1.13.aar')
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    }

below my Logcat:

07/01 17:42:05: Launching 'app' on Xiaomi Redmi Note 7.
Install successfully finished in 4 s 662 ms.
$ adb shell am start -n "uk.co.lorenzopulcinelli.trackapp/uk.co.lorenzopulcinelli.trackapp.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 28815 on device 'xiaomi-redmi_note_7-16dccaa4'.
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/Perf: Connecting to perf service.
I/FeatureParser: can't find lavender.xml in assets/device_features/,it may be in /system/etc/device_features
E/libc: Access denied finding property "ro.vendor.df.effect.conflict"
W/inelli.trackapp: type=1400 audit(0.0:93235): avc: denied { read } for name="u:object_r:vendor_displayfeature_prop:s0" dev="tmpfs" ino=17716 scontext=u:r:untrusted_app:s0:c168,c257,c512,c768 tcontext=u:object_r:vendor_displayfeature_prop:s0 tclass=file permissive=0
E/Perf: Fail to get file list uk.co.lorenzopulcinelli.trackapp
E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
I/StorageUtils: /data/user/0/uk.co.lorenzopulcinelli.trackapp/files is writable
I/StorageUtils: /storage/emulated/0/Android/data/uk.co.lorenzopulcinelli.trackapp/files is writable
I/StorageUtils: /storage/4A6A-676E/Android/data/uk.co.lorenzopulcinelli.trackapp/files is writable
I/StorageUtils: /data/user/0/uk.co.lorenzopulcinelli.trackapp/files is writable
I/StorageUtils: /storage/emulated/0/Android/data/uk.co.lorenzopulcinelli.trackapp/files is writable
I/StorageUtils: /storage/4A6A-676E/Android/data/uk.co.lorenzopulcinelli.trackapp/files is writable
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.trackapp activity: uk.co.lorenzopulcinelli.trackapp.MainActivity@148f695
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.trackapp activity: uk.co.lorenzopulcinelli.trackapp.MainActivity@148f695
W/inelli.trackap: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
W/inelli.trackap: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.trackapp activity: uk.co.lorenzopulcinelli.trackapp.MainActivity@148f695
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.trackapp activity: uk.co.lorenzopulcinelli.trackapp.MainActivity@148f695
I/OsmDroid: Using tile source specified in layout attributes: Mapnik
I/OsmDroid: Using tile source: Mapnik
I/OsmDroid: Tile cache increased from 0 to 9
I/System.out: null
I/System.out: creato
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.trackapp activity: uk.co.lorenzopulcinelli.trackapp.MainActivity@148f695
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.trackapp activity: uk.co.lorenzopulcinelli.trackapp.MainActivity@148f695
I/chatty: uid=10424(uk.co.lorenzopulcinelli.trackapp) identical 5 lines
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.trackapp activity: uk.co.lorenzopulcinelli.trackapp.MainActivity@148f695
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.trackapp activity: uk.co.lorenzopulcinelli.trackapp.MainActivity@148f695
I/chatty: uid=10424(uk.co.lorenzopulcinelli.trackapp) identical 6 lines
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.trackapp activity: uk.co.lorenzopulcinelli.trackapp.MainActivity@148f695
I/System.out: inizio
I/System.out: passo1 - creoArrayList
I/System.out: passo2 - CreoPuntiEAggiungoInArrayList
I/System.out: passo3 - CreoStrada
D/BONUSPACK: OSRMRoadManager.getRoads:https://routing.openstreetmap.de/routed-car/route/v1/driving/-14.6000000000,66.7000000000;-1.9000000000,48.4000000000?alternatives=false&overview=full&steps=true
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: uk.co.lorenzopulcinelli.trackapp, PID: 28815
    java.lang.NoClassDefFoundError: Failed resolution of: Lokhttp3/Request$Builder;
        at org.osmdroid.bonuspack.utils.HttpConnection.doGet(HttpConnection.java:65)
        at org.osmdroid.bonuspack.utils.BonusPackHelper.requestStringFromUrl(BonusPackHelper.java:59)
        at org.osmdroid.bonuspack.routing.OSRMRoadManager.getRoads(OSRMRoadManager.java:194)
        at org.osmdroid.bonuspack.routing.OSRMRoadManager.getRoad(OSRMRoadManager.java:286)
        at uk.co.lorenzopulcinelli.trackapp.MainActivity.onCreate(MainActivity.kt:132)
        at android.app.Activity.performCreate(Activity.java:7893)
        at android.app.Activity.performCreate(Activity.java:7880)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3286)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3460)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2047)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7590)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "okhttp3.Request$Builder" on path: DexPathList[[zip file "/data/app/uk.co.lorenzopulcinelli.trackapp-jx1_0YR4HzgrzlHgIcGy8w==/base.apk"],nativeLibraryDirectories=[/data/app/uk.co.lorenzopulcinelli.trackapp-jx1_0YR4HzgrzlHgIcGy8w==/lib/arm64, /system/lib64, /system/product/lib64]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:230)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at org.osmdroid.bonuspack.utils.HttpConnection.doGet(HttpConnection.java:65) 
        at org.osmdroid.bonuspack.utils.BonusPackHelper.requestStringFromUrl(BonusPackHelper.java:59) 
        at org.osmdroid.bonuspack.routing.OSRMRoadManager.getRoads(OSRMRoadManager.java:194) 
        at org.osmdroid.bonuspack.routing.OSRMRoadManager.getRoad(OSRMRoadManager.java:286) 
        at uk.co.lorenzopulcinelli.trackapp.MainActivity.onCreate(MainActivity.kt:132) 
        at android.app.Activity.performCreate(Activity.java:7893) 
        at android.app.Activity.performCreate(Activity.java:7880) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3286) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3460) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2047) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:224) 
        at android.app.ActivityThread.main(ActivityThread.java:7590) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) 
I/Process: Sending signal. PID: 28815 SIG: 9


Solution

  • I found the solution by importing dependencies that I had overlooked I followed the answer to this question:

    Unable to resolve dependency for retrofit2

    in particular it was enough to add these dependencies, these in my app build.gradle file:

    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.google.code.gson:gson:2.8.2'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
    implementation 'com.squareup.okhttp3:okhttp:3.10.0'
    

    and these in my project build.gradle file:

    allprojects {
        repositories {
            google()
            maven { url "https://jitpack.io" }
            jcenter()
        }
    }