I'm trying to develop my application, I initially wrote all the code in the MainActivity.kt class for simplicity. Now I am trying to organize my project in several classes, one of these I would like to contain the functions for the navigator that I'm developing (NavFunProva.kt), moving the function that creates a path between two points ( routePath() ) I'm encountering a problem which I report below, I have inserted some println in the function to understand where it hangs and I have noticed that it happens when it arrives at the line
road = roadManager.getRoad(waypoints)
this is the whole function
fun routePath(p1Latit: Double, p1Laong: Double, p2Latit: Double, p2Laong: Double){
println("inizio")
val roadManager: RoadManager = OSRMRoadManager(context, "lolloMaps")
OSRMRoadManager.MEAN_BY_FOOT
println("passo1 - creoArrayList")
val waypoints = arrayListOf<GeoPoint>()
println("passo2 - CreoPuntiEAggiungoInArrayList")
val startPoint: GeoPoint = GeoPoint(p1Latit, p1Laong) //43.12628, 12.04705
waypoints.add(startPoint)
val endPoint: GeoPoint = GeoPoint(p2Latit, p2Laong) //43.12124, 11.97211
waypoints.add(endPoint)
println("passo3 - CreoStrada")
road = roadManager.getRoad(waypoints)
if (road.mStatus != Road.STATUS_OK){
Toast.makeText(context, "Errore nel caricamento di road - status = " road.mStatus, Toast.LENGTH_SHORT).show()
}
println("passo4 - CreoPolilinea")
val roadOverlay: Polyline = RoadManager.buildRoadOverlay(road)
println("passo5 - AggiungoPolilineaAllaMappa")
mapView.overlays.add(roadOverlay)
mapView.invalidate()
// crea checkpoint lungo il percorso
val nodeIcon: Drawable? = ResourcesCompat.getDrawable(resources, R.drawable.marker_node, null)
for (i: Int in road.mNodes.indices){
val node: RoadNode = road.mNodes[i]
val nodeMarker: Marker = Marker(mapView)
nodeMarker.position = node.mLocation
nodeMarker.icon = nodeIcon
nodeMarker.title = "Passo $i"
mapView.overlays.add(nodeMarker)
// aggiunge informazioni nelle finestre dei checkpoint
nodeMarker.snippet = node.mInstructions
nodeMarker.subDescription = Road.getLengthDurationText(context,node.mLength, node.mDuration)
// var icon: Drawable = resources.getDrawable(R.drawable.ic_continue)
// nodeMarker.image = icon
}
}
and this is the error
08/30 18:58:55: Launching 'app' on Xiaomi Redmi Note 7.
Install successfully finished in 7 s 441 ms.
$ adb shell am start -n "uk.co.lorenzopulcinelli.navigationdrawer/uk.co.lorenzopulcinelli.navigationdrawer.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 6312 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/avigationdrawe: Late-enabling -Xcheck:jni
E/avigationdrawe: Unknown bits set in runtime_flags: 0x8000
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
W/avigationdrawer: type=1400 audit(0.0:143699): avc: denied { read } for name="u:object_r:vendor_displayfeature_prop:s0" dev="tmpfs" ino=18148 scontext=u:r:untrusted_app:s0:c184,c257,c512,c768 tcontext=u:object_r:vendor_displayfeature_prop:s0 tclass=file permissive=0
E/libc: Access denied finding property "ro.vendor.df.effect.conflict"
E/Perf: Fail to get file list uk.co.lorenzopulcinelli.navigationdrawer
E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
E/Perf: Fail to get file list uk.co.lorenzopulcinelli.navigationdrawer
E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
W/Looper: Slow Looper main: Long Msg: seq=2 plan=18:59:02.567 late=2ms wall=1016ms running=859ms runnable=69ms io=8ms h=android.app.ActivityThread$H w=110
I/StorageUtils: /data/user/0/uk.co.lorenzopulcinelli.navigationdrawer/files is writable
W/BpBinder: Slow Binder: BpBinder transact took 676 ms, interface=android.os.storage.IStorageManager, code=35 oneway=false
I/StorageUtils: /storage/emulated/0/Android/data/uk.co.lorenzopulcinelli.navigationdrawer/files is writable
I/StorageUtils: /storage/4A6A-676E/Android/data/uk.co.lorenzopulcinelli.navigationdrawer/files is writable
I/StorageUtils: /data/user/0/uk.co.lorenzopulcinelli.navigationdrawer/files is writable
I/StorageUtils: /storage/emulated/0/Android/data/uk.co.lorenzopulcinelli.navigationdrawer/files is writable
I/StorageUtils: /storage/4A6A-676E/Android/data/uk.co.lorenzopulcinelli.navigationdrawer/files is writable
I/StorageUtils: /data/user/0/uk.co.lorenzopulcinelli.navigationdrawer/files/osmdroid is writable
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.navigationdrawer activity: uk.co.lorenzopulcinelli.navigationdrawer.MainActivity@506693c
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.navigationdrawer activity: uk.co.lorenzopulcinelli.navigationdrawer.MainActivity@506693c
W/avigationdrawe: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
W/avigationdrawe: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.navigationdrawer activity: uk.co.lorenzopulcinelli.navigationdrawer.MainActivity@506693c
I/chatty: uid=10440(uk.co.lorenzopulcinelli.navigationdrawer) identical 1 line
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.navigationdrawer activity: uk.co.lorenzopulcinelli.navigationdrawer.MainActivity@506693c
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
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.navigationdrawer activity: uk.co.lorenzopulcinelli.navigationdrawer.MainActivity@506693c
I/chatty: uid=10440(uk.co.lorenzopulcinelli.navigationdrawer) identical 6 lines
D/ForceDarkHelper: updateByCheckExcludeList: pkg: uk.co.lorenzopulcinelli.navigationdrawer activity: uk.co.lorenzopulcinelli.navigationdrawer.MainActivity@506693c
I/System.out: null
I/System.out: creato
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/12.0470500000,43.1262800000;11.9721100000,43.1212400000?alternatives=false&overview=full&steps=true
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: uk.co.lorenzopulcinelli.navigationdrawer, PID: 6312
java.lang.RuntimeException: Unable to start activity ComponentInfo{uk.co.lorenzopulcinelli.navigationdrawer/uk.co.lorenzopulcinelli.navigationdrawer.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3311)
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.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at android.content.ContextWrapper.getResources(ContextWrapper.java:93)
at android.view.ContextThemeWrapper.getResourcesInternal(ContextThemeWrapper.java:134)
at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:128)
at androidx.appcompat.app.AppCompatActivity.getResources(AppCompatActivity.java:609)
at android.content.Context.getString(Context.java:648)
at org.osmdroid.bonuspack.routing.OSRMRoadManager.buildInstructions(OSRMRoadManager.java:302)
at org.osmdroid.bonuspack.routing.OSRMRoadManager.getRoads(OSRMRoadManager.java:257)
at org.osmdroid.bonuspack.routing.OSRMRoadManager.getRoad(OSRMRoadManager.java:286)
at uk.co.lorenzopulcinelli.navigationdrawer.NavFunProva.routePath(NavFunProva.kt:49)
at uk.co.lorenzopulcinelli.navigationdrawer.MainActivity.onCreate(MainActivity.kt:136)
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: 6312 SIG: 9
below I report my MainActivity.kt and the NavFun.kt class
this is MainActivity.kt
package uk.co.lorenzopulcinelli.navigationdrawer
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.drawerlayout.widget.DrawerLayout
import com.google.android.material.navigation.NavigationView
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.StrictMode
import android.util.DisplayMetrics
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.res.ResourcesCompat
import androidx.preference.PreferenceManager
import org.osmdroid.api.IMapController
import org.osmdroid.bonuspack.clustering.RadiusMarkerClusterer
import org.osmdroid.bonuspack.location.NominatimPOIProvider
import org.osmdroid.bonuspack.location.POI
import org.osmdroid.bonuspack.routing.OSRMRoadManager
import org.osmdroid.bonuspack.routing.Road
import org.osmdroid.bonuspack.routing.RoadManager
import org.osmdroid.bonuspack.routing.RoadNode
import org.osmdroid.bonuspack.utils.BonusPackHelper
import org.osmdroid.config.Configuration
import org.osmdroid.config.Configuration.*
import org.osmdroid.events.MapEventsReceiver
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 toggle: ActionBarDrawerToggle
var context: Context = this
lateinit var mapView : MapView
private lateinit var myLocationNewOverlay: MyLocationNewOverlay
private lateinit var compassOverlay: CompassOverlay
private lateinit var mapController: IMapController
// private lateinit var editTextLatitudine: EditText
// private lateinit var editTextLongitudine: EditText
override fun onCreate(savedInstanceState: Bundle?) {
// disabilita la policy di strictMode nella onCreate per non fare chiamate network in async tasks
val policy: StrictMode.ThreadPolicy = StrictMode.ThreadPolicy.Builder().permitAll().build()
StrictMode.setThreadPolicy(policy)
super.onCreate(savedInstanceState)
//richiesta per gestire i permessi
requestPermission()
// inizializza la configurazione di osmdroid, non funziona se non si importa org.osmdroid.config.Configuration.*
getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this))
//crea la mappa
setContentView(R.layout.activity_main)
mapView = findViewById<MapView>(R.id.map)
mapView.setTileSource(TileSourceFactory.MAPNIK)
mapView.zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
// crea MapController e setta posizione iniziale
mapController = mapView.controller
// crea overlay posizione
myLocationNewOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), mapView)
myLocationNewOverlay.enableMyLocation()
myLocationNewOverlay.enableMyLocation()
myLocationNewOverlay.isDrawAccuracyEnabled = true
myLocationNewOverlay.runOnFirstFix { runOnUiThread {
mapController.animateTo(myLocationNewOverlay.myLocation)
mapController.setZoom(9.0)
}
}
mapView.overlays.add(myLocationNewOverlay)
//set user agent
Configuration.getInstance().userAgentValue = "lolloMaps"
// controllo
println(myLocationNewOverlay.myLocation)
println("creato")
// attiva bussola, Non Funziona!
compassOverlay = CompassOverlay(this, InternalCompassOrientationProvider(this), mapView)
compassOverlay.enableCompass()
mapView.overlays.add(compassOverlay)
// attivare griglia latitudine e longitudine
// val overlay = LatLonGridlineOverlay2()
// mapView.overlays.add(overlay)
// abilita gesture rotazione e zoom
val rotationGestureOverlay = RotationGestureOverlay(mapView)
rotationGestureOverlay.isEnabled
mapView.setMultiTouchControls(true)
mapView.overlays.add(rotationGestureOverlay)
// abilita mia posizione
myLocationNewOverlay = MyLocationNewOverlay(GpsMyLocationProvider(this), mapView)
myLocationNewOverlay.enableMyLocation()
mapView.overlays.add(myLocationNewOverlay)
// abilita overlay scala
val dm : DisplayMetrics = resources.displayMetrics
val scaleBarOverlay = ScaleBarOverlay(mapView)
scaleBarOverlay.setCentred(true)
scaleBarOverlay.setScaleBarOffset(dm.widthPixels / 2, 10)
mapView.overlays.add(scaleBarOverlay)
// abilita comandi sulla mappa, single tap e long press
val mapEventsReceiver: MapEventsReceiverImpl = MapEventsReceiverImpl()
val mapEventsOverlay: MapEventsOverlay = MapEventsOverlay(mapEventsReceiver)
mapView.overlays.add(mapEventsOverlay)
// traccia percorso tra due punti
val navFunProva: NavFunProva = NavFunProva()
navFunProva.routePath(43.12628, 12.04705, 43.12124, 11.97211)
// codice per menu laterale
val drawerLayout: DrawerLayout = findViewById(R.id.drawerLayout)
val navView: NavigationView = findViewById(R.id.nav_view)
toggle = ActionBarDrawerToggle(this, drawerLayout, R.string.open, R.string.close)
drawerLayout.addDrawerListener(toggle)
toggle.syncState()
supportActionBar?.setDisplayHomeAsUpEnabled(true)
navView.setNavigationItemSelectedListener {
when(it.itemId){
R.id.nav_home -> Toast.makeText(applicationContext, "Clicked Home", Toast.LENGTH_SHORT).show()
R.id.nav_message -> Toast.makeText(applicationContext, "Clicked Message", Toast.LENGTH_SHORT).show()
R.id.nav_sync -> Toast.makeText(applicationContext, "Clicked Sync", Toast.LENGTH_SHORT).show()
R.id.nav_trash -> Toast.makeText(applicationContext, "Clicked Trash", Toast.LENGTH_SHORT).show()
R.id.nav_settings -> Toast.makeText(applicationContext, "Clicked Settings", Toast.LENGTH_SHORT).show()
R.id.nav_login -> Toast.makeText(applicationContext, "Clicked Login", Toast.LENGTH_SHORT).show()
R.id.nav_share -> Toast.makeText(applicationContext, "Clicked Share", Toast.LENGTH_SHORT).show()
R.id.nav_rate_us -> Toast.makeText(applicationContext, "Clicked Rate Us", Toast.LENGTH_SHORT).show()
}
true
}
}
override fun onResume() {
super.onResume()
mapView.onResume()
}
override fun onPause() {
super.onPause()
mapView.onPause()
}
//funzione per controllare se ho i permessi
private fun hasPermission() : Boolean {
// ritorna true quando abbiamo i permessi
return ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
//funzione per richiedere i permessi
private fun requestPermission() {
//aggiungo i permessi ad una lista
val permission = mutableListOf<String>()
// se non ho i permessi
if (!hasPermission()) {
// aggiungo i permesi alla lista
permission.add(Manifest.permission.ACCESS_FINE_LOCATION)
}
// concede i permessi nella lista
if (permission.isNotEmpty()) {
ActivityCompat.requestPermissions(this, permission.toTypedArray(), 0)
}
}
// funzione del menu laterale
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (toggle.onOptionsItemSelected(item)){
return true
}
return super.onOptionsItemSelected(item)
}
}
and this is NavFunProva.kt
package uk.co.lorenzopulcinelli.navigationdrawer
import android.content.Context
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.widget.EditText
import android.widget.Toast
import androidx.core.content.res.ResourcesCompat
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.bonuspack.routing.RoadNode
import org.osmdroid.config.Configuration.*
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.MapView
import org.osmdroid.views.overlay.*
import org.osmdroid.views.overlay.compass.CompassOverlay
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay
class NavFunProva {
private lateinit var road: Road
// var mapView: MapView = mainActivity.mapView
private var mainActivity: MainActivity = MainActivity()
private var context: Context = mainActivity.context
// funzione per creare percorso fra due punti
fun routePath(p1Latit: Double, p1Laong: Double, p2Latit: Double, p2Laong: Double){
println("inizio")
val roadManager: RoadManager = OSRMRoadManager(context, "lolloMaps")
OSRMRoadManager.MEAN_BY_FOOT
println("passo1 - creoArrayList")
val waypoints = arrayListOf<GeoPoint>()
println("passo2 - CreoPuntiEAggiungoInArrayList")
val startPoint: GeoPoint = GeoPoint(p1Latit, p1Laong) //43.12628, 12.04705
waypoints.add(startPoint)
val endPoint: GeoPoint = GeoPoint(p2Latit, p2Laong) //43.12124, 11.97211
waypoints.add(endPoint)
println("passo3 - CreoStrada")
road = roadManager.getRoad(waypoints)
if (road.mStatus != Road.STATUS_OK){
Toast.makeText(context, "Errore nel caricamento di road - status = " road.mStatus, Toast.LENGTH_SHORT).show()
}
println("passo4 - CreoPolilinea")
val roadOverlay: Polyline = RoadManager.buildRoadOverlay(road)
println("passo5 - AggiungoPolilineaAllaMappa")
mapView.overlays.add(roadOverlay)
mapView.invalidate()
// crea checkpoint lungo il percorso
val nodeIcon: Drawable? = ResourcesCompat.getDrawable(resources, R.drawable.marker_node, null)
for (i: Int in road.mNodes.indices){
val node: RoadNode = road.mNodes[i]
val nodeMarker: Marker = Marker(mapView)
nodeMarker.position = node.mLocation
nodeMarker.icon = nodeIcon
nodeMarker.title = "Passo $i"
mapView.overlays.add(nodeMarker)
// aggiunge informazioni nelle finestre dei checkpoint
nodeMarker.snippet = node.mInstructions
nodeMarker.subDescription = Road.getLengthDurationText(context,node.mLength, node.mDuration)
// var icon: Drawable = resources.getDrawable(R.drawable.ic_continue)
// nodeMarker.image = icon
}
}
/*
// funzione per aggiungere 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 = "io sono il pin #$i con coordinate $lati, $longi."
pinMarker.isDraggable = true
mapView.overlays.add(pinMarker)
mapView.invalidate()
}
}
CodePudding user response:
You should not be doing this in the NavFunProva
:
private var mainActivity: MainActivity = MainActivity()
private var context: Context = mainActivity.context
You should not be creating an Activity
instance by Yourself. Activities
are created and managed by the Android system as the activity has more to its creation than just calling its constructor. This is why this error happened - the mainActivity.context
was not fully initialized and the osmdroid
library tried to call getResource
on an invalid, null
context
resulting in a NullPointerException
.
Instead You can pass the context
to the NavFunProva
constructor:
class NavFunProva(private val context: Context) {
...
}
And the use it in MainActivity
like this:
val navFunProva: NavFunProva = NavFunProva(this)
navFunProva.routePath(43.12628, 12.04705, 43.12124, 11.97211)
CodePudding user response:
From the error you get, I understand that you are using null instead of context because you haven't initialized it yet.
Can you try:
val navFunProva: NavFunProva = NavFunProva(this)
and change the constructor of your class to:
class NavFunProva(val context: Activity) {
Remaining code
}
And let me know if it works?