SkillAgentSearch skills...

Leku

:earth_africa: Map location picker component for Android. Based on Google Maps. An alternative to Google Place Picker.

Install / Use

/learn @AdevintaSpain/Leku

README

<!-- Title: Leku - Map location picker for Android Description: Google Maps based library for Android that returns a latitude, longitude and an address based on the location picked with the Activity provided. Author: AdevintaSpain --> <img src="docs/images/leku_logo.png" align="left" height="128px" /> <img align="left" width="0" height="128px" hspace="10" /> <div style="display:block; height: 168px;"> * <i>The location Picker for Android</i> *

Component library for Android that uses Google Maps and returns a latitude, longitude and an address based on the location picked with the Activity provided.

</div> <br/> <p align="center"> <b><a href="#features">Features</a></b> | <b><a href="#download">Download</a></b> | <b><a href="#permissions">Permissions</a></b> | <b><a href="#usage">Usage</a></b> | <b><a href="#localization">Localization</a></b> | <b><a href="#customization">Customization</a></b> | <b><a href="#tracking">Tracking</a></b> | <b><a href="#extra">Extra</a></b> | <b><a href="#who-made-this">Who Made This</a></b> | <b><a href="#apps-using-leku">Apps using Leku</a></b> | <b><a href="#contribute">Contribute</a></b> | <b><a href="#bugs-and-feedback">Bugs and Feedback</a></b> | <b><a href="#license">License</a></b> </p> <br/>

Features

<img align="right" width="0" height="368px" hspace="20"/> <img src="docs/images/new_design_screenshot.png" height="368px" align="right" />
  • Search by voice
  • Search by text
  • Geo Location by GPS, network
  • Google Places (optional)
  • Google Time Zone API (optional)
  • Pick locations using "touch" gestures on the map
  • Customization (Theme and layout)
  • Events Tracking
  • Multi-language support (English, Spanish and Vietnamese supported by default)
  • RTL (Right-To-Left) layout support <br><br><br>

Prerequisites

minSdkVersion >= 23<br/> Google Play Services = 19.0.0<br/> AndroidX

Download

Include the mavenCentral repository in your top build.gradle:

Enabled by default on AndroidStudio projects

allprojects {
    mavenCentral()
}

Include the dependency in your app build.gradle:

dependencies {
    implementation 'com.adevinta.android:leku:13.0.0'
}

Alternatively, if you are using a different version of Google Play Services and AndroidX use this instead:

implementation ('com.adevinta.android:leku:13.0.0') {
    exclude group: 'com.google.android.gms'
    exclude group: 'androidx.appcompat'
}
Troubleshoot

If you find this issue:

Execution failed for task ':app:transformClassesWithMultidexlistForDebug'. com.android.build.api.transform.TransformException: Error while generating the main dex list: Error while merging dex archives: Program type already present: com.google.common.util.concurrent.ListenableFuture Learn how to resolve the issue at https://developer.android.com/studio/build/dependencies#duplicate_classes.

The workaround for this is:

// Add this to your app build.gradle.kts file
configurations.all {
	// this is a workaround for the issue:
	// https://stackoverflow.com/questions/52521302/how-to-solve-program-type-already-present-com-google-common-util-concurrent-lis
	exclude group: 'com.google.guava', module: 'listenablefuture'
}

Permissions

You must add the following permissions in order to use the Google Maps Android API:

  • android.permission.INTERNET Used by the API to download map tiles from Google Maps servers.

  • android.permission.ACCESS_NETWORK_STATE Allows the API to check the connection status in order to determine whether data can be downloaded.

The following permissions are not required to use Google Maps Android API v2, but are recommended.

  • android.permission.ACCESS_COARSE_LOCATION Allows the API to use WiFi or mobile cell data (or both) to determine the device's location. The API returns the location with an accuracy approximately equivalent to a city block.

  • android.permission.ACCESS_FINE_LOCATION Allows the API to determine as precise a location as possible from the available location providers, including the Global Positioning System (GPS) as well as WiFi and mobile cell data.

  • android.permission.WRITE_EXTERNAL_STORAGE Allows the API to cache map tile data in the device's external storage area.

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

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

You must also explicitly declare that your app uses the android.hardware.location.network or android.hardware.location.gps hardware features if your app targets Android 5.0 (API level 21) or higher and uses the ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission in order to receive location updates from the network or a GPS, respectively.

Note: It supports runtime permissions for Android 6 (Marshmallow). You don't need to do anything, it will ask for permissions if needed.

Usage

To use the LocationPickerActivity first you need to add these lines to your AndroidManifest file:

<activity
    android:name="com.adevinta.leku.LocationPickerActivity"
    android:label="@string/leku_title_activity_location_picker"
    android:theme="@style/Theme.MaterialComponents.Light.NoActionBar"
    android:windowSoftInputMode="adjustPan"
    android:parentActivityName=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data android:name="android.app.searchable"
        android:resource="@xml/leku_searchable" />
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity" />
</activity>

Then you have setup the call to start this activity wherever you like, always as a ActivityResultLauncher. You can set a default location, search zone and other customizable parameters to load when you start the activity. You only need to use the Builder setters like:

val lekuActivityResultLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
            if (result.resultCode == Activity.RESULT_OK) {
                Log.d("RESULT****", "OK")
                val latitude = data?.getDoubleExtra(LATITUDE, 0.0)
                Log.d("LATITUDE****", latitude.toString())
                val longitude = data?.getDoubleExtra(LONGITUDE, 0.0)
                Log.d("LONGITUDE****", longitude.toString())
                val address = data?.getStringExtra(LOCATION_ADDRESS)
                Log.d("ADDRESS****", address.toString())
                val postalcode = data?.getStringExtra(ZIPCODE)
                Log.d("POSTALCODE****", postalcode.toString())
                val bundle = data?.getBundleExtra(TRANSITION_BUNDLE)
                Log.d("BUNDLE TEXT****", bundle?.getString("test").toString())
                val fullAddress = data?.getParcelableExtra<Address>(ADDRESS)
                if (fullAddress != null) {
                    Log.d("FULL ADDRESS****", fullAddress.toString())
                }
                val timeZoneId = data?.getStringExtra(TIME_ZONE_ID)
                if (timeZoneId != null) {
                    Log.d("TIME ZONE ID****", timeZoneId)
                }
                val timeZoneDisplayName = data?.getStringExtra(TIME_ZONE_DISPLAY_NAME)
                if (timeZoneDisplayName != null) {
                    Log.d("TIME ZONE NAME****", timeZoneDisplayName)
                }
            } else {
                Log.d("RESULT****", "CANCELLED")
            }
        }

val activity = context as MainActivity
val locationPickerIntent = LocationPickerActivity.Builder(applicationContext)
    .withLocation(41.4036299, 2.1743558)
    .withGeolocApiKey("<PUT API KEY HERE>")
    .withGooglePlacesApiKey("<PUT API KEY HERE>")
    .withSearchZone("es_ES")
    .withSearchZone(SearchZoneRect(LatLng(26.525467, -18.910366), LatLng(43.906271, 5.394197)))
    .withDefaultLocaleSearchZone()
    .shouldReturnOkOnBackPressed()
    .withStreetHidden()
    .withCityHidden()
    .withZipCodeHidden()
    .withSatelliteViewHidden()
    .withGooglePlacesEnabled()
    .withGoogleTimeZoneEnabled()
    .withVoiceSearchHidden()
    .withUnnamedRoadHidden()
    .withSolidBottomColor()
    .withSearchBarHidden()
    .build()

activity.lekuActivityResultLauncher.launch(locationPickerIntent)

That's all folks!

Google Places

Leku now supports Google Places queries using the search box. If you want to enable it these are the steps you need to follow:

  1. Enable Google Places API for Android on your google developer console.

  2. Add the key to the location picker builder

val locationPickerIntent = LocationPickerActivity.Builder(context)
      .withGooglePlacesApiKey("<PUT API KEY HERE>")

If you set up the same credential for both APIs (Geo - Places) you don't need this step

And you are good to go. :)

Localization

If you would like to add more language translations the only thing you have to do is:

  1. Crate a new strings resource folder and file for your language like "/values-ru".
  2. Add all text translations for those strings:
<string name="leku_title_activity_location_picker">Location Picker</string>
<string name="leku_load_location_error">Something went wrong. Please try again.</string>
<string name="leku_no_search_results">There are no results for your search</string>
<string name="leku_unknown_location">unknown location</string>
<string name="leku_voice_search_promp">Search by voice…</
View on GitHub
GitHub Stars777
CategoryDevelopment
Updated13d ago
Forks170

Languages

Kotlin

Security Score

100/100

Audited on Mar 18, 2026

No findings