Top Banner
Matteo Moreno Matricola 722172 Anno Accademico 2015/2016 13 giugno 2016 Programmazione Dispositivi Mobili
31

Android Overview

Feb 17, 2017

Download

Science

Matteo Moreno
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Android Overview

Matteo MorenoMatricola 722172

Anno Accademico 2015/201613 giugno 2016

Programmazione Dispositivi Mobili

Page 2: Android Overview

Categoria BINTENTS AND INTENT FILTERS

Categoria CDATA STORAGE

Categoria D LOCATION API

Categoria ABROADCAST RECEIVERS

Applicazione BR Applicazione EI-IApplicazione IF

Applicazione LA Applicazione ISApplicazione ESApplicazione DB

Page 3: Android Overview

Categoria A : BROADCAST RECEIVERSI BroadcastReceivers rispondono semplicemente ai messaggi di tipo broadcast derivanti da altre applicazioni e dal sistema stesso.

Questi messaggi sono molto spesso chiamati events o intents.

Ad esempio: le applicazioni possono inviare messaggi di tipo broadcast in modo tale che altre applicazioni possano sapere che il download di un file è terminato ed è quindi disponibile per le applicazioni interessate.

Ci sono due importanti passi per fare si che un BroadcastReceiver funzioni per la diffusione degli intenti di sistema: Creare il Broadcast Receiver Registrare il Broadcast Receiver

Ci sarebbe inoltre un successivo passo nel quale si procede con l’implementazione di intenti personali, che una volta creati dovranno essere diffusi in modalità broadcast.

Page 4: Android Overview

Categoria A : BROADCAST RECEIVERS

Creazione di un Broadcast Receiver

Un Broadcast Receiver è implementato come una sottoclasse della classe BroadcastReceiver e facendo overriding del metodo onReceive(), dove ogni messaggio è ricevuto come parametro di un oggetto di tipo Intent.

Page 5: Android Overview

Categoria A : BROADCAST RECEIVERSRegistrazione di un Broadcast Receiver

Un’applicazione ricerca uno specifico intent di tipo broadcast archiviando un Broadcast Receiver nel file AndoridManifest.xml. Consideriamo, ad esempio, che si vuole registrare MyReceiver per l’evento generato del Sistema ACTION_BOOT_COMPLETED, che viene distrutto una volta che il Sistema Android ha completato il processo di boot.

In questo modo, ogni volta che il dispositivo Andorid effettuerà il boot, verrà intercettato dal Broadcast Receiver MyReceiver e la logica implementata all’interno di onReceive() verrà eseguita.

Page 6: Android Overview

Categoria A : BROADCAST RECEIVERS

Ci sono molti eventi generati dal Sistema definiti come campi static e final all’interno della classe Intent.

La tabella mostra una lista dei piu’ importanti.

Page 7: Android Overview

Categoria A : BROADCAST RECEIVERSInvio di Intenti Personalizzati

Se si vuole che l’applicazione in modo autonomo generi e invii intenti personalizzati, bisogna creare e inviare questi intenti usando il metodo sendBroadcast() all’interno della classe Activity. Se si usa il metodo sendStickyBroadcast(Intent), l’intent è sticky, in quanto l’intent che viene inviato rimare in giro anche nel momento in cui il broadcast è completo.

Page 8: Android Overview

Categoria A : BROADCAST RECEIVERS

Il metodo OnReceive() intercetta il messaggio broadcast e reagisce, in base a come è stato implementato.

Il tasto ‘START BROADCAST’ consente di inviare un messaggio ‘messaggio broadcast’, come mostrato dal codice:

Page 9: Android Overview

Categoria B : INTENTS AND INTENT FILTERSIn Android un Intent è una descrizione astratta di un azione che sarà performata. Può essere usato con startActivity per lanciare un Activity, broadcastIntent per inviarlo ad un qualunque Broadcast Receiver e con startService(Intent) or bindService(Intent,ServiceConnection,int) per comunicare con un servizio in background.

Ad esempio, assumiamo che si ha un Activity che deve lanciare un client email e deve inviare una email usando il proprio dispositivo Android. A questo scopo, l’Activity invierà un ACTION_SEND insieme all’appropiato chooser, al Intent Resolver di Android. Il selettore offrirà la propria interfaccia all’utente per scegliere in che modo inviare i dati via email.

Il codice chiama il metodo startActivity per fare partire una Activity per le email, e il risultato è quello mostrato nella figura

Page 10: Android Overview

Categoria B : INTENTS AND INTENT FILTERSIntent Objects

Un Intent object è un pacchetto di informazioni che è usato sia dal componente che riceve l’intent, sia dal Sistema Android. In base a quello che viene comunnicato o all’azione che si andrà a performare, un Intent object può contenere i seguenti elementi:

• ActionQuesta è una parte obbligatoria dell’Intent ed è una stringa che dà il nome all’azione che andrà ad essere performata e determina come il resto dell’ intent object è strutturato. La classe Intent definisce un numero di azioni costanti che corrispondono ad intenti differenti.L’ Action è un Intent object che puo’ essere settato dal metodo setAction() e letto da getAction().

• DataAggiunge e precisa i dati in un intent filter; in particolare si puo’ avere un tipo dati (attributo mimeType), un URI oppure entrambi.Il metodo setData() specifica che i dati sono come un URI, setType() li specifica solo come MIME type, e setDataAndType() li specifica in entrambi i modi appena elencati. L’URI è letto dal metodo getData() e il tipo da getType().

Page 11: Android Overview

Categoria B : INTENTS AND INTENT FILTERS• CategoryE’ una parte opzionale di un Intet Object; si presenta come una stringa che contiene informanzioni aggiuntive che dovranno gestire l’Intent.Il metodo addCategory() posizione una categoria in un Intent object, mentre il metodo removeCategory() cancella una categoria aggiunta in precedenza e, infine, il metodo getCategories() restituisce le categorie che si trovano nell’Intent object.

• ExtrasQuesto sarà una coppia di valori chiave per informazioni aggiuntive che dovranno essere inviate all’handler dai component dell’intent.Possono essere settati e letti usando i metodi putExtras() e getExtras() rispettivamente.

• FlagsSono una parte opzionale di un Intent object e istruiscono il Sistema Android su come lanciare un Activity, cosa fare una volta che questa è stata lanciata, ecc.La tabella riporta alcune delle Flags piu’ importanti.

Page 12: Android Overview

Categoria B : INTENTS AND INTENT FILTERSExplicit Intents

Utili per collegare un’Activity ad un’altra. Nello schema sotto, la prima Activity è collegata alla seconda grazie al click che viene effettuato sul bottone “click me”.

Designano il target attraverso il proprio nome e sono usati tipicamente per applicazioni, per le quali un Activity lancia un servizio subordinato oppure una Activity collegata.

Implicit IntentsNon indicano il nome del target e il campo per il nome della componente viene lasciato vuoto. Sono spesso usati per attivare component in altre applicazioni.

Il component che riceve l’Intent puo’ usare il metodo getExtras() per ricevere dati extra inviati dalla component sorgente.

Page 13: Android Overview

Categoria B : INTENTS AND INTENT FILTERSExplicit Intent: far partire un Component disponibile nella stessa Activity.

Implicit Intent: far partire un Component disponibile in altre applicazioni.

Page 14: Android Overview

Categoria B : INTENTS AND INTENT FILTERSIntent Filters

Il sistema operativo Android utilizza i filtri per indicare con esattezza quali Activity, Service o Broadcast Receiver possono gestire l’Intent con l’aiuto di specifiche azioni, categorie e dati associate ad un Intent.Si utilizza l’elemento <intent-filter> nel file AndroidManifest.xml per fare una lista di azioni, categorie e tipi di dati associate ad un Activity, Service o un BroadcastReceiver.

A lato, un esempio di una parte del file AndroidManifest.xml che specifica l’Activity com.example.My Application.CustomActivity la quale puo’ essere invocata o dalle due actions, o da category, oppure da data.

Una volta che l’Activity è definita per i filtri menzionati, le altre Activity sono in grado di invocarla usando o android.intent.action.VIEW oppure usando com.example.My Application.LAUNCH fornendo la categoria android.intent.category.DEFAULT

L’elemento <data> specifica il tipo che l’Activity si aspetti che venga chiamato; nell’esempio l’Activity si aspetta che il dato inizi con http://

Page 15: Android Overview

Categoria B : INTENTS AND INTENT FILTERSSi potrebbe verificare il caso in cui un Intent possa passare attraverso i filtri di una o piu’ attività o servizi e che all’utente sia chiesto quali di queste component attivare.Si solleverà un’eccezione nel caso in cui nessun target verrà trovato

Android effettua i seguenti test prima di invocare un Activity:

• Un filtro <intent-filter> puo’ avere una lista di piu’ di un’azione, ma questa lista non puo’ essere vuota; un filtro deve contentere almeno un element <action>, altrimenti l’Intent verrà bloccato. Se vengono menzionate piu’ azioni, il sistema Android proverà ad abbinare una di quelle menzionate prima di invocare l’Activity.

• Un filtro <intent-filter> puo’ avere una lista di zero, una o piu’ categorie; se c’è una sola categoria menzionata; se non ci sono categorie menzionate, Android supera sempre questo test, ma nel caso ci sia piu’ di una categoria elencata, allora ogni categoria della classe Intent deve abbinarsi ad una categoria nel filtro.

• Ogni elemento <data> puo’ specificare un URI e un tipo dato; non ci sono attributi distinti come scheme, host, port e path per ogni parte dell’URI. Un Intent object che contiene sia l’URI che il tipo dato passa il test solo se il tipo del dato si abbina al tipo del dato presente nel filtro

Page 16: Android Overview

Categoria B : INTENTS AND INTENT FILTERSIntent Filter: l’ActivityTwo dell’App-A e l’ActivityThree dell’App-C hanno le stesso nome dell’Intent Filter impostato nel file AndoridManifest.xml.

Il Sistema Android chiede dunque all’utente con quale delle due applicazioni desidera continuare.

Page 17: Android Overview

Categoria C : DATA STORAGEAndroid fornisce diverse opzioni per salvare in modo persistente i dati. La soluzione viene scelta in base ai propri specifici bisogni, come ad esempio se i dati devono essere privati per l’applicazione oppure acessibili da altre applicazioni (o da altri utenti) e quanto spazio richiede l’archiviazione dei dati.

Shared PreferencesMemorizzazione di dati privati primitivi a coppie chiave-valore.

Internal StorageMemorizzazione dei dati privati nella memoria interna del dispositivo.

External StorageMemorizzazione di dati pubblici nella memoria esterna del dispositivo.

SQLite DatabasesMemorizzazione di dati strutturati in un database privato.

Page 18: Android Overview

Categoria C : DATA STORAGELa classe SharedPreferences fornisce un framework generale che permette di salvare e recuperare persistenti coppie chiave-valore di tipi di dati primitivi: boolean, float, int, long e string. Questi dati persisteranno per tutte le sessioni dell’utente (anche se l’applicazione verrà ‘uccisa’).

Per ottenere un oggetto SharedPreferences nell’applicazione, bisogna usare uno di questi due metodi:

• getSharedPreferences(): viene usato se si ha bisogno di più file di preferenze identificati attraverso il nome, che verrà specificato come primo parametro.

• getPreferences(): usato se si ha bisogno di un solo file di preferenza per la propria Activity; dato che ci sarà solo un file preferenza nell’Activity, non è necessario fornire un nome.

Per scrivere i valori:• chiamare edit() per ottenere un SharedPreferences.Editor• aggiungere i valori con metodi come putBoolean() e

putString()• inviare i nuovi valori col metodo commit()

Per leggere i valori usare i metodi di SharedPreferences come getBoolean() e getString().

Page 19: Android Overview

Categoria C : DATA STORAGEI file possono essere salvati direttamente nella memoria interna del dispositivo. I file salvati nella memoria interna sono privati per le proprie applicazioni e quindi altre applicazioni non possono avervi accesso (stessa cosa per gli utenti). Nel momento in cui l’utente disinstalla l’applicazione, questi file vengono rimossi.

Per creare e scrivere un file privato nella memoria interna bisogna:

• chiamare openFileOutput() con il nome del file e il modo operativo; questo ritorna un FileOutputStream

• scrivere nel file con write()• chiudere lo stream con close()

Per leggere un file dalla memoria interna si deve:• chiamare openFileInput() e passare il nome del file

da leggere; questo ritorna un FileInputStream• leggere i byte del file con read()• chiudere lo stream con close()

MODE_PRIVATE creerà il file (o lo rimpiazzerà nel caso di file con lo stesso nome) e lo renderà privato per la propria applicazione. Altri metodi disponibili sono: MODE_APPEND, MODE_WORLD_READABLE MODE_WORLD_WRITEABLE

Page 20: Android Overview

Categoria C : DATA STORAGE

Page 21: Android Overview

Categoria C : DATA STORAGEOgni dispositivo compatibile con Android supporta una memoria esterna su cui è possibile salvare i file. Questa puo’ essere una memoria rimovibile (come la scheda SD) oppure una memoria interna (non rimovibile). I file salvati nella memoria esterna possono essere letti da chiunque e modificati dall’utente quando viene attivata l’archiviazione di massa USB per trasferire i file su un computer.

Al fine di leggere o scrivere file nella memoria esterna, l'applicazione deve acquisire i permessi di sistema READ_EXTERNAL_STORAGE o WRITE_EXTERNAL_STORAGE

Prima di qualsiasi operazione sulla memoria esterna, bisogna sempre chiamare il metodo getExternalStorageState() per verificare che il supporto sia disponibile, in quanto questo potrebbe essere mancante, si sola lettura o in qualche altro stato. Di seguito un esempio di un paio di metodi che si possono usare per questo scopo:

Page 22: Android Overview

Categoria C : DATA STORAGE

Page 23: Android Overview

Categoria C : DATA STORAGEAndroid fornisce un supporto completo per SQLite Database. Ogni database creato sarà accessibile tramite il nome da ogni classe dell'applicazione, ma non all'esterno dell'applicazione. Il modo per creare un nuovo SQLite Database è quello di creare una sottoclasse di SQLiteOpenHelper e fare override del metodo onCreate(), nel quale si possono eseguire i comandi SQLite per creare il database.

Per scrivere e leggere dal database, bisogna chiamare rispettivamente i metodi getWritableDatabase() e getReadableDatabase(), che ritornano entrambi un oggetto di tipo SQLiteDatabase che rappresenta il database e fornisce i metodi per le operazioni di SQLite

Inoltre, si posso anche eseguire le queries usando il metodo query(). Ogni SQLite query ritorna un cursor che punta alle righe trovate dalla query. Il cursore è sempre il maccanismo con cui si po' navigare attraverso i risultati della query e leggere le righe e le colonne del database.

SDK Android include uno strumento per il database sqlite3 che permette di navigare nei contenuti delle tabelle, avviare i comandi SQL ed eseguire altre utili funzioni sul database SQLite.

Page 24: Android Overview

Categoria C : DATA STORAGE

Page 25: Android Overview

Categoria D : LOCATION APIAndorid da alle applicazioni accesso ai servizi di localizzazione supportati dal dispositivo tramite le classi contenute nel package android.location. Il componente centrale del framework di localizzazione è il servizio LocationManager, il quale consente alle API di determinare la localizzazione e il cuscinetto del dispositivo sottostante (se disponibile).

Come in altri servizi di sistema, non bisogna istanziare direttamente un LocationManager. Invece bisogna richiedere un istanza al sistema chiamando getSystemService(Context.LOCATION_SERVICE). Il metodo restituisce un gestore per l'istanza LocationManager.

Una volta che l'applicazione ha un LocationManager, l'applicazione sarà in grado di fare tre cose:• Fare query per avere la lista di tutti i LocalProviders per l'ultima posizione nota dell'utente• Registrare/Non registrare gli aggiornamenti periodici di posizione corrente dell'utente da un local

provider• Registrare/Non registrare per un dato intento di essere cancellato se il dispositivo viene fornito

all'interno di una determinata vicinanza di un dato lat/long.

Page 26: Android Overview

Categoria D : LOCATION APIQuando si sviluppa un’applicazione per la localizzazione in Android, si puo' utilizzare sia il GPS che il Network Location Provider di Android per acquisire la posizione dell'utente.

Sebbene il GPS sia piu' accurato, funziona solo all'esterno, consuma batteria più velocemente e non restituisce la posizione in maniera veloce come pretende l'utente.

Il Network Location Provider di Android determina la posizione dell'utente usando le celle e il segnale WI-Fi, fornendo informazioni sia all'interno che all'esterno, rispondendo più velocemente e usando meno batteria.

Per ottenere la localizzazione dell'utente nell'applicazione, si possono usare entrambi i metodi appena descritti, oppure uno solo dei due.

Page 27: Android Overview

Categoria D : LOCATION APIOttenere la posizione di un utente da un dispositivo mobile può essere complicata. Ci possono essere numerose ragioni per cui la lettura della posizione (a prescindere dalla fonte) può contenere errori ed essere imprecisa. Alcune fonti di errori includono:

• Moltitudine di fonti di localizzazioneGPS, Cell-ID, and Wi-Fi possono fornire ognuno indizi sulla posizione dell'utente. Determinare quali di questi fidarsi ed utilizzare è questione di accuratezza, velocità ed efficienza della batteria.

• Movimenti dell'utenteA causa dei cambiamenti di posizione dell'utente, è necessario tenerne conto per effettuare ogni tanto una nuova stima della sua posizione.

• Variando la precisioneLa posizione stimata da ogni fonte di localizzazione può non essere coerente con la sua precisione. Una posizione ottenuta 10 secondi prima da una fonte potrebbe essere più accurata rispetto alla più recente posizione di un altra o della stessa fonte.

Page 28: Android Overview

Categoria D : LOCATION API

Per ottenere la posizione dell'utente in Android lavora con le callback. Si indica che si vorrebbero ricevere gli aggiornamenti sulla posizione dal LocationManager chiamando requestLocationUpdates() e passandolo al LocationListener, il quale implementerà diversi metodi di callback che il LocationManager chiama quando la posizione dell'utente cambia o quando lo stato del dispositivo cambia.

Il primo parametro in requestLocationUpdates() è il tipo di servizio di localizzazione da usare (nell'esempio, il NetworkLocationProvider basato sulla localizzazione da rete mobile e WI-Fi). Si può controllare la frequenza con la quale si ricevono gli aggiornamenti con il secondo e terzo parametro -il secondo è il minimo intervallo tra le notifiche e il terzo è la minima distanza tra le notifiche- settando entrambi a zero per ottenere le richieste di aggiornamento il più frequentemente possibile. L'ultimo parametro è il LocationListener, che riceve i richiami per l'aggiornamento della posizione.

Per richiedere l'aggiornamento della posizione tramite il servizio GPS, bisogna sostituire GPS_PROVIDER per NETWORK_PROVIDER. Si puo' anche richiedere la localizzazione con entrambi chiamando requestLocationUpdates() due volte, una per NETWORK_PROVIDER e l'altra per GPS_PROVIDER.

Page 29: Android Overview

Categoria D : LOCATION APIAl fine di ricevere l'aggiornamento della posizione da NETWORK_PROVIDER o GPS_PROVIDER, si deve richiedere il permesso dell'utente dichiarando il permesso ACCESS_COARSE_LOCATION o ACCESS_FINE_LOCATION rispettivamente nel file AndroidManifest.xml. Senza questi permessi, l'applicazione morirà in fase di esecuzione quando verranno richiesti gli aggiornamenti della posizione.

Per superare gli ostacoli derivanti dal voler ottenere una buona localizzazione dell'utente cercando di preservare la batteria, bisogna definire un modello coerente che specifica come l'applicazione ottiene la posizione dell'utente. Questo modello include anche quando iniziare e quando terminare con gli aggiornamenti della posizione e quando utilizzare i dati di localizzazione nella cache.

Page 30: Android Overview

Categoria D : LOCATION APISi potrebbe desiderare di iniziare ad ascoltare gli aggiornamenti di posizione non appena l'applicazione viene avviata, oppure solo dopo che l'utente attiva una certa configurazione. Bisogna essere consapevoli che lunghe finestre di ascolto per le correzione della localizzazione possono consumare molta batteria, ma periodi brevi potrebbero non consentire una sufficiente precisione.

Il tempo necessario per il LocationListener di ricevere la prima posizione è spesso troppo lungo per gli utenti che aspettano. Fino a quando non viene fornita una posizione più precisa , si dovrebbe utilizzare una posizione memorizzata nella cache chiamando il metodo getLastKnownLocation(String).

Bisogna sempre fare attenzione che l'ascolto per un lungo periodo di tempo consuma molta energia della batteria, quindi non appena si hanno le informazioni necessarie, si dovrebbe interrompere l'ascolto degli aggiornamenti della posizione chiamando il metodo removeUpdates(PendingIntent).

Page 31: Android Overview

Categoria D : LOCATION API