Leku


Source link: https://github.com/SchibstedSpain/Leku

Leku

A Location Picker for Android

Location picker component for Android. It returns a latitude, longitude and an address based on the location picked in the LocationPickerActivity provided.


Features | Download | Permissions | Usage | Localization | Customization | Tracking | Extra | Who Made This | Apps using Leku | Contribute | Bugs and Feedback | License


Features

  • Search by voice
  • Search by text
  • Geo Location by GPS, network
  • Pick locations using "touch" gestures on the map
  • Customization (Theme and layout)
  • Events Tracking
  • Multi-language support (English and Spanish supported by default)
  • RTL (Right-To-Left) layout support


Prerequisites

minSdkVersion >= 15 Google Play Services = 11.4.2 Support Library = 26.1.0

Download

Include the jcenter repository in your top build.gradle:

Enabled by default on AndroidStudio projects

allprojects {

  jcenter() 
}

Include the dependency in your app build.gradle:

dependencies {

  compile 'com.schibstedspain.android:leku:3.5.0' 
}

IMPORTANT: If you want support for Google Play Services version '8.4.0', and support library version '23.1.1' use version '1.0.0'. Beware that version '1.0.0' is going not be maintained. Also, if you want to use a version below 10.0.1 for Play Services you can use the version '2.3.1'.

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.schibstedspain.leku.LocationPickerActivity"
  android:label="@string/title_activity_location_picker"
  android:theme="@style/Theme.AppCompat.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/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 startActivityForResult. 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:

Intent intent = new LocationPickerActivity.Builder()
  .withLocation(41.4036299, 2.1743558)
  .withGeolocApiKey("<PUT API KEY HERE>")
  .withSearchZone("es_ES")
  .shouldReturnOkOnBackPressed()
  .withStreetHidden()
  .withCityHidden()
  .withZipCodeHidden()
  .withSatelliteViewHidden()
  .build(getApplicationContext());
  startActivityForResult(intent, 1);

And add the response code from that activity:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {

  if (requestCode == 1) {

if(resultCode == RESULT_OK){

 double latitude = data.getDoubleExtra(LocationPickerActivity.LATITUDE, 0);

 Log.d("LATITUDE****", String.valueOf(latitude));

 double longitude = data.getDoubleExtra(LocationPickerActivity.LONGITUDE, 0);

 Log.d("LONGITUDE****", String.valueOf(longitude));

 String address = data.getStringExtra(LocationPickerActivity.LOCATION_ADDRESS);

 Log.d("ADDRESS****", String.valueOf(address));

 String postalcode = data.getStringExtra(LocationPickerActivity.ZIPCODE);

 Log.d("POSTALCODE****", String.valueOf(postalcode));

 Bundle bundle = data.getBundleExtra(LocationPickerActivity.TRANSITION_BUNDLE);

 Log.d("BUNDLE TEXT****", bundle.getString("test"));

 Address fullAddress = data.getParcelableExtra(LocationPickerActivity.ADDRESS);

 if(fullAddress != null)

  Log.d("FULL ADDRESS****", fullAddress.toString());

}

if (resultCode == RESULT_CANCELED) {

 //Write your code if there's no result

}

  
}
 
}
 

That's all folks!

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="title_activity_location_picker">Location Picker</string> <string name="load_location_error">Something went wrong. Please try again.</string> <string name="no_search_results">There are no results for your search</string> <string name="unknown_location">unknown location</string> <string name="voice_search_promp">Search by voice…</string> <string name="voice_search_extra_language">en-EN</string> <string name="toolbar_action_voice_title">Voice</string> <string name="search_hint">Search</string>

Note that you have the voice_search_extra_language that is used for the language of the voice recognition. Replace it with the allowed voice recognition locale for your language.

I encourage you to add these languages to this component, please fork this project and submit new languages with a PR. Thanks!

Transition Bundle

If you need to send and receive a param through the LocationPickerActivity you can do it. You only need to add an "Extra" param to the intent like:

Intent intent = new Intent(getApplicationContext(), LocationPickerActivity.class);
 intent.putExtra("test", "this is a test");
 startActivityForResult(intent, 1);

And parse it on onActivityResult callback:

Bundle bundle = data.getBundleExtra(LocationPickerActivity.TRANSITION_BUNDLE);
 String test = bundle.getString("test");

Customization

Theming

This library uses AppCompat, so should use Theme.AppCompat or descendant in manifest.

<item name="colorPrimary">#E91E63</item> <item name="colorPrimaryDark">#C51162</item> <item name="colorAccent">#FBC02D</item> <item name="colorControlActivated">#E91E63</item>

colorControlActivated is used to colorize Street title, if not set, it uses colorAccent by default

Layout

It's possible to hide or show some of the information shown after selecting a location. Using tha bundle parameter LocationPickerActivity.LAYOUTS_TO_HIDE you can change the visibility of the street, city or the zipcode.

intent.putExtra(LocationPickerActivity.LAYOUTS_TO_HIDE, "street|city|zipcode");
Search Zone

By default the search will be restricted to a zone determined by your default locale. If you want to force the search zone you can do it by adding this line with the locale preferred:

intent.putExtra(LocationPickerActivity.SEARCH_ZONE, "es_ES");
Force return location on back pressed

If you want to force that when the user clicks on back button it returns the location you can use this parameter (note: is only enabled if you don't provide a location):

intent.putExtra(LocationPickerActivity.BACK_PRESSED_RETURN_OK, true);
Enable/Disable the Satellite view

If you want to disable the satellite view button you can use this parameter (note: the satellite view is enabled by default):

intent.putExtra(LocationPickerActivity.ENABLE_SATELLITE_VIEW, false);
Enable/Disable requesting location permissions

If you want to disable asking for location permissions (and prevent any location requests)

intent.putExtra(LocationPickerActivity.ENABLE_LOCATION_PERMISSION_REQUEST, false);

Tracking

Optionally, you can set a tracking events listener. Implement LocationPickerTracker interface, and set it in your Application class as follows:

LocationPicker.setTracker(new <<YourOwnTracker implementing LocationPickerTracker>>());

Available tracking events are:

TAG Message
didLoadLocationPicker Location Picker
didSearchLocations Click on search for locations
didLocalizeMe Click on localize me
didLocalizeByPoi Long click on map
RESULT_OK Return location
CANCEL Return without location

Geocoding API Fallback

In few cases, the geocoding service from Android fails due to an issue with the NetworkLocator. The only way of fixing this is rebooting the device.

In order to cover these cases, you can instruct Leku to use the Geocoding API. To enable it, just use the method '''withGeolocApiKey''' when invoking the LocationPicker.

You should provide your Server Key as parameter. Keep in mind that the free tier only allows 2,500 requests per day. You can track how many times is it used in the Developer Console from Google.

Extra

If you would like to use the Geocoder presenter (MVP) used for this use case you are free to use it! GeocoderPresenter has three methods:

  • getLastKnownLocation: Which obviously returns the last known user location as a Location object.

  • getFromLocationName(String query): Returns a List <Address > for the text introduced.

  • getFromLocationName(String query, LatLng lowerLeft, LatLng upperRight): Returns a List <Address > for the text and the Rectangle introduced.

  • getDebouncedFromLocationName(String query, int debounceTime): Returns a List <Address > for the text introduced. Useful if you want to implement your own search view with auto-complete.

  • getDebouncedFromLocationName(String query, LatLng lowerLeft, LatLng upperRight, int debounceTime): Returns a List <Address > for the text and the Rectangle introduced. Useful if you want to implement your own search view with auto-complete.

  • getInfoFromLocation(double latitude, double longitude): Returns a List <Address > based on a latitude and a longitude.

To use it first you need to implement the GeocoderViewInterface interface in your class like:

public class LocationPickerActivity extends AppCompatActivity implements GeocoderViewInterface {

Then you need to setup the presenter:

private GeocoderPresenter geocoderPresenter;  @Override protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

***
Geocoder geocoder = new Geocoder(this, Locale.getDefault());

  geocoderPresenter = new GeocoderPresenter(getApplicationContext(), new GeocoderInteractor(geocoder));

  geocoderPresenter.setUI(this);

*** 
}

And besides filling the interface methods you have to add some things to your activity/fragment lifecycle to ensure that there are no leaks.

@Override protected void onStart() {

  super.onStart();

  geocoderPresenter.setUI(this);
 
}
  @Override protected void onStop() {

  geocoderPresenter.stop();

  super.onStop();
 
}
Tests

Note: If you need to execute the Espresso test you will need to add the Google Maps Key into the Tests AndroidManifest.xml

Now you have all you need. :)

Important

Searching using the "SearchView" (geocoder) will be restricted to a zone if you are with a Locale from: US, UK, France, Italy and Spain. If not, the search will return results from all the world.

Sample usage

We provide a sample project which provides runnable code samples that demonstrate their use in Android applications. Note that you need to include your Google Play services key in the sample to be able to test it.

Who made this

Ferran Pons

Contributors

Diego Millán Gerard Pedreny Marc Serra Sergio Castillo Bernat Borras Cristian García

Apps using Leku

The following is a list of some of the public apps using Leku and are published on the Google Play Store.

Want to add your app? Found an app that no longer works or no longer uses Leku? Please submit a pull request on GitHub to update this page!

vibbo Worksi Domoticz

Contribute

  1. Create an issue to discuss about your idea
  2. [Fork it] ( https://github.com/SchibstedSpain/leku/fork)
  3. Create your feature branch ( git checkout -b my-new-feature)
  4. Commit your changes ( git commit -am 'Add some feature')
  5. Push to the branch ( git push origin my-new-feature)
  6. Create a new Pull Request
  7. Profit!

Bugs and Feedback

For bugs, questions and discussions please use the Github Issues.

License

Copyright 2016 Schibsted Classified Media Spain S.L.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0 

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Resources

A simple android library that lets you easily get an authentication token for the Google Apis.

Secure Preference Manager is a simple library which helps you to protect your Shared Preferences.

Jackdaw is a Java Annotation Processor which allows to simplify Java/Android development and prevents writing of tedious code.

Jackdaw was inspired by Lombok project, but in comparison with Lombok:

  • it does not need to have an extra plugin in IDE
  • it does not modify the existing source code

Google Photos style multi-selection for RecyclerViews.

An utility library for Android to run jobs delayed in the background. Depending on the Android version either the JobScheduler, GcmNetworkManager or AlarmManager is getting used.

Abstract adapter for convenient work with RecyclerView. It has several headers and footers.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes