Skip to Content
Installation

Installation and Usage

This guide walks you through getting a working map with navigation in your Android app.

Requirements

RequirementMinimum Version
Android minimum SDKAPI 23 (Android 6.0)
Target / Compile SDKAPI 35
Kotlin1.9.22+
Gradle8.x
JDK17

The SDK also requires devices with Bluetooth LE support for indoor positioning features.

Step 1: Obtain an API Key

The SDK requires an API key for authentication and billing. Contact the Lazarillo team at https://lazarillo.app  to obtain your key.

Important: Keep your API key secure. Store it in local.properties or an environment variable. Do not commit it to version control.

Step 2: Install the SDK

Add the JitPack Repository

Kotlin DSL — in your project-level settings.gradle.kts:

dependencyResolutionManagement { repositories { google() mavenCentral() maven { url = uri("https://jitpack.io") } } }

Groovy DSL — in your project-level build.gradle:

allprojects { repositories { google() mavenCentral() maven { url 'https://jitpack.io' } } }

See the JitPack documentation  for more details.

Add the SDK Dependency

Kotlin DSL — in your module-level build.gradle.kts:

dependencies { implementation("com.github.lazarilloapp:sdkandroidlibrary:<VERSION>") }

Groovy DSL — in your module-level build.gradle:

dependencies { implementation 'com.github.lazarilloapp:sdkandroidlibrary:<VERSION>' }

Replace <VERSION> with the desired release tag (e.g., 4.3.11). Check JitPack  for the latest available version.

Sync Gradle

After adding the dependency, sync your project with Gradle files in Android Studio (File > Sync Project with Gradle Files).

Step 3: Configure Permissions

Add the following permissions to your AndroidManifest.xml:

<!-- Required: Network access for map tiles and API calls --> <uses-permission android:name="android.permission.INTERNET" /> <!-- Required: Location access for GPS positioning --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Required: Bluetooth for indoor beacon positioning --> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- Optional: Legacy Bluetooth for devices below API 31 --> <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <!-- Required: Motion detection for location accuracy --> <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />

You must also request location and Bluetooth permissions at runtime. See the Permissions page for the full runtime permissions guide.

Step 4: Initialize the SDK

Initialize the SDK early in your app lifecycle, typically in your Application class or main Activity:

import com.lazarillo.sdk.plugin.LzSdkManager class MyApplication : Application() { override fun onCreate() { super.onCreate() LzSdkManager.initialize( context = applicationContext, apiKey = "YOUR_API_KEY", targetParentPlaceId = "YOUR_PLACE_ID", // Optional: pre-loads venue data enableLogging = BuildConfig.DEBUG // Logs in debug builds only ) } }

Parameters:

  • context — Application context (required).
  • apiKey — Your Lazarillo API key (required).
  • targetParentPlaceId — The venue or place ID you want to display. When provided, the SDK pre-loads sub-places and beacon data in the background for faster first render.
  • enableLogging — Set to true during development for debug logs. Disable in production.

Step 5: Display a Map

1. Add a container to your layout

<!-- res/layout/fragment_main.xml --> <FrameLayout android:id="@+id/map_container" android:layout_width="match_parent" android:layout_height="match_parent" />

2. Create and configure the map

import com.lazarillo.sdk.plugin.map.LazarilloMap import com.lazarillo.sdk.plugin.map.LazarilloMapConfig import com.lazarillo.sdk.maplibre.LatLng class MainFragment : Fragment() { private var lzMap: LazarilloMap? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { val binding = FragmentMainBinding.inflate(inflater, container, false) // Configure the map val mapConfig = LazarilloMapConfig().apply { parentPlaceId = "YOUR_PLACE_ID" zoom = 17 minZoom = 15.0 maxZoom = 20.0 hideZoomIn = false hideZoomOut = false hideZoomToLocation = false hideFloorSelector = false } // Create the map lzMap = LazarilloMap( id = "main-map", config = mapConfig, passedContext = requireContext(), inflater = layoutInflater, lifecycleScope = viewLifecycleOwner.lifecycleScope, positionRepository = null ) { // Map is ready -- perform post-initialization here } // Add map to the view hierarchy binding.mapContainer.addView(lzMap) return binding.root } }

At this point you should see an interactive map centered on your venue.

Step 6: Add Navigation

Once the map is displayed, you can calculate and display a route:

import com.lazarillo.sdk.plugin.repository.model.LzLocation import com.lazarillo.sdk.plugin.repository.model.IdPlaceLocation import com.lazarillo.sdk.plugin.map.routepaint.PlainRouteLine // Calculate a route (call from a coroutine scope) lifecycleScope.launch { try { // Define start and destination val startLocation = LzLocation( building = null, floor = null, latitude = -33.4489, longitude = -70.6693 ) val destination = IdPlaceLocation( id = "destination-place-id", level = 1 ) // Request a route val response = LzSdkManager.getRoute( initialLocation = startLocation, finalLocation = destination, preferAccessibleRoute = false, language = "en" ) if (response.isSuccessful) { val routes = response.body() routes?.firstOrNull()?.let { route -> // Store the route in the SDK LzSdkManager.setCurrentShowingRoute(route) // Display the route on the map lzMap?.addRoute( route = route, nextStepsLineStyle = PlainRouteLine( colorHex = "#7000FF", lineWith = 4f ), prevStepsLineStyle = PlainRouteLine( colorHex = "#D2E0EB", lineWith = 4f ) ) { // Route is now visible on the map } } } else { // Handle failed route request } } catch (e: Exception) { // Handle errors } }

Next Steps

Last updated on