Google Play-services de Places-API gebruiken

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.

1. Instellen

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 Activiteitde levenscyclus. We doen dit in de onCreateonStart, 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 (); 

2. Gebruik de Widget Plaats kiestool

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); 

3. De huidige plaats van de gebruiker vinden

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 () PendingResult result = 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 (); ); 

4. Plaatsen voorspellen

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 Lijst filterTypes = 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.

5. Zoeken naar een plaats op ID

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 (); ); 

Conclusie

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.