In maart 2015 heeft Google de Places API voor Android vrijgegeven als onderdeel van de Play-services van Google. Met deze API kunnen ontwikkelaars toegang krijgen tot een schat aan informatie van Google om gebruikers een ervaring te bieden die is afgestemd op hun huidige locatie door de namen en informatie van plaatsen te gebruiken in plaats van een set coördinaten.
In deze zelfstudie leert u hoe u uw gebruikers presenteert met de component Place Picker, de Places API gebruikt om de huidige locatie van de gebruiker te raden, naar een plaats op basis van de ID te zoeken en de gebruiker de mogelijkheid te geven een tekstveld in te voeren om deze weer te geven met voorspellende resultaten.
Als u nog geen openbare API-sleutel voor Android heeft, moet u een openbare Google API-sleutel maken voor Android-apps. U kunt dit doen door naar de Developers Console van Google te gaan. Instructies voor het maken van een sleutel op basis van uw handtekeningcertificaat en pakketnaam zijn beschikbaar in de documentatie van Google en vallen buiten het bestek van dit artikel.
Wanneer u een sleutel hebt gemaakt, zoekt u naar de Places-API en stelt u deze in op ingeschakeld. Sommige oproepen naar de Places-API zijn beperkt in het aantal verzoeken dat per periode van 24 uur kan worden verzonden. Op het moment van schrijven kan een account zonder een factureringsprofiel maximaal 1000 aanvragen verzenden, terwijl een account met een factureringsprofiel 150.000 verzoeken kan verzenden. Als u meer nodig hebt, kunt u een verzoek indienen om deze limiet te laten verhogen, zoals beschreven in de documentatie over gebruikslimieten.
Met de API-sleutel klaar voor gebruik, is het tijd om aan het demoproject te gaan werken. Maak een project in Android Studio en stel de minimaal ondersteunde SDK-versie in op minimaal 9. Dit is de minimale vereiste voor het gebruik van de Play-services van Google.
Nadat Android Studio het Hallo Wereld sjabloonproject, open de build.gradle bestand en, onder de afhankelijkheden
knooppunt, voeg de vereiste afhankelijkheid van Play Services 7.0 toe. Dit is het laatste op het moment van schrijven, maar u kunt de nieuwste versie verifiëren door de documentatie van Google te controleren.
afhankelijkheden compile fileTree (dir: 'libs', include: ['* .jar']) compileer 'com.android.support:appcompat-v7:22.0.0' compileer 'com.google.android.gms: afspeelservices : 7.0.0 '
Open vervolgens AndroidManifest.xml, voeg de vereiste rechten voor het project toe en stel in dat OpenGL versie 2 vereist is door de toepassing.
Het laatste dat je in het manifest moet doen, is er twee toevoegen
tags om de gms-versie en API-sleutel voor de app binnen de
label.
Wanneer je klaar bent met het manifest, ben je klaar om te beginnen met het schrijven van code. Omdat dit onderdeel is van Play Services, moet u uw initialiseren GoogleApiClient
en verbind / ontkoppel het tijdens uw Activiteit
de levenscyclus. We doen dit in de onCreate
, onStart
, en onStop
methoden van de Activiteit
klasse.
@Override protected void onCreate (Bundle savedInstanceState) // - Snippet mGoogleApiClient = new GoogleApiClient .Builder (this) .enableAutoManage (this, 0, this) .addApi (Places.GEO_DATA_API) .addApi (Places.PLACE_DETECTION_API) .addConnectionCallbacks ( this) .addOnConnectionFailedListener (this) .build (); @Override protected void onStart () super.onStart (); if (mGoogleApiClient! = null) mGoogleApiClient.connect (); @Override protected void onStop () if (mGoogleApiClient! = Null &&GoogleApiClient.isConnected ()) mGoogleApiClient.disconnect (); super.onStop ();
De widget Plaats kiestool is een gebruikersinterfacecomponent geleverd door Play Services waarmee de gebruiker een kaart van hun omgeving kan zien. Het onderdeel bevat een lijst met plaatsen in de buurt die door uw app kunnen worden gebruikt. Door dit onderdeel te gebruiken, kunt u een standaardontwerp volgen dat uw gebruikers zullen weten te gebruiken, terwijl ze kunnen besparen op ontwikkelingstijd.
Als u de plaatskiezer wilt gebruiken, moet u een intentie maken en luisteren naar de Activiteit
resultaat om de door de gebruiker geselecteerde plaats op te halen. De volgende methode laat zien hoe u dit zou lanceren Activiteit
.
private void displayPlacePicker () if (mGoogleApiClient == null ||! mGoogleApiClient.isConnected ()) geretourneerd; PlacePicker.IntentBuilder builder = nieuwe PlacePicker.IntentBuilder (); probeer startActivityForResult (builder.build (getApplicationContext ()), PLACE_PICKER_REQUEST); catch (GooglePlayServicesRepairableException e) Log.d ("PlacesAPI Demo", "GooglePlayServicesRepairableException thrown"); catch (GooglePlayServicesNotAvailableException e) Log.d ("PlacesAPI Demo", "GooglePlayServicesNotAvailableException thrown");
De PlacePicker.IntentBuilder
wordt gebruikt om de voornemen
die wordt gebruikt om de plaatskiezer te lanceren. Het heeft ook een methode beschikbaar, setLatLngBounds
, waarmee je een geografische grens kunt plaatsen van een zuidwestelijke hoek tot een noordoostelijke hoek om het zoekgebied te besturen.
De voornemen
kan worden gebouwd met behulp van de bouwen
methode van PlacePicker.IntentBuilder
en gelanceerd met behulp van de startActivityForResult
methode van uw Activiteit
. Opgemerkt moet worden dat het gebruik van de bouwen
methode heeft de mogelijkheid om een GooglePlayServicesRepairableException
of a GooglePlayServicesNotAvailableException
uitzondering, dus die moeten worden gecontroleerd op het gebruik van een standaard try / catch-blok en elegant worden behandeld als ze zich voordoen.
Als de gebruiker een locatie selecteert in de lijst met plaatskiezers, is dat het geval Plaats
object is verpakt in een voornemen
en teruggestuurd naar de roeping Activiteit
. De ... gebruiken PlacePicker.getPlace
methode, kunt u de Plaats
gegevens van de geretourneerde voornemen
.
protected void onActivityResult (int requestCode, int resultCode, Intent data) if (requestCode == PLACE_PICKER_REQUEST && resultCode == RESULT_OK) displayPlace (PlacePicker.getPlace (data, this));
Zodra de Plaats
object wordt geëxtraheerd, het kan worden behandeld als een modelobject om weer te geven of te gebruiken in uw app.
private void displayPlace (Place place) if (place == null) retour; String-inhoud = ""; if (! TextUtils.isEmpty (place.getName ())) content + = "Name:" + place.getName () + "\ n"; if (! TextUtils.isEmpty (place.getAddress ())) content + = "Address:" + place.getAddress () + "\ n"; if (! TextUtils.isEmpty (place.getPhoneNumber ())) content + = "Telefoon:" + place.getPhoneNumber (); mTextView.setText (inhoud);
Een ander interessant kenmerk van de Places-API is dat u deze kunt gebruiken om te raden of de gebruiker zich momenteel op een vermelde plaats bevindt. De API biedt ook een kans, zodat u weloverwogen beslissingen kunt nemen over hoe uw app met de gebruiker moet omgaan. Opgemerkt moet worden dat dit een van de kenmerken van de API is waarvoor een verzoek moet worden ingediend tegen uw toegewezen gebruik.
Om de plaats van de gebruiker te detecteren, moet u de Places.PlacesDetectionApi.getCurrentPlace
methode om een te maken PendingIntent
dat keert terug met een PlaceLikelihoodBuffer
voorwerp. Met behulp van een ResultCallBack
, je kunt de eerste en meest waarschijnlijke plaats uit de buffer plaatsen en gebruiken in je app.
Als uw app meer informatie nodig heeft, kunt u andere extraheren PlaceLikelihood
items uit de buffer door er doorheen te lus. De waarschijnlijkheid dat deze plaats is waar de gebruiker zich momenteel bevindt, wordt in elk ervan doorgegeven PlaceLikelihood
object als een zwevende kommawaarde uit 0.0 naar 1.0, 1.0 bijna een gegarandeerde match zijn. Vergeet niet te bellen vrijlating
op de PlaceLikelihoodBuffer
om geheugenlekken te voorkomen.
private void guessCurrentPlace () PendingResultresult = Places.PlaceDetectionApi.getCurrentPlace (mGoogleApiClient, null); result.setResultCallback (nieuwe ResultCallback () @Override openbare leegte onResult (PlaceLikelihoodBuffer likelyPlaces) PlaceLikelihood placeLikelihood = likelyPlaces.get (0); String-inhoud = ""; if (placeLikelihood! = null && plaatsLikelihood.getPlace ()! = null &&! TextUtils.isEmpty (placeLikelihood.getPlace (). getName ())) content = "Meest waarschijnlijke plaats:" + placeLikelihood.getPlace (). getName () + "\ n"; if (placeLikelihood! = null) content + = "Percentage verandering van daar te zijn:" + (int) (placeLikelihood.getLikelihood () * 100) + "%"; mTextView.setText (inhoud); likelyPlaces.release (); );
Het volgende en meest complexe onderwerp dat we in deze zelfstudie bespreken, is het voorspellen en weergeven van plaatsen voor de gebruiker bij het invoeren van een zoekopdracht. Nogmaals, deze API-oproep telt ook mee voor de gebruikslimieten van de API. Het is echter van onschatbare waarde om uw app beter bruikbaar te maken.
Voor dit gedeelte van de zelfstudie gebruikt u een AutoCompleteTextView
en een aangepaste adapter in de app om de naam van een plaats voor voorspellingen te typen. Bijna al het werk gebeurt in de adapter. We moeten echter een verwijzing doorgeven naar de GoogleApiClient
naar de adapter zodat deze toegang heeft tot de API.
Dit kan in de standaard worden gedaan GoogleApiClient
Bel terug, onConnected
, en we kunnen het exemplaar van de client verwijderen onStop
waar mAdapter
is een voorbeeld van onze gewoonte Adapter
klasse, AutoCompleteAdapter
.
@Override protected void onStop () if (mGoogleApiClient! = Null &&GoogleApiClient.isConnected ()) mAdapter.setGoogleApiClient (null); mGoogleApiClient.disconnect (); super.onStop (); @Override public void onConnected (bundelbundel) if (mAdapter! = Null) mAdapter.setGoogleApiClient (mGoogleApiClient);
Een API-aanroep activeren telkens wanneer de gebruiker een nieuwe brief intypt in de AutoCompleteTextView
, je moet de getFilter
methode van de ArrayAdapter
. Deze methode wordt geactiveerd wanneer de gebruiker de inhoud van de weergave die aan de adapter is gekoppeld, wijzigt. Hiermee kunt u de inhoud van de adapter van de AutoCompleteTextView
. In het volgende voorbeeld, beperkingen
is de inhoud van de weergave.
@Override public Filter getFilter () return new Filter () @Override protected FilterResults performFiltering (CharSequence-beperking) if (mGoogleApiClient == null ||! MGoogleApiClient.isConnected ()) Toast.makeText (getContext (), "Not connected ", Toast.LENGTH_SHORT) .show (); return null; duidelijk(); displayPredictiveResults (constraint.toString ()); return null; @Override beschermde ongeldige publicatieresultaten (CharSequence-beperking, resultaten FilterResults) notifyDataSetChanged (); ;
De displayPredictiveResults
methode is waar de daadwerkelijke interactie met de API plaatsvindt. Er zijn een paar verschillende objecten die kunnen worden gemaakt om uw voorspellingen aan te passen.
De eerste is a LatLngBounds
object dat een vierkante grens creëert van een zuidwestpunt naar een noordoostpunt om de query te lokaliseren. Als nul
wordt doorgegeven in plaats van een geïnitialiseerd LatLngBounds
object, dan worden er geen geografische beperkingen op de query geplaatst.
LatLngBounds bounds = new LatLngBounds (nieuwe LatLng (39.906374, -105.122337), nieuwe LatLng (39.949552, -105.068779));
Het tweede object dat u kunt maken om de query aan te passen, is een filter voor de API-aanvraag. Het filter voor de plaatsen
AutoCompletePredictions
oproep is een lijst van Geheel getal
objecten die verschillende soorten filters vertegenwoordigen. Op dit moment kan slechts één filtertype op een query worden toegepast. De acceptabele waarden zijn te vinden in de documentatie. Als het Geheel getal
lijst is leeg of nul
wordt doorgegeven, dan worden alle resultaattypen teruggestuurd.
Als u klaar bent om het verzoek te doen, kunt u de Places.GeoDataApi.getAutocompletePredictions
methode om een te retourneren PendingIntent
, die kan worden geassocieerd met een ResultCallback
om de geretourneerde informatie weer te geven.
Het is belangrijk om op te merken dat een aangepast object de AutoCompletePrediction
objecten uit de buffer worden gebruikt om de gegevens op te slaan in de ArrayAdapter
. Anders een IllegalArgumentsException
Uitzondering zou worden gegenereerd zodra de buffer wordt vrijgegeven, wat cruciaal is om een geheugenlek te voorkomen.
private void displayPredictiveResults (Stringquery) // Southwest corner to Northeast corner. LatLngBounds bounds = new LatLngBounds (nieuwe LatLng (39.906374, -105.122337), nieuwe LatLng (39.949552, -105.068779)); // Filter: https://developers.google.com/places/supported_types#table3 LijstfilterTypes = nieuwe ArrayList (); filterTypes.add (Place.TYPE_ESTABLISHMENT); Places.GeoDataApi.getAutocompletePredictions (mGoogleApiClient, query, bounds, AutocompleteFilter.create (filterTypes)) .setResultCallback (new ResultCallback () @Override public void onResult (AutocompletePredictionBuffer buffer) if (buffer == null) retour; if (buffer.getStatus (). isSuccess ()) for (AutocompletePrediction-voorspelling: buffer) // Toevoegen als een nieuw item om IllegalArgumentsException te voorkomen wanneer buffer wordt vrijgegeven add (nieuwe AutoCompletePlace (prediction.getPlaceId (), prediction.getDescription ( ))); // Voorkom geheugenlek door bufferbuffer vrij te geven (); , 60, TimeUnit.SECONDS);
De inhoud in AutoCompleteAdapter
wordt weergegeven met behulp van a android.R.layout.simple_list_item_1
lay-out en standaard ViewHolder-patroon in getView
.
@Override openbaar View getView (int position, View convertView, ViewGroup parent) ViewHolder holder; if (convertView == null) holder = new ViewHolder (); convertView = LayoutInflater.from (getContext ()) .inflate (android.R.layout.simple_list_item_1, parent, false); holder.text = (TextView) convertView.findViewById (android.R.id.text1); convertView.setTag (houder); else holder = (ViewHolder) convertView.getTag (); houder.text.setText (getItem (positie) .getDescription ()); return convertView;
Wanneer een item wordt aangeklikt in deze lijst, wordt de ID van de geselecteerde Plaats
wordt doorgegeven aan de onItemClickedListener
en gezocht naar om weer te geven.
Het laatste deel van deze tutorial behandelt het vinden van een Plaats
object op basis van zijn ID. Dit werkt op dezelfde manier als de andere API-aanroepen door een PendingIntent
en interactie met een geretourneerde buffer om de plaats op te halen. Net als de andere bufferobjecten waarmee je hebt gewerkt, de PlaceBuffer
moet bellen vrijlating
om geheugenlekken te voorkomen.
private void findPlaceById (String id) if (TextUtils.isEmpty (id) || mGoogleApiClient == null ||! mGoogleApiClient.isConnected ()) terug; Places.GeoDataApi.getPlaceById (mGoogleApiClient, id) .setResultCallback (new ResultCallback() @Override public unfid onResult (PlaceBuffer-plaatsen) if (places.getStatus (). IsSuccess ()) Place place = places.get (0); displayPlace (plaats); mPredictTextView.setText (""); mAdapter.clear (); // Ontgrendel de PlaceBuffer om te voorkomen dat een geheugenlekken places.release (); );
De Places API is een krachtig hulpmiddel om uw apps bewust te maken van de locatie van de gebruiker om hen contextuele informatie te bieden. In deze zelfstudie hebt u geleerd hoe u de component Place Picker gebruikt, de plaats van de gebruiker raadt, deze tijdens het zoeken voorziet van voorspellende resultaten en een plaats vindt op basis van een opgegeven ID. Naast de onderwerpen die hier worden behandeld, is het ook mogelijk om nieuwe plaatsen bij Google in te dienen om de informatie te helpen uitbreiden waartoe de API toegang heeft.