Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
//--------------------------------------------------------------------------------------------
//-- ARCHITETTURA ANDROID
//--------------------------------------------------------------------------------------------
/*
- Linux Kernel: fornisce i servizi di base come:
- filesystem
- gestione memoria e processi
- gestione interaccia di rete
- drivers delle periferiche
- inoltre forisce dei servizi specifici per android:
- gestione batteria
- gestione memoria condivisa
- low memory killer
- interprocess communication
- System App: applicazione già presenti nel sistema (contatti, telefono, browser...)
*/
//--------------------------------------------------------------------------------------------
--
//-- LAYOUTS: definiscono l'aspetto grafico dell'interfaccia utente
//--------------------------------------------------------------------------------------------
--
/* LINEAR LAYOUT:
- posiziona gli elementi uno dopo l'altro a seconda del verso scelto:
android:orientation="vertical" oppure android:orientation="horizontal"
- Inoltre è possibile dividere in parti uguali lo spazio del layout tra i figli, inserendo
nei figli: android:layout_height="0dp"
android:layout_weight="1” per lo spazio verticale
oppure
android:layout_width="0dp"
android:layout_weight="1” per lo spazio orizzontale.
*/
/* RELATIVE LAYOUT
- android:layout_alignParentTop=”true"
– android:layout_centerVertical=”true"
– android:layout_below=”@id/other_object"
– android:layout_toRightOf=”@id/other_object”
//--------------------------------------------------------------------------------------------
--
//-- MISURE
//--------------------------------------------------------------------------------------------
--
/*
- px: pixel reali
- dp: density indipendent pixels (dip), in cui la dimensione è calcolata in base alla
densità
del display (rapporto tra dimensione e risoluzione del display)
i dp permettono di ottenere widget con dimensioni simile anche con display a
diverse risoluzioni
- mm: millimetri
- in: inches
*/
/*--------------------------------------------------------------------------------------------
--
-- LIST VIEW
----------------------------------------------------------------------------------------------
- ListView è un widget, bisogna inserirlo nel file xml di layout e collegarlo ad una
data source.
- è specifico per creare liste di elementi
- bisogna specificare il layout (xml) per il singolo elemento della lista
- la lista, di default, supporta lo scrolling.
*/
/* setta l'adapter al ListView, automaticamente ogni elemento del dataSource sarà un elemento
della listView
*/
listView.setAdapter(adapter)
/* bisogna aggiungere un OnItemClickListener al ListView per far in modo che ogni elemento sia
cliccabile, inoltre nel onItemClick si può definire il comportamento al click di un item.
Il listener è applicato all intero item, non è possibile quindi differenziare le varie
parti
che compongono un item.
*/
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
/* se l'item della lista è composto da più parti che richiedono un click singolo, bisogna
NON aggiungere un OnItemClickListener, ma aggiungere degli onClick (nel layout
dell'elemento della lista)
poi nell singolo onClick è possibile ottenere l'elemento con adapter.getItem(index) se si
ha un riferimento ad
adapter.
*/
//costrutture
public CustomAdapter(Context context, ...) {
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null)
view = inflater.inflate(R.layout.list_element, null);
codice();
return view;
}
}
/* SCROLL VIEW
Una view che permette lo scrolling di ciò che contiene. Una ScrollView dovrebbe avere un
solo figlio all'interno
(es: LinearLayout, FrameLayout..) e supporta solo lo scrolling verticale. Usare
HorizontalScrollView per
lo scrolling orizzontale.
Se la dimensione verticale della scroll view è pari a meta dello schermo impostare:
android:fillViewport="true"
*/
//--------------------------------------------------------------------------------------------
--
//-- GRID VIEW:
//--------------------------------------------------------------------------------------------
--
//un grid view permette di visualizzare elementi in una griglia (scegliendo solo il numero
di colonne)
//bisogna usare un adapter per inserire gli elementi
/* attributi specifici:
- android:columnWidth="45dp"
- android:horizontalSpacing="3dp"
- android:numColumns="3"
- android:stretchMode="columnWidth" //spacingWidth, spacingWidthUniform
- android:verticalSpacing="3dp">
/*--------------------------------------------------------------------------------------------
--
-- BUTTON ONCLICK PROGRAMMATICO
----------------------------------------------------------------------------------------------
*/
//implementare nella classe corrente: View.OnClickListener oppure creare una nuova classe
interna
//code...
}
//oppure
button.setOnClickListener( new View.OnClickListener() {
@Override
public void onCLick(View view) {
//stuff...
}
} )
//--------------------------------------------------------------------------------------------
--
//-- EDIT TEXT
//--------------------------------------------------------------------------------------------
--
// nel file di layout, inserire:
android:inputType="xxx" //per specificare il tipo di input (es: text, passoword...)
// disabilitare edit text per renderlo non cliccabile e modificabile
android:clickable="false"
android:cursorVisible="false"
android:focusable="false"
android:focusableInTouchMode="false"
//VISIBILITà
//COLORE/BACKGROUND TRASPARENTE
android:backgroundTint="@android:color/transparent"
//--------------------------------------------------------------------------------------------
--
//-- IMAGE VIEW
//--------------------------------------------------------------------------------------------
--
// settare il il contenuto dell'imageView
android:src="id or @drawable/some_id"
//usare @drawable/ per i contenuti di default
/*--------------------------------------------------------------------------------------------
--
-- LAYOUT PROGRAMMATICO (creare/aggiungere widget ad un layout programmaticamente!)
--
-- definire un layout (es: GridLayout) in un file di layout, dopo, da codice sarranno settate
-- le proprietà al layout ed aggiunti elementi al layout
----------------------------------------------------------------------------------------------
*/
//--------------------------------------------------------------------------------------------
--
//-- ACTIVITY LIFE CYCLE
//--------------------------------------------------------------------------------------------
--
/*
• Attività non esiste
1. onCreate() -> activity creata dal sistema
2. onStart() -> avviata e resa visibile
3. onResume() -> ripresa (dopo la onResume l'activity è visibile e interattiva)
• Attività in esecuzione
4. onPause() -> activity va in foreground (parzialmente visibile)
5. onStop() -> quando l'attività non è più visibile
6. onDestroy() -> activity terminata o distrutta dal sistema
• Stati:
- Created: causato da onCreate()
- Started(visible): causato da onStart(), oppure onRestart() + onStart()
- Resumed(visible): causato da onResume()
- Paused(parzialmente visibile): causato da onPause()
- Stopped(hidden): causato da onStop()
- Destroyed(rimossa dalla memoria): causato da onDestroy()
• Passaggi di stato:
- Created -> Started: causato da onStart()
- Started -> Resumed: causato da onResume()
- Resumed -> Paused: causato da onPause()
- Paused -> Resumed: causato da onResume()
- Paused -> Stopped: causato da onStop()
- Stopped -> Started: causato da onRestart() + onStart()
- Stopped -> Destroyed: causato da onDestroy()
*/
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
// Lo si recupera in onCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
L'azione di premere il tasto back scatena il pop dell'ultima activity inserita nel
back-stack, premendo ulteriormente si estraggono tutte le varie activity fino a quando
si ritorna alla home screen del launcher, a questo punto il task è vuoto ed è eliminato.
Nel back-stack possono essere aggiunti anche le transazioni ai fragment, fare back
vuol dire annullare l'effetto della transazione eseguita.
*/
//--------------------------------------------------------------------------------------------
--
//-- INTENT
//--------------------------------------------------------------------------------------------
--
/*
Gli intent sono degli oggetti che mandano messaggi, racchiudono una azione e dei dati.
Possono essere di due tipi:
- intent espliciti: quando si conosce la componente, spesso usati all'interno della
propria app
- intent impliciti: usati quando non si conosce il nome completo della componente,
basta
specificare l'azione e i dati poi l'intent sarà inviato al sistema android che si
occupererà di risolvere l'intent e di trovare il componente adatto per esso. In
pratica
il sistema visiona il manifest delle varie applicazioni installate, nel manifest
cerca
per il tipo corretto di intent-filter.
//intent che mostra l'app di default per le mappe, con l'indirizzo inserito
[Uri.parse("geo:0,0?q=" + address)]
Intent geoIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=" +
address));
//lancia l'intent e fornisce il risultato dell' intent alla activity che lo ha lanciato.
startActivityForResult(intent, REQUEST_CODE); //REQUEST_CODE è un intero (1)
// INTENT COMPONENT: permette di specificare l'attività target (usare solo quando il target
è unico)
intent.setComponent();
intent.setClass();
intent.setClassName();
/*--------------------------------------------------------------------------------------------
---
//-- INTENT-FILTERS
//--------------------------------------------------------------------------------------------
---
Sono specificati nel manifest, in particolare ogni attività può specificare un
intent-filter,
questi indicano quali tipi di intent impliciti possono essere ricevuti dall'activity. Se
nessun intent implicito è specificato allora l'activity accetterà solo intent espliciti.
<category> contiene informazioni aggiuntive riguardo al tipo di componente che può gestire
l'intent.
- CATEGORY_BROWSABLE: l'activity target consente di essere avviata da un web-browser.
- CATEGORY_LAUNCHER: l'activity è quella iniziale, mostrata nel launcher di sistema.
Il sistema android, leggendo queste componenti, può decidere quale componente avviare per
risolvere l'intent.
//--------------------------------------------------------------------------------------------
--
//-- PERMESSI
//--------------------------------------------------------------------------------------------
--
/* per proteggere risorse e dati e limtare l'accesso a:
- informazioni dell'utente (contatti...)
- servizi con costi (sms, chiamate, accesso a intenet...)
- risorse di sistema (camera, gps..)
if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
// Permission is granted
} else {
//Permission negated
}
}
}
//--------------------------------------------------------------------------------------------
--
//-- DISPLAY
//--------------------------------------------------------------------------------------------
--
Display display -> contiene informazioni sulla grandezza e densità del display logico
che rappresenta.
*/
/*
display.getSize(Point) -> serve ad ottenere le dimensioni reali in pixel del display,
il metodo inserisce i valori di width ed height in un oggetto Point, richiamabili tramite
le proprietà di x e y di Point.
*/
// oppure:
view.getLayoutParams().width = width;
//--------------------------------------------------------------------------------------------
--
//-- DATA STORAGE
//--------------------------------------------------------------------------------------------
--
//oppure: quando si vogliono usare più file, bisogna ottenere la SharedPreferences del file
specificato
SharedPreferences prefs = PreferenceManager.getSharedPreferences(filename);
//al termine bisogna effettuare il commit per scrivere i valori (altrimenti non saranno
salvati)
editor.commit();
//-- FILE: possono essere privati dell'app o pubblici (accessibili da altre app)
//--------------------------------------------------------------------------------------------
--
//per ogni app il android prevede una directory privata in cui solo l'app può accedervi.
//permessi neccessari:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
return Environment.MEDIA_MOUNTED.equals(state);
}
//controlla se lo storage primario (esterno) è leggibile
public boolean isExternalStorageReadable() {
return (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state));
}
//Data Directory
String path = Environment.getDataDirectory().toString();
//mode:
Context.MODE_PRIVATE //file accessibile solo all'app (file privato)
Context.MODE_APPEND //permette l'append del file
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_CMD); //esegue una query per creare la tabella
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// non serve in questo esempio, ma deve esserci
}
//struttura tabella
public static abstract class Table implements BaseColumns {
public static final String TABLE_NAME = "studenti";
public static final String COLUMN_NAME = "nome";
public static final String COLUMN_VOTO = "voto";
}
}
// Eseguiamo la query
Cursor cursor = db.query(
SchemaDB.Tavola.TABLE_NAME, // The table to query
projection, // The columns to return
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
return cursor;
}
Cursor cursorSelected = readSelectedEntries();
getApplicationContext(), //context
R.layout.list_layout, //Layout della lista
cursorSelected, //Il cursore con i dati del database
DatabaseOpenHelper.columns, // String[] con i nomi delle colonne database
new int[]{R.id._id, R.id.name, R.id.voto}, //id dei campi nel layout
0 //flags
);
/*--------------------------------------------------------------------------------------------
--
-- BITMAP
----------------------------------------------------------------------------------------------
*/
ImageView imageView;
Bitmap bmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
imageView.setImageBitmap(bmap);
/*
BitmapFactory è una classe che permette di creare un oggetto Bitmap
a partire da varie fonti quali: file, stream o array di byte.
//--------------------------------------------------------------------------------------------
--
//-- THREAD E ASYNCTASK
//--------------------------------------------------------------------------------------------
--
//-- THREAD: hanno un proprio program counter e stack ma condividono heap e memoria statica
//--------------------------------------------------------------------------------------------
--
/* i thread creati non possono modificare l'interfaccia grafica dell applicazione, solo il
solo il MainThread può farlo.
@Override
public void run() {
imageView.setImageBitmap(bmap);
}
});
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bmap);
}
});
quando un task asincrono è eseguito, il task esegue 4 step (in pratica sono metodi da
implementare):
1.onPreExecute() -> è eseguito nel UI Thread (MainThread) prima che il task sia eseguito,
è utilizzato per eseguire codice di startup.
//AsyncTask che carica un immagine e utilizza una progress bar per mostrare l'avanzamento
del caricamento
class LoadImageTask extends AsyncTask<Integer, Integer, Bitmap> {
private Integer index = 1;
// Load bitmap
Bitmap tmp = BitmapFactory.decodeResource(getResources(), img_ids[0]);
/* Simuliamo il ritardo */
for (int i = 1; i < 11; i++) {
sleep(500);
publishProgress(i * 10);
}
return tmp;
}
/*--------------------------------------------------------------------------------------------
--
-- FRAGMENTS
----------------------------------------------------------------------------------------------
-
Un fragment rappresenta una porzione dell interfaccia utente. E' possibile combinare più
fragments
in una singola activity. Ogni fragment ha un ciclo di vita (simile a quello dell activity) che
dipende dal ciclo di vita dell' activity. Un fragment deve avere il proprio layout e deve
essere
ospitato in una activity (risiederà in un ViewGroup).
I fragment possono essere aggiunti/rimossi durante l'esecuzione. Combinare fragment è utile
quando
abbiamo un device con un ampio schermo (interfacce utente dinamiche).
I fragment possono essere riutilizati in più activity.
*/
/*
viene impostato il layout del fragment,
applicando il layout specificato in xml (id)
*/
return inflater.inflate(R.layout.myFragment, container, false);
}
}
/* OPPURE DINAMICAMENTE*/
/* METODI UTILI */
//rimuove il fragment
fragmentTransaction.remove(fragment)
/* aggiunge il fragment al backStack quando sarà premuto back (mostrerà ciò che
precedeva il fragment ).
Il back-stack considera solo le activity, se si vogliono considerare
anche i fragmentes bisogna aggiungerli manualmente, altrimenti quando
si preme back sarà mostrata l'activity che precedeva il fragment omettendo
i cambiamenti nell ui effettuati dai fragment.
/* ListFragment
E' un fragment che mostra una lista di items (legata a dei dati: array),
inoltre fornisce un handler utile quando l'utente seleziona un item della lista.
ListFragment opsita un ListView che può essere associato a diverse data sources e ne
eredita il comportamento (item layout, adapter...)
*/
/* DETACH:
Scollega (detach) il frammento dato dalla UI. Il Frammento va in uno stato simile a
quando va nello back-stack,
ma il fragment è ancora attivamente gestito dal FragmentManager. Quando viene
effettuato il detach sul
fragment la sua gerarchia di view è eliminata.
Ciò vuol dire che la detach provoca solo la distruzione della view del fragment,
mentre il suo stato
continua ad essere gestito dal fragment manager.
REMOVE:
Rimuove un frammento esistente, se era aggiunto ad un container sarò rimossa anche la
sua view.
Inoltre il suo stato sarà rimosso dal FragmentManager.
ATTACH:
Effettua il re-attch del fragment di cui è stato fatto il detach in precedenza. Ciò
causa la
ri-creazione della sua view hierarchy che sarà collegata alla UI e mostrata solo le
il fragment
è stato aggiunto ad un container. Inoltre lo stato del fragment sarà gestio dal
FragmentManager.
*/
//----------------------------------------------------------------------------------------
--
//classe fragment che definisce un interfaccia:
class FragmentA extends Fragment {
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
} catch (ClassCastException e) {
//interfaccia di comunicazione
public interface CallbackListener {
}
}
/*--------------------------------------------------------------------------------------------
--
-- NETWORKING
----------------------------------------------------------------------------------------------
-*/
//aggiungere al manifest.xml i permessi per l'accesso ad internet
//<uses-permission android:name="android.permission.INTERNET" />
//cè connessione!
}
try {
} catch (IOException e) {
e.printStackTrace()
}
/* SOCKET:
conviene estendere AsyncTask per create un task asincrono
specifico per inviare i dati in rete
*/
class NetworkTask extends AsyncTask<Integer, Integer, String> {
@Override
protected void onPreExecute() {
@Override
protected String doInBackground(Integer...values) {
//connessione:
try {
} catch (Exception e) {
e.printStackTrace();
return null;
}
if (socket == null)
return null; //connessione non stabilita
} catch (Exception e) {
e.printStackTrace();
}
//lettura della prima linea dei dati ricevuti, per controllare se ci sono dati
String line;
if ((line = in.readLine()) == null) {
Log.d(TAG,"Errore");
}
received_data += (char) c;
} catch (Exception e) {
e.printStackTrace();
}
return received_data;
}
@Override
protected void onProgressUpdate(Integer... values) {
/*--------------------------------------------------------------------------------------------
--
-- JSOUP: libreria per il parsing delle pagine html
----------------------------------------------------------------------------------------------
-*/
//recupera la pagine web, l'oggetto document rappresenta il DOM della pagina
Document doc = Jsoup.connect(url).get();
/*--------------------------------------------------------------------------------------------
--
//-- GRAFICA, ANIMAZIONI E CUSTOM WIDGETS
//--------------------------------------------------------------------------------------------
---
Un’immagine può essere disegnata in
– un oggetto View
• grafica semplice, senza necessità di cambiamenti
– un oggeto Canvas
• grafica complessa, aggiornamenti frequenti
@Override
public void run() {
imageView.setAlpha(0); //nasconde l'immagine
}
@Override
public void onAnimationStart(Animation animation) {
//inizio dell'animazione
}
@Override
public void onAnimationRepeat(Animation animation) {
//ripetizione dell'animazione
}
@Override
public void onAnimationEnd(Animation animation) {
//fine dell'animazione
}
});
/*
//-- CUSTOM WIDGETS: oltre ai widget offerti da android è possibile crearne di propri
LinearLayout
|
--------------------------------
| | | |
ImageView Frame EditText LinearLayout
| |
RelativeLayout -----------
| | |
------------- Button Button
| |
Button ImageView
private float x;
private float y;
x = x0;
y = y0;
setMinimumWidth(WIDTH);
setMinimumHeight(HEIGHT);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//per mostrarlo bisogna aggiungerlo ad una view container altrimenti non sarà eseguito
l'onDraw()
viewContainer.addView(nota); //viewContainer come: Frame, Linerar, Relative, Grid Layout...
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
return true;
}
});
/*--------------------------------------------------------------------------------------------
--
-- MULTI-TOUCH
----------------------------------------------------------------------------------------------
-
• MotionEvent: rappresenta un movimento registrato da una periferica (mouse, dita,
trackball...)
• Il movimento è rappresentato con:
- ACTION_CODE: codice cambiamento avvenuto
- ACTION_VALUES: Posizione e proprietà del movimento (tempo, sorgente, pressione...)
• MotionEvents ACTION_CODES:
– ACTION_DOWN: un dito tocca lo schermo ed è il primo
– ACTION_POINTER_DOWN: un dito tocca lo schermo ma non è il primo
– ACTION_MOVE: un dito che è sullo schermo si muove
– ACTION_POINTER_UP: un dito che è sullo schermo non lo tocca più
– ACTION_UP: l’ultimo dito sullo schermo viene alzato
*/
// Metodi di MotionEvent:
//Esempio:
view.setOnTouchListener(new OnTouchListener() {
//il metodo onTouch è chiamato prima che la view sia notificata dell'evento
@Override
public boolean onTouch(View v, MotionEvent event) {
int pointerIndex;
int pointerID;
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
pointerIndex = event.getActionIndex();
pointerID = event.getPointerId(pointerIndex);
//code
break;
//ecc...
}
return true; //true indica che l'evento è stato consumato, false altrimenti
}
});
/*--------------------------------------------------------------------------------------------
--
//-- GESTURE DETECTOR: permette di riconoscere le gesture
//--------------------------------------------------------------------------------------------
---
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velX, float velY) {
//do something
if (Math.abs(e1.getX() - e2.getX()) > X_OFFSET && velX > VEL_OFFSET)
return true; //evento consumato
/*--------------------------------------------------------------------------------------------
---
//-- VIEW ANIMATOR E VIEW FLIPPER
//--------------------------------------------------------------------------------------------
---
• ViewAnimator:
- è un view container di base (agisce come un Framelayout)
- può eseguire animazioni quando si passa da una view all'altra.
• ViewFlipper:
- sottoclasse di ViewAnimator
- crea animazioni tra due o più view contenute all'interno
- solo un figlio (view) per volta è visualizzato
- può anche cambiare view (tra le view figlie) ad intervalli regolari.
/*--------------------------------------------------------------------------------------------
---
//-- MUSIC PLAYER
//--------------------------------------------------------------------------------------------
---
• AudioManager: controlla le sorgenti audio
- gestisce il volume
- è ottenuto tramite: Context.getSystemService(Context.AUDIO_SERVICE)
• Sorgente dati
– Risorse locali
– URI (interni)
– URL
• Audio Focus: il canale di output è unico, l'audio focus permette di gestire l'accesso
contemporaneo, in quanto:
- una app richiede l'audio focus per usare l'audio
- se lo perde deve smettere di suonare o abbassare il proprio volume.
*/
//avvia il brano
public void play() {
if (player != null)
player.start();
}
if (player != null)
{
player.stop(); //ferma la musica
player.release(); //rilascia le risorse
if (player != null)
player.pause();
}
@Override
public void onCompletion(MediaPlayer arg0) {
//do something..
}
} );
/*--------------------------------------------------------------------------------------------
---
//-- SENSORI
//--------------------------------------------------------------------------------------------
---
• SensorManager:
- permette di capire quali sensori sono disponibili
- fornisce le caratterstiche del singolo sensore (range, accuratezza...)
- permette di leggere i dati grezzi del sensore
- permette di usare listener sui cambiamenti dei dati
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@Override
protected void onResume() {
super.onResume();
@Override
protected void onPause() {
super.onPause();
//metodo richiamato ogni qual volta si verifica un evento che riguarda i sensori
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
/*--------------------------------------------------------------------------------------------
---
//-- NOTIFICHE: permettono di informare l'utente al di fuori dell'interfaccia grafica dell'app
//--------------------------------------------------------------------------------------------
---
• Ne sono un esempio:
- Toast
- Dialog
- Notification Area (notifiche che compaiono nella status bar)
*/
//-- Dialog: sono dei messaggi in cui possono esserci anche bottoni
public void showDialog(View v) {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which)
{
case DialogInterface.BUTTON_POSITIVE:
case DialogInterface.BUTTON_NEGATIVE:
//-- Notifiche:
public void showNotification(View v) {
//costruisce la notifica
Notification.Builder notificationBuilder = new
Notification.Builder(getApplicationContext())
.setTicker("Messaggio breve")
.setSmallIcon(R.drawable.icon) //icona
.setAutoCancel(true)
.setContentTitle("Titolo notifica")
.setContentText("Testo della notifica")
;
/*--------------------------------------------------------------------------------------------
---
//-- ALARMS: permettono di eseguire intent in funzione di specifici eventi
//--------------------------------------------------------------------------------------------
---
• Un app che usa un alarm può eseguire del codice anche se l'aplicazione è terminata
• Un alarm è attivo anche se il telefono va in modalità sleep:
- l'alarm può causare la ripresa dell'attività
- oppure potrà essere gestito quando il telefono ritornerà in modalità normale
• Esempi di alarm:
- controllo periodico dei messaggi non spediti
- rendere la periferica non visibile (bluetooth) dopo un certo periodo
*/
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
//creare un alarm
alarmManager.set(int type, long triggerAtTime, PendingIntent i);
alarmManager.setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent
i);
/*--------------------------------------------------------------------------------------------
---
//-- BROADCASTS
//--------------------------------------------------------------------------------------------
---
• Spedire i messaggi:
- sendBroadcast(Intent i): disponibile in LocalBroadcastManager e Context
- sendBroadcast(Intent i, String permission): disponibile sono in Context, inoltre
verrà consegnato solo ai receiver che hanno il permesso (dichiarato dall'app nel
manifest)
*/
//classe receiver:
public class Receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//nell'activity:
sendBroadcast( new Intent("my.app.BROADCAST_CODE") ); //invia il broadcast
@Override
public void onReceive(Context context, Intent intent) {
//cancella il receiver
unregisterReceiver(receiver);
//eventi globali:
Intent.ACTION_TIME_TICK
Intent.AIRPLANE_MODE
Intent.BATTERY_LOW
Intent.DATA_SMS_RECEIVED
Intent.DATE_CHANGED
Intent.DEVICE_STORAGE_LOW
Intent.TIMEZONE_CHANGED
Intent.USER_PRESENT
Intent.WALLPAPER_CHANGED
/*--------------------------------------------------------------------------------------------
---
//-- CONTENT PROVIDERS
//--------------------------------------------------------------------------------------------
---
• Funzionamento:
- Un ContentResolver è utilizzato (nel contesto dell'app) per comunicare con il
provider
(oggetto instanza di una classe che implementa ContentProvider).
- L'oggetto Provider riceve le richieste di dati dai clients, effettua la richiesta e
ritorna il risutato.
- Bisogna implementare un proprio provider se si è interessati a condividere dati con
altre applicazioni (o per fornire suggerimenti di ricerca custom, o per copiare e
incollare dati complessi dalla propria applicazione ad un altra).
• ContentProvider standard:
- Browser (info su bookmarks, history)
- Call Log (info sulle chiamate)
- Contact (info sui contatti presenti in rubrica)
- Media (lista dei file multimediali utilizzabili)
- UserDictionary (lista delle parola digitate)
- ec..
/*--------------------------------------------------------------------------------------------
---
//-- SERVICES
//--------------------------------------------------------------------------------------------
---
• Le componenti che vogliono interagire con un service devono effetturare un bind con
esso:
- Context.bindService(Intent service, ServiceConnection conn, int flags);
- il binding permette di inviare richieste e ricevere risposte.
- se al momento della richiesta il bind service non è ancora attivo allora:
- viene fatto partire,
- e rimane attivo fino a quando c'è almeno un client connesso.
<service
android:name="my_service"
android:label="my service label" />
</application>
*/
//Esempio service:
@Override
public void onCreate() {
super.onCreate();
//onCreate code
}
//code..
//rilasciare le risorse
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
//fermare un service
Service.stopSelf();
//client:
public class Client extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//avvia il servizio
startService(serviceIntent);
}
//ferma il servizio
stopService(serviceIntent);
}
/*--------------------------------------------------------------------------------------------
--
-- CONTATTI
----------------------------------------------------------------------------------------------
-*/
// inserire nel manifest i permessi per leggere i contatti
<uses-permission android:name="android.permission.READ_CONTACTS" />
//--------------------------------------------------------------------------------------------
---
//-- RESOURCES
//--------------------------------------------------------------------------------------------
---
//--------------------------------------------------------------------------------------------
---
//-- HANDLER: eseguire del codice DOPO UN CERTO DELAY
//--------------------------------------------------------------------------------------------
---
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {