A marzo 2015, Google ha rilasciato l'API Places per Android come parte dei servizi di gioco di Google. Questa API consente agli sviluppatori di accedere a una grande quantità di informazioni da Google per fornire agli utenti un'esperienza personalizzata in base alla loro posizione corrente utilizzando i nomi e le informazioni dei luoghi, piuttosto che un insieme di coordinate.
In questo tutorial, imparerai come presentare i tuoi utenti con il componente Seleziona Raccoglitore, utilizzare l'API di Places per indovinare la posizione corrente dell'utente, cercare un luogo tramite il suo ID e consentire all'utente di digitare in un campo di testo per presentarli con risultati predittivi.
Se non hai già una chiave API pubblica Android, dovrai creare una chiave API pubblica per le applicazioni Android. Puoi farlo visitando la Google Developers Console. Le istruzioni per la creazione di una chiave in base al certificato di firma e al nome del pacchetto sono disponibili nella documentazione di Google e vanno oltre lo scopo di questo articolo.
Quando hai creato una chiave, cerca l'API di Places e impostala su enabled. Alcune chiamate all'API Places sono limitate in quante richieste possono essere inviate per periodo di 24 ore. Al momento della scrittura, un account senza profilo di fatturazione può inviare fino a 1.000 richieste mentre un account con un profilo di fatturazione può inviare 150.000 richieste. Se ne hai bisogno di più, puoi inviare una richiesta per aumentare questo limite come descritto nella documentazione sui limiti di utilizzo.
Con la chiave API pronta per l'uso, è ora di iniziare a lavorare sul progetto demo. Crea un progetto in Android Studio e imposta almeno la versione minima supportata dell'SDK 9. Questo è il requisito minimo per l'utilizzo dei servizi di riproduzione di Google.
Una volta che Android Studio ha creato il Ciao mondo modello di progetto, apri il build.gradle file e, sotto il dipendenze
nodo, aggiungi la dipendenza richiesta di Play Services 7.0. Questo è l'ultimo al momento della scrittura, ma puoi verificare l'ultima versione controllando la documentazione di Google.
dependencies compile fileTree (dir: 'libs', include: ['* .jar']) compila 'com.android.support:appcompat-v7:22.0.0' compila 'com.google.android.gms: play-services : 7.0.0 '
Avanti, aperto AndroidManifest.xml, aggiungere le autorizzazioni necessarie per il progetto e indicare che OpenGL versione 2 è richiesta dall'applicazione.
L'ultima cosa che devi fare nel manifest è l'aggiunta di due
tag per impostare la versione di gms e la chiave API per l'app all'interno di
etichetta.
Quando hai finito con manifest, sei pronto per iniziare a scrivere codice. Poiché questo è un componente di Play Services, dovrai inizializzare il tuo GoogleApiClient
e connettersi / disconnetterlo durante il tuo Attività
Il ciclo di vita. Lo facciamo nel onCreate
, onStart
, e onStop
metodi del Attività
classe.
@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 && mGoogleApiClient.isConnected ()) mGoogleApiClient.disconnect (); super.onStop ();
Il widget Scelta luogo è un componente dell'interfaccia utente fornito da Play Services che consente all'utente di visualizzare una mappa dell'area circostante. Il componente include un elenco di luoghi nelle vicinanze che possono essere utilizzati dalla tua app. Usando questo componente, sei in grado di seguire un design standard che i tuoi utenti sapranno come interagire con il tempo risparmiando sui tempi di sviluppo.
Per utilizzare il Selettore dei luoghi, devi creare un intento e ascoltare il Attività
risultato per recuperare il luogo selezionato dall'utente. Il seguente metodo mostra come lo avvierai Attività
.
private void displayPlacePicker () if (mGoogleApiClient == null ||! mGoogleApiClient.isConnected ()) return; PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder (); prova startActivityForResult (builder.build (getApplicationContext ()), PLACE_PICKER_REQUEST); catch (GooglePlayServicesRepairableException e) Log.d ("PlacesAPI Demo", "GooglePlayServicesRepairableException gettato"); catch (GooglePlayServicesNotAvailableException e) Log.d ("PlacesAPI Demo", "GooglePlayServicesNotAvailableException gettato");
Il PlacePicker.IntentBuilder
è usato per creare il Intento
che verrà utilizzato per avviare il Place Picker. Ha anche un metodo disponibile, setLatLngBounds
, che consente di posizionare un confine geografico da un angolo sud-ovest a un angolo nord-est per controllare l'area di ricerca.
Il Intento
può essere costruito usando il costruire
metodo da PlacePicker.IntentBuilder
e lanciato usando il startSubActivity
metodo dal tuo Attività
. Va notato che l'utilizzo del costruire
il metodo ha la possibilità di lanciare a GooglePlayServicesRepairableException
o a GooglePlayServicesNotAvailableException
eccezione, quindi quelli dovrebbero essere controllati per l'utilizzo di un blocco try / catch standard e gestiti con garbo se si verificano.
Se l'utente seleziona una posizione dall'elenco di selezione dei luoghi, quello Posto
l'oggetto è confezionato in un Intento
e rimandato alla chiamata Attività
. Usando il PlacePicker.getPlace
metodo, è possibile estrarre il Posto
dati dal reso Intento
.
protected void onActivityResult (int requestCode, int resultCode, Intent data) if (requestCode == PLACE_PICKER_REQUEST && resultCode == RESULT_OK) displayPlace (PlacePicker.getPlace (data, this));
Una volta il Posto
l'oggetto viene estratto, può essere trattato come un oggetto modello da visualizzare o utilizzare all'interno della tua app.
private void displayPlace (Place place) if (place == null) return; String content = ""; if (! TextUtils.isEmpty (place.getName ())) content + = "Nome:" + place.getName () + "\ n"; if (! TextUtils.isEmpty (place.getAddress ())) content + = "Indirizzo:" + place.getAddress () + "\ n"; if (! TextUtils.isEmpty (place.getPhoneNumber ())) content + = "Phone:" + place.getPhoneNumber (); mTextView.setText (contenuto);
Un'altra caratteristica interessante dell'API Places è che puoi utilizzarla per indovinare se l'utente si trova attualmente in un luogo elencato. L'API fornirà anche una probabilità in modo che tu possa prendere decisioni informate su come l'app deve interagire con l'utente. Va notato che questa è una delle funzionalità dell'API che richiede una richiesta contro gli usi assegnati.
Per rilevare la posizione dell'utente, è necessario utilizzare il Places.PlacesDetectionApi.getCurrentPlace
metodo per creare a PendingIntent
che ritorna con a PlaceLikelihoodBuffer
oggetto. Usare un ResultCallBack
, puoi prendere il primo, e molto probabilmente, posto dal buffer e usarlo nella tua app.
Se la tua app ha bisogno di più informazioni, puoi estrarne altre PlaceLikelihood
elementi dal buffer scorrendo attraverso di esso. La probabilità che questo luogo sia dove si trova attualmente l'utente viene riconsegnata a ciascuno di essi PlaceLikelihood
oggetto come valore in virgola mobile da 0.0 a 1.0, 1.0 essendo quasi una partita garantita. Non dimenticare di chiamare pubblicazione
sul PlaceLikelihoodBuffer
per evitare perdite di memoria.
private void guessCurrentPlace () PendingResultresult = Places.PlaceDetectionApi.getCurrentPlace (mGoogleApiClient, null); result.setResultCallback (nuovo ResultCallback () @Override public void onResult (PlaceLikelihoodBuffer probablyPlaces) PlaceLikelihood placeLikelihood = likelyPlaces.get (0); String content = ""; if (placeLikelihood! = null && placeLikelihood.getPlace ()! = null &&! TextUtils.isEmpty (placeLikelihood.getPlace (). getName ())) content = "Luogo più probabile:" + placeLikelihood.getPlace (). getName () + "\ n"; if (placeLikelihood! = null) content + = "Variazione percentuale dell'essere lì:" + (int) (placeLikelihood.getLikelihood () * 100) + "%"; mTextView.setText (contenuto); likelyPlaces.release (); );
Il prossimo argomento, più complesso, che esamineremo in questo tutorial è la previsione e la visualizzazione dei luoghi per l'utente quando inseriscono una query di ricerca. Ancora una volta, questa chiamata API conta anche per i limiti di utilizzo dell'API. Tuttavia, è di valore inestimabile per rendere la tua app più utilizzabile.
Per questa parte del tutorial, userai un AutoCompleteTextView
e un adattatore personalizzato nell'app per digitare il nome di un luogo per le previsioni. Quasi tutto il lavoro è fatto nell'adattatore. Tuttavia, dovremo passare un riferimento al GoogleApiClient
all'adattatore per poter accedere all'API.
Questo può essere fatto nello standard GoogleApiClient
richiama, onConnected
, e possiamo rimuovere l'istanza del client in onStop
dove mAdapter
è un'istanza della nostra abitudine Adattatore
classe, AutoCompleteAdapter
.
@Override protected void onStop () if (mGoogleApiClient! = Null && mGoogleApiClient.isConnected ()) mAdapter.setGoogleApiClient (null); mGoogleApiClient.disconnect (); super.onStop (); @Override public void onConnected (Bundle bundle) if (mAdapter! = Null) mAdapter.setGoogleApiClient (mGoogleApiClient);
Per attivare una chiamata API ogni volta che l'utente digita una nuova lettera nel AutoCompleteTextView
, hai bisogno di scavalcare il getFilter
metodo del ArrayAdapter
. Questo metodo viene attivato ogni volta che l'utente modifica il contenuto della vista associata all'adattatore. Ti permette di cambiare il contenuto dell'adattatore del AutoCompleteTextView
. Nell'esempio seguente, vincoli
è il contenuto della vista.
@Override public Filter getFilter () return new Filter () @Override protected FilterResults performFiltering (CharSequence constraint) if (mGoogleApiClient == null ||! MGoogleApiClient.isConnected ()) Toast.makeText (getContext (), "Not connected ", Toast.LENGTH_SHORT) .show (); return null; clear (); displayPredictiveResults (constraint.toString ()); return null; @Override protected void publishResults (CharSequence constraint, FilterResults results) notifyDataSetChanged (); ;
Il displayPredictiveResults
il metodo è dove si verifica l'interazione effettiva con l'API. Ci sono alcuni oggetti diversi che possono essere fatti per personalizzare le tue previsioni.
Il primo è a LatLngBounds
oggetto che crea un confine quadrato da un punto sud-ovest a un punto nord-est per localizzare la query. Se nullo
viene passato anziché inizializzato LatLngBounds
oggetto, quindi nessuna restrizione geografica verrà inserita nella query.
LatLngBounds bounds = new LatLngBounds (new LatLng (39.906374, -105.122337), new LatLng (39.949552, -105.068779));
Il secondo oggetto che è possibile creare per personalizzare la query è un filtro per la richiesta dell'API. Il filtro per il posti
AutoCompletePredictions
la chiamata è una lista di Numero intero
oggetti che rappresentano diversi tipi di filtri. A questo punto, è possibile applicare un solo tipo di filtro a una query. I valori accettabili possono essere trovati nella documentazione. Se la Numero intero
la lista è vuota o nullo
viene passato, quindi vengono restituiti tutti i tipi di risultati.
Una volta che sei pronto per fare la richiesta, puoi usare il Places.GeoDataApi.getAutocompletePredictions
metodo per restituire a PendingIntent
, che può essere associato a a ResultCallback
per visualizzare le informazioni restituite.
È importante notare che un oggetto personalizzato che rappresenta il AutoCompletePrediction
gli oggetti dal buffer sono usati per memorizzare i dati nel ArrayAdapter
. Altrimenti a IllegalArgumentsException
l'eccezione verrebbe generata non appena viene rilasciato il buffer, il che è fondamentale per evitare perdite di memoria.
private void displayPredictiveResults (String query) // Angolo sud-ovest all'angolo nord-est. LatLngBounds bounds = new LatLngBounds (new LatLng (39.906374, -105.122337), new LatLng (39.949552, -105.068779)); // Filter: https://developers.google.com/places/supported_types#table3 ListfilterTypes = new ArrayList (); filterTypes.add (Place.TYPE_ESTABLISHMENT); Places.GeoDataApi.getAutocompletePredictions (mGoogleApiClient, query, bounds, AutocompleteFilter.create (filterTypes)) .setResultCallback (nuovo ResultCallback () @Override public void onResult (AutocompletePredictionBuffer buffer) if (buffer == null) return; if (buffer.getStatus (). isSuccess ()) for (AutocompletePrediction previsione: buffer) // Aggiungi come nuovo elemento per evitare IllegalArgumentsException quando il buffer viene rilasciato add (new AutoCompletePlace (prediction.getPlaceId (), prediction.getDescription ( ))); // Previene perdite di memoria rilasciando buffer buffer.release (); , 60, TimeUnit.SECONDS);
Il contenuto in AutoCompleteAdapter
viene visualizzato utilizzando a android.R.layout.simple_list_item_1
layout e modello ViewHolder standard in GetView
.
@Override pubblico Visualizza getView (posizione int, Visualizza convertView, ViewGroup parent) titolare ViewHolder; 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 (titolare); else holder = (ViewHolder) convertView.getTag (); holder.text.setText (getItem (posizione) .getDescription ()); return convertView;
Quando si fa clic su un elemento da questo elenco, l'ID del selezionato Posto
è passato al onItemClickedListener
e cercato per visualizzare.
La parte finale di questo tutorial riguarda la ricerca di a Posto
oggetto basato sul suo ID. Funziona in modo simile alle altre chiamate API creando un PendingIntent
e interagendo con un buffer restituito per recuperare il posto. Come gli altri oggetti buffer con cui hai lavorato, il PlaceBuffer
deve chiamare pubblicazione
per evitare perdite di memoria.
private void findPlaceById (String id) if (TextUtils.isEmpty (id) || mGoogleApiClient == null ||! mGoogleApiClient.isConnected ()) return; Places.GeoDataApi.getPlaceById (mGoogleApiClient, id) .setResultCallback (nuovo ResultCallback() @Override public void onResult (PlaceBuffer places) if (places.getStatus (). IsSuccess ()) Place place = places.get (0); displayPlace (luogo); mPredictTextView.setText (""); mAdapter.clear (); // Rilasciare PlaceBuffer per prevenire una perdita di memoria places.release (); );
L'API Places è un potente strumento per rendere le tue app consapevoli della posizione dell'utente per fornire loro informazioni contestuali. In questo tutorial, hai imparato come utilizzare il componente di selezione dei luoghi, indovinare la posizione dell'utente, presentarli con risultati predittivi durante la ricerca e trovare un luogo basato su un determinato ID. Oltre agli argomenti trattati qui, è anche possibile inviare nuovi posti a Google per aiutare a espandere le informazioni a cui l'API ha accesso.