FAQ & Troubleshooting
This page covers frequently asked questions and common issues when using the Lazarillo SDK.
Frequently Asked Questions
General
How can I start using the SDK?
If you want to start using the SDK, you need to contact Lazarillo in order to get the API key for the package, then follow the instructions on the Installation page.
Which android version is supported?
This library has a minimum version of Android 5.1 / API level 22. The target and compile SDK version is API 35.
What mapping engine does the SDK use?
The SDK uses MapLibre GL (version 11.12.1), not Google Maps. MapLibre is an open-source mapping library that provides high-performance vector tile rendering.
Does the SDK require Google Play Services?
Yes, the SDK uses Google Play Services for the Fused Location Provider (GPS). Bluetooth beacon scanning uses the AltBeacon library and does not require Play Services.
Can I use the SDK without indoor beacons?
Yes. Without beacons, the SDK falls back to GPS-only positioning. Indoor features (floor detection, indoor navigation) will not be available, but outdoor mapping and navigation work normally.
How large is the SDK?
The SDK AAR file is relatively lightweight. The main dependencies (MapLibre, Retrofit, AltBeacon) add approximately 5-8 MB to your APK. Use Android App Bundles to minimize the impact per device.
Location Tracking
Why does location tracking stop when I zoom the map?
By default, MapLibre automatically deactivates location tracking (CameraMode.TRACKING_GPS) when users interact with the map (zoom, pan, etc.). This is the standard behavior to prevent unexpected camera movements.
However, you can configure automatic reactivation of tracking after zoom changes using the new TrackingConfig:
val lzMapConfig = LazarilloMapConfig()
lzMapConfig.trackingConfig = TrackingConfig(
enableReactivation = true, // Enable automatic reactivation
reactivationDelayMs = 1000L, // Wait 1 second before reactivating
preserveTrackingParams = true, // Keep original tracking settings
maxReactivationAttempts = 3, // Limit reactivation attempts
enableDebugLogging = false // Enable debug logs if needed
)This configuration will automatically reactivate tracking after zoom changes, preserving your original tracking parameters (pitch, zoom, padding).
How do I configure tracking for navigation apps?
For navigation apps where continuous tracking is important, use this configuration:
trackingConfig = TrackingConfig(
enableReactivation = true,
reactivationDelayMs = 500L, // Fast reactivation
preserveTrackingParams = true,
maxReactivationAttempts = 10, // More attempts for reliability
enableDebugLogging = true // Enable logs for debugging
)Does the tracking configuration affect performance?
No, the tracking configuration only affects behavior when enableReactivation = true. By default (enableReactivation = false), there’s no performance impact and the behavior remains unchanged from previous versions.
Why is indoor location inaccurate?
Indoor accuracy depends on:
- Number and placement of beacons in the venue
- Bluetooth environment (interference, reflections)
- Device Bluetooth hardware quality
Typical indoor accuracy is 1-3 meters with properly configured beacons.
Maps
Can I customize map styles without code changes?
Yes. Map styles are managed remotely by the Lazarillo backend. Colors, icons, text sizes, and layer visibility can be updated server-side without requiring app updates. Contact Lazarillo to request style changes.
How do I restrict the map to a specific venue area?
Use the limitToRadius option in LazarilloMapConfig:
val config = LazarilloMapConfig().apply {
parentPlaceId = "YOUR_PLACE_ID"
limitToRadius = 500.0 // Meters from venue center
}Troubleshooting
Location Component Issues
User Location Marker Not Appearing
Problem: The user’s location marker doesn’t show on the map.
Possible Causes and Solutions:
-
LocationComponent not activated
// Solution: Ensure position repository is set before enabling lzMap.setLocationProvider(positionRepository) lzMap.toggleLocationComponent(true) -
Position repository is null
// Check if position repository is properly initialized if (positionRepository == null) { // Initialize your position repository first positionRepository = buildPositionRepository() lzMap.setLocationProvider(positionRepository) } -
Indoor location on wrong floor
- The marker is automatically hidden when the user is on a different floor than currently displayed
- Solution: Change to the user’s floor or check if the user is actually on the displayed floor
-
LocationComponent permissions
// Ensure location permissions are granted if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Request location permissions } -
Wait for map to be ready:
lzMap = LazarilloMap(...) { // Map is ready -- now safe to enable location lzMap?.setLocationProvider(repo) lzMap?.toggleLocationComponent(true) }
Location Component Activation Errors
Problem: Getting toggleLocationComponent_error events.
Common Error Messages:
"locationProvider is null": Position repository not set"Failed to activate LocationComponent": MapLibre LocationComponent issues
Solutions:
-
Set position repository first:
// Always set the position repository before enabling location lzMap.setLocationProvider(positionRepository) lzMap.toggleLocationComponent(true) -
Check LocationComponent state:
// The SDK automatically checks and attempts to reactivate // Monitor logs for activation attempts -
Verify map is ready:
// Ensure the map is fully loaded before enabling location lzMap = LazarilloMap(...) { // Map is ready, now safe to enable location lzMap.setLocationProvider(positionRepository) lzMap.toggleLocationComponent(true) }
Location Not Updating
Problem: Location marker appears but does not move.
Solutions:
-
Check motion detection:
- If
useMotionDetection = true, the SDK only emits location updates when the user is moving. Stand still to confirm initial location, then walk to trigger updates.
- If
-
Check Bluetooth for indoor locations:
- Indoor positioning requires active Bluetooth scanning. Ensure Bluetooth is enabled on the device.
- Verify
BLUETOOTH_SCANpermission is granted (required on API 31+).
-
Verify beacon data is loaded:
lifecycleScope.launch { LzSdkManager.loadCacheForLocationUpdates("YOUR_PLACE_ID") }
Place Marker Issues
Place Markers Not Showing
Problem: Place markers don’t appear on the map.
Possible Causes:
- Wrong floor: Markers are on a different floor than currently displayed
- Marker creation failed: Check the callback for errors
- Symbol manager not ready: Map not fully initialized
Solutions:
// Check marker creation result
lzMap.addPlaceMarker(place) { result ->
result.onSuccess { marker ->
println("Marker created successfully")
}.onFailure { error ->
println("Marker creation failed: ${error.message}")
}
}
// Verify current floor matches marker floor
val currentFloor = lzMap.currentShowingFloor?.id
val markerFloor = place.inFloor.firstOrNull()
if (currentFloor != markerFloor) {
// Change to the correct floor or marker won't be visible
lzMap.setFloorById(markerFloor ?: "") {}
}Ensure map is fully initialized: only add markers after the onLazarilloMapReady callback fires.
Place Marker Images Not Loading
Problem: Place markers show as text instead of logos.
Possible Causes:
- Logo URL invalid: The place logo URL is broken or inaccessible
- Network issues: Can’t download the logo image
- Image format unsupported: Logo format not supported
Solutions:
// Check if place has a valid logo
if (place.logo != null) {
val logoUrl = place.logo.getUrlString()
if (logoUrl.isNullOrEmpty()) {
println("Place has no valid logo URL")
}
} else {
println("Place has no logo, will use text marker")
}Map Loading Issues
Map Not Loading
Problem: Map appears blank or doesn’t load.
Possible Causes:
- Invalid API key: Check your API key
- Invalid place ID: The parent place ID doesn’t exist
- Network connectivity: No internet connection
- Style loading failed: Map style couldn’t be loaded
- SDK not initialized:
LzSdkManager.initialize()must be called before creating aLazarilloMap
Solutions:
// Verify API key and place ID
LzSdkManager.initialize(
apiKey = "your_valid_api_key",
targetParentPlaceId = "valid_place_id"
)
// Check if SDK is active
if (!LzSdkManager.isSdkActive()) {
Log.e("SDK", "SDK not active -- check API key")
}
// Check network connectivity
// Ensure device has internet access
// Monitor map loading
lzMap = LazarilloMap(...) {
println("Map loaded successfully")
}Floor Selector Not Working
Problem: Floor selector doesn’t show floors or doesn’t change floors.
Possible Causes:
- No floors available: Place has no indoor floors
- Floor selector hidden: Configuration hides the floor selector
- Floor data not loaded: Place data not fully loaded
Solutions:
// Check if place has floors
val floors = currentShowingPlace?.innerFloors
if (floors.isNullOrEmpty()) {
println("Place has no indoor floors")
}
// Ensure floor selector is visible
val config = LazarilloMapConfig().apply {
hideFloorSelector = false // Make sure it's not hidden
}
// Manually change floors
lzMap.setFloorById("target_floor_id") {
println("Floor changed successfully")
}Route Display Issues
Problem: Route calculation succeeds but nothing appears on the map.
Solutions:
-
Verify
addRoute()is called after map is ready:lzMap = LazarilloMap(...) { // Now safe to add routes lzMap?.addRoute(route) { } } -
Check the route has valid geometry:
println("Steps: ${route.getSteps().size}") println("Legs: ${route.legs.size}") -
Verify route is on the current floor: Multi-floor routes render differently per floor. Switch floors to see the relevant segments.
Beacon Detection Issues
Problem: Indoor positioning does not work or is inaccurate.
Solutions:
-
Ensure Bluetooth is enabled on the device.
-
Verify Bluetooth permissions are granted at runtime (especially
BLUETOOTH_SCANon API 31+). -
Check beacon configuration: The venue must have beacons configured in the Lazarillo backend.
-
Verify parent place ID: The SDK only scans for beacons relevant to the current parent place.
-
Check proximity: The user must be within beacon detection range (typically 5-10 meters).
-
Test with simulated beacons:
LzSdkManager.setBeaconsIds(listOf("beacon-1", "beacon-2"))
Performance Issues
Slow Map Performance
Problem: Map is laggy or slow to respond.
Solutions:
-
Reduce marker count: Too many markers can slow performance
// Clear unnecessary markers lzMap.clearAllPlaceMarkers() // Add only visible markers val visiblePlaces = getPlacesForCurrentFloor() visiblePlaces.forEach { place -> lzMap.addPlaceMarker(place) { /* handle result */ } } -
Optimize marker sizes: Large markers use more memory
// Use smaller marker sizes lzMap.addPlaceMarker(place, markerSize = 120) { /* callback */ } -
Limit zoom levels: Restrict zoom range
val config = LazarilloMapConfig().apply { minZoom = 15.0 maxZoom = 20.0 }
ProGuard / R8 Rules
If you use code shrinking (R8 or ProGuard), add the following rules to your proguard-rules.pro:
# Lazarillo SDK
-keep class com.lazarillo.sdk.** { *; }
-keepclassmembers class com.lazarillo.sdk.** { *; }
# MapLibre
-keep class org.maplibre.** { *; }
-keep class com.mapbox.** { *; }
# Retrofit / OkHttp
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn retrofit2.**
# Jackson
-keep class com.fasterxml.jackson.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-dontwarn com.fasterxml.jackson.databind.**
-keepclassmembers class * {
@com.fasterxml.jackson.annotation.* *;
}
# AltBeacon
-keep class org.altbeacon.** { *; }Version Compatibility
| SDK Version | Min Android | Kotlin | Notes |
|---|---|---|---|
| 4.5.x | API 23 | 1.9.24 | Gradient route animation, multi-source rendering |
| 4.4.x | API 23 | 1.9.24 | Element filtering, MapLibre 13.0.1 |
| 4.3.x | API 22 | 1.9.22 | Route preview, step navigation |
| 4.2.x | API 22 | 1.9.22 | Location tracking improvements |
| 4.0.x - 4.1.x | API 22 | 1.9.22 | Place markers, route animation |
| 3.x | API 22 | 1.9.x | Beacon positioning, flow-based location |
| 2.x | API 22 | — | Motion detection added |
Debugging Tips
Enable Detailed Logging
The SDK uses Timber for logging. Enable debug logs to see detailed information:
// In debug builds, plant a debug tree
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}You can also enable SDK-level logging at initialization:
LzSdkManager.initialize(
context = applicationContext,
apiKey = "YOUR_API_KEY",
enableLogging = true
)Or toggle logging at runtime:
LzSdkManager.setLoggingEnabled(true)Monitor Tracking Events
The SDK logs events that help diagnose issues:
| Event | Description |
|---|---|
toggleLocationComponent | Location component state changes |
toggleLocationComponent_error | Location activation errors |
addPlaceMarker | Place marker creation |
addRoute | Route rendering |
setFloorById | Floor changes |
getRoute / getRoute_error | Route calculation results |
getPlace / getPlace_cache_hit | Place data retrieval and caching |
Common Log Messages
"LocationComponent not ready": LocationComponent needs activation"Hide location"/"Show location": User marker visibility changes due to floor"Floor changed": Floor switching events"Marker created successfully": Place marker creation"Cache is still valid": Beacon/location cache does not need refresh"Need update cache": Cache refresh triggered
Testing Location Issues
For testing location-related features:
// Use simulated beacons for testing indoor positioning
positionRepository.simulateBeacons(testBeacons)
// Test different floor scenarios
lzMap.setFloorById("test_floor_id") {
// Verify location marker behavior
}Getting Help
If you cannot resolve an issue:
- Enable logging and reproduce the issue.
- Collect relevant log output.
- Note the SDK version, Android version, and device model.
- Contact the Lazarillo support team with this information.