Nel tutorial di oggi vedremo l'utilizzo del componente LocationSensor (palette Sensors) che permette di ottenere nelle nostre app informazioni sulla "geolocalizzazione" del nostro telefono.
In pratica questo componente viene utilizzato in tutte quelle applicazioni che han bisogno di conoscere con esattezza la nostra posizione.
Gli utilizzi sono veramente innumerevoli (una semplice app che visualizzi le previsioni del tempo per la nostra località, oppure una app che ci ricordi dove abbiamo parcheggiato, etc...) e fortunatamente App Inventor ha un componente apposito fin dalla sua prima release.
L'utilizzo non è proprio immediato ed anche la documentazione ufficiale è in qualche modo lacunosa, vedremo con l'esempio di oggi di chiarirvi un pò le idee e di aiutarvi nella realizzazione delle vostre splendide app!
Anche quest'oggi, per risparmiare tempo, partiremo dalla applicazione "Tutorial Meteo", se non l'avete, andate alla pagina relativa e scaricatene il sorgente prima di iniziare questo tutorial.
L'idea di base è quella di aggiungere una funzione che "legga" la nostra posizione che poi verrà data in pasto al componente web utilizzato per recuperare le previsioni meteo stesse.
Come al solito, buona visione!!!
Il sorgente del progetto lo trovate qui
Alcune note tecniche:
Il componente LocationSensor NON funziona utilizzando l'emulatore o utilizzando il blocks editor collegato al nostro cellulare. Dovremo quindi ogni volta scaricare sul telefono il file .apk affinchè il componente funzioni correttamente!
Useremo anche la funzione UriEncode del componente Web per codificare nel formato HTML corretto la stringa da passare all'API di google weather.
Vi riporto infine brevemente l'help tradotto in italiano del componente stesso:
LocationSensor
Il componente ci fornisce la posizione del device Android utilizzando il GPS se disponibile od un metodo alternativo come la triangolazione delle celle o gli access point wifi conosciuti.
Il componente ci fornisce i dati di latitudine , longitudine, altezza e indirizzo
Questo componente può anche fornire "geocoding", convertendo un indirizzo in una coppia latitudine/longitudine.
Affinchè funzioni è necessario che il componente sia settato "enabled" ed il device deve avere un sensore di locazione abilitato (GPS o triangolazione o wifi).
Properties
Accuracy
- Accuratezza della lettura, in metri.
Altitude
- Altitudine (se disponibile).
AvailableProviders
- Lista dei provider disponibili (gps, network)
CurrentAddress
- Indirizzo stradale corrente del dispositivo.
Enabled
- Se abilitato, le informazioni sulla posizione vengono rese disponibili.
HasAccuracy
- Se "true" il device può dare informazioni riguardo l'accuratezza della misurazione.
HasAltitude
Se "true" il device può dare informazioni riguardo l'altezza.
HasLongitudeLatitude
- Se "true" il device può dare informazioni su lat/lon.
Latitude
- La latitudine attuale del dispositivo.
Longitude
- La longitudine attuale del dispositivo.
ProviderLocked
- Il device non cambierà autonomamente il suo provider per la posizione (gps o network).
ProviderName
- Il nome del provider corrente (gps, network e credo wifi ma non ne son sicuro...).
Events
LocationChanged(number latitude, number longitude, number altitude)
- Evento generato quando il device acquisisce una NUOVA posizione.
StatusChanged(text provider, text status)
- Evento generato quando il device CAMBIA il suo provider per la lettura della posizione.
Methods
LatitudeFromAddress(text locationName)
- Trasforma l'indirizzo passato nel suo corrispondente valore di latitudine.
LongitudeFromAddress(text locationName)
- Trasforma l'indirizzo passato nel suo corrispondente valore di longitudine.
grazie per i tutorial. Volevo chiedere a te oppure ai tantissimi " seguaci " dei tuoi video. E' possibile impostare in una label il numero dei satelliti visibili e quindi connessi? Io ho provato ma oltre al nome GPS non sono riuscito a visualizzare. Sapete qualcosa in piu' che io non conosco? Grazie
RispondiEliminaNo, il componente non ritorna il numero di satelliti che sta vedendo, puoi però provare a stampare il valore di "accuracy" che riporta l'accuratezza della lettura in metri.
EliminaTanto più basso è questo valore tanti più satelliti sono visibili dal tuo GPS.
Ciao, ho provato alcuni esempi pubblicati qui utilizzando il activitystarter e questo non funziona sul mio Samsung Galaxy S, quando cerco di fare clic sul pulsante che utilizza il activitystarter dà un errore: "Errore 601:. Nessuna attività corrispondente è stata trovata non ho modificato alcun file, sto usando i tuoi esempi. Qualsiasi aiuto? GRAZIE!
RispondiEliminanon dovrebbe assolutamente dipendere dal telefono,prova a mandarmi lo screenshot del tuo blocks editor e vedo probabilmente dove c'è l'errore.
EliminaErrore 601 indica qualche problema nella sintassi dell'activitystarter.
Bravo Sebastiano!! Ho scoperto i tuoi tutorial da poco... Sono proprio interessanti!! continua così... ;)
RispondiEliminaHo però un problema con il locationSensor1.CurrentAddress...
Non mi dice l'indirizzo ma mi scrive "No address available".
Sai perchè? Come posso risolvere?
Hai il gps attivo? Hai provato a lanciare l'app quando sei all'aperto? Ovviamente con l'emulatore non va ma solo con un telefono vero
RispondiEliminaSe non hai risolto prova a mandarmi il tuo sorgente per email e vedo se da me funziona...
Bene, ora funziona perfettamente... Grazie!
EliminaInvece avrei bisogno di aiuto sulle matrici... dove posso scriverti?
s e blogapps@gmail.com , ovviamente rimuovi gli spazi
EliminaCiao Sebastiano,
RispondiEliminaho visto il tutorial, molto bel fatto complimenti, ma mi deve esser sfuggito qualcosa..
se attivo sullo smartphone (galaxy sII) anche "Usa reti wireless" registro solo le coordinate della cella telefonica; ho fatto anche la prova del nove, ovvero disattivendo nuovamente le reti wireless torna a registrare i più accurati dati GPS
posso fare qualcosa? non ho settato bene il sensore?
grazie in anticipo
Gabriele
non dovrebbe essere così, nel senso che lui usa la miglior posizione possibile quindi se hai attivo posizioni wireless e gps prende il segnale dal gps, mentre se il gps non riesce a fare il lock sui satelliti allora prende le informazioni dalla cella telefonica.
EliminaProva a vedere che lettura ti da la proprietà "ProviderName", quando fa il fix dovrebbe dirti "gps"
Intanto grazie mille per la solerzia
Eliminacomunque come non detto.....mi sono rivisto il tutorial ed effettivamente mi ero perso la parte del provider, comunque ha magicamente preso a funzionare.
pur essendo per strada o sul balcone all'aria aperta è da ieri che non funzionava, ma non avevo tenuto conto del maltempo era questa la difficoltà che evidentemente incontrava.
suggerisco per primo a me stesso e se posso anche agli altri utenti, di mettere magari un controllo e se server fare una notifica di quale provider si stia utilizzando al momento in maniera tale da poter "giustificare" eventuali imprecisioni del rilevamento GPS
grazie ancora
Gabriele
Confermo lo strano problema segnalato da Gabriele: su Galaxy s2, se tengo attiva nelle impostazioni del servizio di localizzazione "usa reti wi-fi", le applicazioni create con app inventor mi sbagliano la localizzazione anche di qualche chilometro a meno che il wifi non sia attivo. Disattivando l'opzione, invece, ci mette un po' di più a trovare le coordinate, ma queste risultano precise.
EliminaPuò essere dovuto forse al fatto che tentando di recuperare i dati più immediati sulla posizione il telefono recupera prima la triangolazione della cella e successivamente i satelliti.
Poi il programma fatto in app inventor non rileva il "cambiamento" di posizione una volta arrivati anche i dati del gps e restano le coordinate sbagliate.
Ciao Ruben,dipende "quando" leggi i dati, su evento "LocationChanged" oppure leggi solo il "CurrentAddress"?
EliminaIo penso si fermi al primo indirizzo utile che recupera,quindi meglio fare un controllo anche su provider e magari prendere la posizione solo quando il provider è gps
Ciao! E' la prima volta che visito il tuo blog e l'ho trovato molto interessante! ;) Ti spiego rapidamente la mia situazione: sto sviluppando un'app per il mio ultimo esame all'università. L'app consiste in una localizzazione del cellulare tramite gps (utile quando ti perdi il telefono). Quando il sistema è attivo, il cellulare appena riceve un sms risponderà al mittente dell'sms con un messaggio dove indica l'indirizzo, la latitudine e la longitudine di dove si trova il telefono. L'app l'ho scaricata sul telefono, ma quando l'avvio all'indirizzo compare "no address available" e alle coordinate GPS "0.0 - 0.0". Ho provato l'app anche sul balcone di casa ma niente. Come posso risolvere? Grazie mille! ;)
RispondiEliminaPasticciando con il componente locationsensor, devo aver settato qualcosa che non consente piu di rilevare la posizione.
RispondiEliminaTi anticipo che "Locationsensor1.Enabled" è true "Locationsensor.HaslongitudeLatitude" è false. Come ripristinarlo. Ciao e grazie per i tuoi tutorial
non credo ci sia nulla da ripristinare,se fai ripartire la tua app reinizializza anche il modulo GPS
EliminaAl massimo cancella il componente da design editor e rimettilo così ti rimette tutti i valori a quelli di default
Ciao, ci sarebbe un metodo per rendere l'intera localizzazione (intendo via, cap, città, nazione) in un dato che rilascia solo la città? Grazie!
RispondiEliminanon direttamente, devi sempre leggere tutto il dato e poi ti estrai a mano il nome della città, ora non ricordo ma può essere che la posizione in cui appare la città sia sempre fissa (ad esempio in ultima posizione)
Eliminaquindi ti puoi creare una funzione di ricerca testuale e di split che ti estragga solo l'info voluta
Ciao, Sebastiano, mi chiamo Domenico e grazie a te ho imparato a fare qualche applicazione apk.
RispondiEliminaArrivo al dunque. Ho fatto un programma per controllare un’antenna satellitare con un modulo BT HC-05 e un Galaxy S3 dove ho implementato il calcolo di Azimut ed Elevazione in relazione alle coordinate in cui ci si trova, con questa formula:
v1 = 6,612 * cos(LAT)*cos(LONG-SATLONG)-1
v2 = 6,612 * sqrt(1-(cos(LAT)^2) * (cos(LONG-SATLONG))^2)
Elevazione = atan(v1/v2)
Azimut = 180 + atan( tan(LONG-SATLONG) / sin(SATLONG) )
POLARIZZAZIONE = -atan( sin(LONG-SATLONG)/tan(LAT) );
dove:
• LONG è la longitudine del luogo dove è posizionata la parabola;
• SATLONG è la longitudine del satellite;
• LAT è la latitudine del luogo dove è posizionata la parabola.
• sqrt è la radice quadrata
La costante 6,612 è pari al rapporto tra il raggio di un'orbita geostazionaria e il raggio terrestre.
Stando alle tabelle e ad altri programmi tipo SatFinder.apk, nella zona dove abito io (Torino), per HOTBIRD dovrei avere circa Azimut 172° e Elevazione 39°. Le coordinate me le dà giuste (45, ….. e 7, ….) mentre il risultato della formula mi dà 157 e 32. Non sto ad inviare lo screenshot del blocks editor in quanto la formula V2 non mi sta sullo schermo e non so come fare, comunque l’ho controllata attentamente e sono convinto di averla impostata giusta. Siamo sicuri che con le formule trigonometriche il programma non faccia errori? Hai qualche esperienza in merito?
Grazie e complimenti ancora
scusa se rispondo solo ora, prova a vedere su emulatore (impostato con lingua inglese) e sul tuo telefono (impostato su lingua italiana) , visto che il problema potrebbe essere la gestione dei . e della , nelle notazioni anglosassoni o europee.
EliminaPutroppo App Inventor fa un pò di casino con queste cose,
poi controlla passo passo i tuoi calcoli con i risultati che ti aspetti dopo ogni step per poter così trovare dove sta l'errore, fammi sapere se risolvi! ciao
dimenticavo, il valore di SATLONG è 13
RispondiEliminaNessuno ha idea di come risolvere il problema?
RispondiEliminaO forse questo non è il posto giusto per intavolare la discussione?
Buongiorno Sebastiano.
RispondiEliminaE' la prima volta che scrivo ma seguo il tuo blog da parecchio tempo e con i tuoi tutorial sono riuscito a fare un sacco di cosette carine.
Ho sfruttato questo tutorial per iniziare a creare un applicazione che dal momento che stacco una fotografia il sensore mi restituisce le coordinate e l'indirizzo.
Ma ho un paio di cose da chiederti che forse mi risolverai in due minuti.
Per prima cosa ho il problema di dover catturare più fotografie sullo stesso posto e sembra che finchè non cambia posizione il sensore non registra le coordinate e non restituisce un valore valido (0).
Seconda cosa Come posso fare un ciclo di attesa finchè il sensore non acquisisce le coordinate e, meglio, uno stato di attesa finche l'accuratezza non sia <= ad un valore predefinito ( es.5mt)
Ti ringrazio anticipatamente per la risposta e ti saluto
Zio
p.s.
Per informazione e completezza ti dico che sto usando il MIT2
Ciao
Allora, da quel che ne so, l'evento LocationChanged viene triggerato quando c'è uno spostamento, però le coordinate le hai a disposizione anche prima appena c'è un fix valido della posizione.
EliminaQuindi in pratica se fai due foto nello stesso posto, puoi semplicemente chiedere le coordinate al location sensor senza legare l'evento per forza a "locationchanged"
Per capire se hai delle coordinate valide puoi appunto aspettare l'evento "locationchanged" quando quell'evento viene generato di sicuro hai delle coordinate (magari prese dalla rete GSM e non dal GPS ma magari ti vanno bene lo stesso)
Per sapere se hai una posizione valida controlla il valore di "hasAccuracy"
Di conseguenza secondo me non ti serve fare un ciclo di attesa ma programmare il tuo evento in "locationchanged" la prima volta, oppure se vuoi la precisione del GPS devi forzare il locationsensor su GPS chiamando il metodo:
set providersensor.ProviderName=GPS
spero di esserti stato d'aiuto, ciao!
Sei stato perfetto! Grazie
EliminaInfatti a me vanno benissimo le prime coordinate che arrivano all'apertura dell'applicazione mettendole dentro un blocco when "screen".initialize poco dopo mi restituisce la posizione.
Quello che intendevo per il ciclo era anche solo per una ....posizione di attesa che potrebbe servirmi anche per altre cose tipo: "aspetta fino a che una determinata label non sia valorizzata" cioè un ciclo per il wait dell'applicazione e informaren con un notifier che l'applicazione sta lavorando.
Ma forse questo fa parte di una ltro tutorial.
nel frattempo grazie del tuo prezziosissimo aiuto.
Cristiano
Ciao Seba, grazie per i tutorial. E' possibile far segnalare ad un utente un punto preciso sulla mappa che corrisponde alla sua posizione e renderla visibile a tutti gli utenti che useranno l'app. Come devo inserire le API statiche di Gmaps? Hai un'app simile?
RispondiEliminaMolto curioso, ma se volessi utilizzare la localizzazione di un altro smartphone come dovrei fare, una sorta di richiesta da uno smartphone all'altro....
RispondiElimina