All Projects → rtchagas → Pingplacepicker

rtchagas / Pingplacepicker

Licence: apache-2.0
An almost plug and play replacement for Google's Place Picker

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to Pingplacepicker

Retaineddatetimepickers
Android Library to help you with your date & time pickers while retaining the instance of the pickers on orientation change.
Stars: ✭ 107 (-13.71%)
Mutual labels:  picker
React Native Form Builder
Handle your forms in a smart way
Stars: ✭ 113 (-8.87%)
Mutual labels:  picker
Calendar
📆 calendar 日历
Stars: ✭ 119 (-4.03%)
Mutual labels:  picker
Storymap
A JavaScript library for digital storytelling with web maps.
Stars: ✭ 107 (-13.71%)
Mutual labels:  maps
Bingmapsv8codesamples
This is a collection of over two hundred code samples an growing for the Bing Maps V8 web control.
Stars: ✭ 111 (-10.48%)
Mutual labels:  maps
Horizontalpicker
DatePicker horizontal con selección smooth por día para Android.
Stars: ✭ 116 (-6.45%)
Mutual labels:  picker
Vue Picker
The picker component based on vue.js
Stars: ✭ 105 (-15.32%)
Mutual labels:  picker
Belvedere
An image picker library for Android
Stars: ✭ 122 (-1.61%)
Mutual labels:  picker
Gradientpathrenderer
Renders MKPolyline with a fancy multicoloured gradient fill
Stars: ✭ 112 (-9.68%)
Mutual labels:  maps
Distancepicker
Custom UIKit control to select a distance with a pan gesture, written in Swift
Stars: ✭ 118 (-4.84%)
Mutual labels:  picker
Contentmanager
Android library for getting photo or video from a device gallery, cloud or camera. Working with samsung devices. Made by Stfalcon
Stars: ✭ 108 (-12.9%)
Mutual labels:  picker
Kotlin Playground
Kotlin practice
Stars: ✭ 111 (-10.48%)
Mutual labels:  picker
Mobile Sdk
CARTO Mobile SDK core project
Stars: ✭ 116 (-6.45%)
Mutual labels:  maps
Jhform
JhForm - 自定义表单工具,更加简单,快捷的创建表单、设置页面
Stars: ✭ 108 (-12.9%)
Mutual labels:  picker
Eon Map
Realtime maps with PubNub and MapBox.
Stars: ✭ 121 (-2.42%)
Mutual labels:  maps
Osmscout Server
Maps server providing tiles, geocoder, and router
Stars: ✭ 105 (-15.32%)
Mutual labels:  maps
Anypicker
jQuery Picker Library for Android, iOS & Windows Phone. eg Date Picker, Time Picker, DateTime Picker, Custom Select etc
Stars: ✭ 114 (-8.06%)
Mutual labels:  picker
Awesome Maps
There is more than google: A collection of great online maps 🌍🗺🌎
Stars: ✭ 124 (+0%)
Mutual labels:  maps
Planetutils
Scripts and a Docker container to maintain your own OpenStreetMap planet, terrain tiles, & Valhalla Tilepacks
Stars: ✭ 121 (-2.42%)
Mutual labels:  maps
Datepicker
仿滴滴出行预约打车IOS风格3D时间选择器 🌲
Stars: ✭ 118 (-4.84%)
Mutual labels:  picker

PING - Because Ping Is Not Google's Place Picker 😉

If you're here looking for a place picker you have probably read this:

Google Place Picker was deprecated

As of the end of January 2019, Google deprecated the so useful Place Picker bundled in the Places SDK for Android. The main reason was due the new pricing model of the Places API.

PING Place Picker is here to help you to (almost) plug-and-play replace the original Google's Place Picker.

Map expanded Place selected Results expanded Search result

A key difference

Different than Google's Place Picker, PING by default doesn't search for places according to where the user is pointing the map to. Instead, it shows only the nearby places in the current location.

This was intentional and the reason is simple. By using the /nearbysearch from Google Places Web API we are going to be charged a lot for each map movement.

NearbySearch warning

According to Nearby Search pricing each request to the API is going to cost 0.04 USD per each (40.00 USD per 1000).

To avoid the extra cost of /nearbysearch, PING relies on Place API's findCurrentPlace() that is going to cost 0.030 USD per each (30.00 USD per 1000).

Moreover, we don't fire a new request when the user moves the map.

Enabling nearby searches

If you do want to fetch places from a custom location or refresh them when the user moves the map, you must enable /nearbysearch queries in PING.

To do that, enable this flag in your project:

 <bool name="enable_nearby_search">true</bool>

By doing so, PING behaviour will be slightly changed:

  • All places will be fetched by /nearbysearch queries.
  • You get a button to refresh the places for the current location.
  • You can set the initial map position to get the places from via pingBuilder.setLatLng(LatLng)

Why use PING?

PING is based entirely on Google Places and MAPs APIs. Google has the biggest places database available to us developers with most up to date and curated places information.

It is worth to notice that Google provides US$ 200 (free) per month to be used with Places API. This should be more than enough for small applications that rely on Places data.

Download

Add Jitpack in your root build.gradle at the end of repositories:

    allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

Step 2. Add the dependency

    dependencies {
            // Places library
            implementation 'com.google.android.libraries.places:places:2.0.0'
            // PING Place Picker
            implementation 'com.github.rtchagas:pingplacepicker:2.0.+'
    }

Setup

  1. Add Google Play Services to your project - How to
  2. Sign up for API keys - How to
  3. Add the Android API key to your AndroidManifest file as in the sample project.
  4. Optional but strongly recommended to enable R8 in you gradle.properties file

Hands on

Check the sample project for a full working example.

- Kotlin

    private fun showPlacePicker() {  
        val builder = PingPlacePicker.IntentBuilder()
	builder.setAndroidApiKey("YOUR_ANDROID_API_KEY")  
        	.setMapsApiKey("YOUR_MAPS_API_KEY")
	
	// If you want to set a initial location rather then the current device location.
	// NOTE: enable_nearby_search MUST be true.
        // builder.setLatLng(LatLng(37.4219999, -122.0862462))
	
        try {
            val placeIntent = pingBuilder.build(this)
            startActivityForResult(placeIntent, REQUEST_PLACE_PICKER)
        }
        catch (ex: Exception) {  
            toast("Google Play Services is not Available")  
        }
    }
    
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {  
	super.onActivityResult(requestCode, resultCode, data)  
	if ((requestCode == REQUEST_PLACE_PICKER) && (resultCode == Activity.RESULT_OK)) {  
	    val place: Place? = PingPlacePicker.getPlace(data!!)  
	    toast("You selected: ${place?.name}")  
	}  
    }

- Java

    private void showPlacePicker() {
	PingPlacePicker.IntentBuilder builder = new PingPlacePicker.IntentBuilder();
	builder.setAndroidApiKey("YOUR_ANDROID_API_KEY")
	       .setMapsApiKey("YOUR_MAPS_API_KEY");
	
	// If you want to set a initial location rather then the current device location.
	// NOTE: enable_nearby_search MUST be true.
        // builder.setLatLng(new LatLng(37.4219999, -122.0862462))
	
	try {
	    Intent placeIntent = builder.build(getActivity());  
	    startActivityForResult(placeIntent, REQUEST_PLACE_PICKER);  
	}  
	catch (Exception ex) {  
	    // Google Play services is not available... 
	}
    }
    
    @Override  
    public void onActivityResult(int requestCode, int resultCode, Intent data) {  
        if ((requestCode == REQUEST_PLACE_PICKER) && (resultCode == RESULT_OK)) {  
            Place place = PingPlacePicker.getPlace(data);  
	    if (place != null) {  
                Toast.makeText(this, "You selected the place: " + place.getName(), Toast.LENGTH_SHORT).show();
            }  
        }
    }

API Keys

PING needs two API keys in order to work.

It was decided to split the API keys to clearly distinguish what you're going to be charged for. Also, the Places Web API and the Geocoding API don't allow an Android API key to be used. To not expose an unrestricted key for all APIs, the Maps API key is now required.

Key Restriction Purpose
Android key Android Applications Used as the Places API key. Main purpose is to retrieve the current places and place details.
Maps key APIs: Geocoding, Maps Static and Places API only Used to fetch static maps, nearby places through Places Web API and perform reverse geocoding on the current user position. That is, discover the address that the user is current pointing to. Your key should look like this.

TIP: It is strongly recommended to not expose your Maps API key in your resource files. Anyone could decompile your apk and have access to that key. To avoid this, the key should be at least obfuscated. A nice approach is to save the key in the cloud through "Firebase remote config" and fetch it at runtime.

Configuration

As some features are charged by Google, you can alter the default PING Place Picker behaviour by overriding below resources:

<!-- 0.002 USD per each (2.00 USD per 1000) -->  
<bool name="show_confirmation_photo">true</bool>  

<!-- 0.007 USD per each (7.00 USD per 1000) -->  
<bool name="show_confirmation_map">true</bool>

<!-- If true, the map will automatically center (pan) to
     the selected marker -->
<bool name="auto_center_on_marker_click">false</bool>

Theming

PING is fully customizable and you just need to override some colors to make it seamlessly connected to your app.

Since release 2.0.0 PING supports dark/night mode by default.
Please make sure your app provide the correct resources to switch to night mode.

You can always refer to Material Design documentation to know more about dark theme and how to implement it.

To customize PING you need to override these colors:

For day/light theme:

  • res/values/colors.xml
    <!-- Toolbar color, places icons, text on top of primary surfaces -->
    <color name="colorPrimary">@color/material_teal500</color>
    <color name="colorPrimaryDark">@color/material_teal800</color>
    <color name="colorOnPrimary">@color/material_white</color>

    <!-- Accent color in buttons and actions -->
    <color name="colorSecondary">@color/material_deeporange500</color>
    <color name="colorSecondaryDark">@color/material_deeporange800</color>
    <color name="colorOnSecondary">@color/material_white</color>

    <!-- Main activity background -->
    <color name="colorBackground">@color/material_grey200</color>
    <color name="colorOnBackground">@color/material_black</color>

    <!-- Cards and elevated views background -->
    <color name="colorSurface">@color/material_white</color>
    <color name="colorOnSurface">@color/material_black</color>

    <!-- Text colors -->
    <color name="textColorPrimary">@color/material_on_surface_emphasis_high_type</color>
    <color name="textColorSecondary">@color/material_on_surface_emphasis_medium</color>

    <color name="colorMarker">@color/material_deeporange400</color>
    <color name="colorMarkerInnerIcon">@color/material_white</color>

For night/dark theme:

  • res/values-night/colors.xml
    <color name="colorPrimary">@color/material_teal300</color>
    <!-- Let the primary dark color as the surface color to not colorfy the status bar -->
    <color name="colorPrimaryDark">@color/colorSurface</color>
    <color name="colorOnPrimary">@color/material_black</color>

    <color name="colorSecondary">@color/material_deeporange200</color>
    <color name="colorSecondaryDark">@color/material_deeporange300</color>
    <color name="colorOnSecondary">@color/material_black</color>

    <color name="colorBackground">@color/colorSurface</color>
    <color name="colorOnBackground">@color/colorOnSurface</color>

    <color name="colorSurface">#202125</color>
    <color name="colorOnSurface">@color/material_white</color>

    <color name="textColorPrimary">@color/material_on_surface_emphasis_high_type</color>
    <color name="textColorSecondary">@color/material_on_surface_emphasis_medium</color>

    <color name="colorMarker">@color/material_deeporange200</color>
    <color name="colorMarkerInnerIcon">@color/colorSurface</color>

In case of doubt in how to implement the new styles, please take a look at the sample app.

Contribute

Let's together make PING awesome!

Please feel free to contribute with improvements.

License

Copyright 2020 Rafael Chagas

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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].