lezione 13

Transcript

lezione 13
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
European Master on Critical Networked Systems
Modulo su Mobile Systems
Parte III:
Sviluppo di applicazioni J2ME
Lezione 2:
Ciclo di sviluppo J2ME
Realizzazione di applicazioni MIDP
Docente: Ing. Salvatore Orlando
Dipartimento di Informatica e Sistemistica
Via Claudio 21, 80125 Napoli
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Contenuti della lezione
Application models per configurazioni CDC e CLDC
Ciclo di sviluppo di un applicazione MIDP
Sviluppo di applicazioni MIDP:
Elementi Base
LCD UI
Event Handling
Record Management System (RMS)
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Application Models
Unmanaged
Managed
www.mobilab.unina.it
Main Class
FP, PP, PBP
Applet
PP
XLet
PP, PBP
MidLet
MIDP
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Application Models: Main Class
• Entry point: public static
void main(String[] args)
• La JVM carica la classe principale ed avvia il metodo
main
• L’applicazione termina:
•
1) Invocando il metodo
•
2) Quanto tutti i suoi threads (eccetto i daemon threads) terminano
•
3) Mediante un segnale del S.O.
System.exit()
Modalità UNMANAGED:
Se l’applicazione viene terminata brutalmente dal sistema operativo, potrebbe
non aver rilasciato tutte le risorse di sistema acquisite
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Application Models: Applet
• Supportata sin dalla prima
release di Java nel 1995
public class BasicApplet
extends java.applet.Applet {
public BasicApplet() {
// constructor - don't do much here
}
public
//
//
//
}
• Gira sotto il controllo di un browser Web
• Strettamente connessa
alla pagina web in cui si trova
void init() {
applet context is ready,
perform all one-time
initialization here
public void start() {
// the applet is being displayed
}
• Applicazione managed:
il ciclo di vita di una applet è sotto il
controllo del browser web
public void stop() {
// the applet is being hidden
}
public void destroy() {
// free up all resources
}
www.mobilab.unina.it
}
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Application Models: Applet
Ciclo di Vita
Stato iniziale
(Dopo l’invocazione del
costruttore) L’applet non è
stata ancora inizializzata
I metodi start e stop
consentono di
avviare/fermare la applet
L’invocazione del metodo
init rende la applet pronta
per l’attivazione
(init può essere invocato
una sola volta nell’intero
ciclo di vita)
Nello stato STOPPED la
applet rilascia le risorse
utilizzate
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Application Models: Applet
Contesto Operativo
• Ottenere parametri della applet (specificati nella pagina web): getParameter
• Interagire mediante l’Applet Context:
• Ridimensionare la applet
• Avviare una clip audio
• Visualizzare un messaggio nella barra di stato del browser
• Aprire una nuova finestra
• Rimpiazzare la URL corrente
• Interagire con i Web Forms via DOM e Javascript
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Application Models: XLet
Managed Applications:
vengono gestite da un
software special purpose
insito nella Java Virtual
Machine
www.mobilab.unina.it
import javax.microedition.xlet.*;
public class BasicXlet implements Xlet
{
private XletContext context;
public BasicXlet() {
// constructor - don't do much here
}
public void initXlet(XletContext context)
throws XletStateChangeException {
// called by the system to
//initialize the Xlet
this.context = context;
}
public void destroyXlet(boolean unconditional)
throws XletStateChangeException {
// the system destroys the Xlet
}
public void pauseXlet() {
// the system pauses the Xlet
}
public void startXlet()
throws XletStateChangeException {
// the system activates the Xlet
}
}
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Application Models: XLet
Ciclo di Vita
La XLet può essere
distrutta in
qualsiasi istante
Stato iniziale
(Dopo l’invocazione del
costruttore) la XLet non è
stata ancora inizializzata
L’invocazione del metodo
initXLet rende la XLet
pronta per l’attivazione
(viene fornito alla XLet un
riferimento al contesto col
quale interagire)
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Application Models: XLet
Contesto Operativo
• L’interazione è regolata dall’interfaccia
javax.microedition.xlet.XletContext
• getContainer restituisce l’oggetto di interfaccia
utente principale dell’applicazione
• getXletProperty restituisce le proprietà di inizializzazione della XLet
• notifyDestroyed porta lo stato della XLet a Destroyed
• notifyPaused porta lo stato della XLet a paused
• resumeRequest richiede all’Application Management System (AMS)
di riattivare la XLet
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Application Models: MidLet
import javax.microedition.midlet.*;
• Managed Application:
viene gestita un software special
purpose (AMS – Application
Management System)
public class BasicMIDlet extends MIDlet
{
public BasicMIDlet() {
// constructor - don't do much here
}
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
// the system destroys the MIDlet
}
• L’AMS deve essere incorporato nel
dispositivo (cellulari, smartphones o
pagers): le midlet potrebbero essere
interrotte da eventi esterni (come
una telefonata)
protected void pauseApp() {
// the system pauses the MIDlet
}
protected void startApp()
throws MIDletStateChangeException {
// the system activates the MIDlet
}
}
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Application Models: MidLet
Ciclo di Vita
La MidLet è stata costruita
ed è attualmente inattiva
(si noti l’assenza
dello stato loaded)
startApp provoca
l’attivazione della Midlet.
Se questa non può
avvenire, si solleva un
eccezione e la MidLet viene
distrutta
La MidLet è terminata è
pronta per essere “riciclata”
dal Garbage Collector
La MidLet può
essere distrutta
anche nello stato
ACTIVE
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Application Models: MidLet
Contesto Operativo
• Ottenere proprieta’ di inizializzazione: getProperty
Le proprietà di inizializzazione sono contenute in un apposito descrittore
chiamato Java Application Descriptor
• Richiedere la riattivazione della MidLet: resumeRequest
La richiesta viene inoltrata all’AMS, che in seguitò decidera se e quando
riattivare la MidLet (re)invocando il metodo startApp
• Mettere in pausa la MidLet: notifyPaused
• Distruggere la MidLet: notifyDestroyed
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Ciclo di sviluppo di una MidLet
Il ciclo di sviluppo di una Applet o di una XLET è identico a quello di una
tradizionale applicazione Java
1. Compilazione – bisogna fornire il
classpath delle librerie J2ME a javac
2. Pre-Verifica – altera il classfile al
fine di allegerire il meccanismo di
verification a runtime (come richiesto
dalla configurazione CLDC)
3. Packaging – produce la MidLet
suite, costituita da un jar includente
tutti i class file e da un application
descriptor, il JAD
4.
www.mobilab.unina.it
Testing – collaudo della MidLet su di
un emulatore (generico o specifico
per una determinata classe di
dispositivi)
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Java Application Descriptor (JAD)
•Contiene le informazioni sull'applicazione, mostrate all'utente prima che si proceda con il
download e l'installazione del software
• Il JAD file fornisce all’application manager maggiori informazioni sul contenuto del JAR
file, per decidere se la MIDlet suite può essere implementata sul dispositivo
(configurazione, profilo...) e se il bytecode proviene da un dominio autorizzato ad
utilizzare certe funzionalità
• Può essere un modo per passare parametri a una MIDlet senza modificare il JAR file (un
web service, ad esempio, potrebbe inserire dinamicamente delle informazioni nel JAD)
• Il JAD file è simile al manifest file come coppie attributo-valore
• Cinque attributi sono obbligatori:
MIDlet-Name
MIDlet-Version
MIDlet-Vendor
MIDlet-n
MIDlet-Jar-URL
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Java Application Descriptor (JAD)
MIDlet-Version: 1.0.2
MIDlet-Vendor: Totore Consulting
MIDlet-Jar-URL:
http://www.mobilab.unina.it/hello.jar
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: MIDP-2.0
MIDlet-1: Demo1, /image/img1.png ,
org.mobilab.midlets.HelloWorld
MIDlet-Jar-Size: 10819
MIDlet-Name: HelloWorld
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: Elementi Base
• Ogni MidLet deve ereditare dalla classe
javax.microedition.midlet.MIDLet
• I metodi di tale classe consentono all’AMS di creare, avviare,
mettere in pausa e distruggere una MidLet.
• Una MidLet deve pertanto implementare almeno i seguenti metodi:
• void startApp()
• void pauseApp()
• void destroyApp(boolean unconditional)
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: LCD UI (1/5)
• API per la creazione di interfacce grafiche per dispositivi con display LCD
• Contenute nel package javax.microedition.lcdui
• Divise in due gruppi logici:
• Alto livello – Classi molto astratte (il rendering dipende dal particolare
dispositivo). Consentono la realizzazione di interfacce piuttosto evolute.
• Basso livello – Consentono controllo preciso sul rendering dei controlli.
Sono meno portabili. In questa lezione non ci concentremo su queste API
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: LCD UI (2/5)
Displayable e Display
• Al fine di essere visualizzato sullo schermo di un
dispositivo, un elemento deve implementare
l’interfaccia Displayable
• Le classi che implementano Displayable possono
avere un titolo, un ticker ed una serie di comandi
• La classe Display rappresenta un astrazione dello schermo di un dispositivo.
• Fornisce metodo per acquisire informazioni sullo schermo
• Visualizza un Displayable o cambia il Displayable correntemente visualizzato
mediante il metodo setCurrent(Displayable element)
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: LCD UI (3/5)
Screens
Classi che implementano l’interfaccia Displayable
• Alert
Utilizzata per visualizzare informazioni o messaggi di errore. Il titolo viene settato
esclusivamente nel costruttore, mentre il messaggio visualizzato può essere cambiato con il
metodo setString. I comandi agiscono analogamente ai pulsanti nelle message box.
• Textbox
Consente di immettere testo in una casella. Consente di impostare alcuni parametri, come il
massimo numero di caratteri. La effettiva validità dei parametri impostati dipende però anche
dalle caratteristiche dei dispositivi.
• List
Realizza una selezione tra più elementi. La selezione può essere multipla (Checkboxes),
esclusiva (RadioButtons) o implicita (Semplice Elenco)
• Form
E’ il displayable più completo (e complesso). E’ una collection di instanze di elementi di tipo
Item. Provvede delle versioni “itemizzate” anche degli elementi TextBox e List
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: LCD UI (4/5)
Forms
• Insieme di istanze di oggetti che implementano l’interfaccia
javax.microedition.lcdui.Item
• Gli elementi vengono aggiunti al form mediante il metodo append(Item item)
1° elemento – indice 0, 2° elemento – indice 1, …
• Per aggiungere gli elementi in una posizione specifica si può usare il metodo
insert(int index, Item item)
• Per rimpiazzare un elemento si può usare il metodo set(int index, Item item)
Elementi Forms
• StringItem – etichetta non modificabile
• DateField – Campo per inserire una data od un ora
• TextField – Casella di testo (analoga alla TextBox)
• ChoiceGroup – Gruppo a selezione singola/multipla
(analoga alla List)
www.mobilab.unina.it
• Spacer – elemento invisibile che aggiunge spazio tra
i controlli
• Gauge – Controllo “Barra di progresso”
• ImageItem – per inserire un immagine nel form
• CustomItem – Classe astratta. Consente la
creazione di controlli “personalizzati”
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: LCD UI (5/5)
Commands
• L’interazione tra la MidLet e l’utente avviene attraverso i comandi
• Un Comando equivale ad un pulsante o ad una voce di menu in un’applicazione “standard”
• Ad ogni Displayable possono essere agganciati dei comandi utilizzando il metodo
addCommand(Command command)
• Un Command è composto da:
• Una “short label” (obbligatoria) ed una “long label” (opzionale)
• Un tipo di comando (Es.: Command.EXIT, Command.OK) - utilizzato per il mapping con i
tasti del dispositivo
• Una priorità - utilizzata per indicare al dispositivo una priorità nella visualizzazione dei
comandi
• La MidLet può gestire l’azione connessa all’esecuzione di un comando implementando
l’interfaccia javax.microedition.lcdui.CommandLister
• bisogna implementare il metodo CommandAction(Command c, Displayable d)
c indica il comando invocato, d indica su quale elemento è stato invocato
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: Event Handling (1/3)
•
L’interazione avviene tramite Callbacks
•
Tipi di UI Callbacks in MIDP:
1.
Comandi astratti (facendi parti della UI di alto livello)
2.
Eventi di basso livello (pressioni e rilascio di tasti)
3.
Invocazioni del metodo paint della classe Canvas
4.
•
Invocazioni del metodo run di oggetti Runnable richieste attraverso una chiamata la
metodo callSerially della classe Display
In questa lezione ci occuperemo esclusivamente della gestione degli eventi di alto livello,
impiegati per:
•
Navigazione attraverso Screens (diverse istanze di Displayable)
•
Automatizzazione Forms (gestione eventi legati a singoli Items dei forms)
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: Event Handling (2/3)
Gestione eventi per Displayables
Realizzata implementando l’interfaccia CommandListener
1. Creazione del Displayable
2. Aggiunta dei comandi al Displayable
3. Impostazione del command listener per il Displayable
NB: Diversi Displayable possono condividere lo stesso CommandListener
menu = new List("Menu Items", Choice.IMPLICIT);
menu.append("Item1", null);
menu.append("Item2", null);
menu.append("Item3", null);
menu.append("Item4", null);
menu.addCommand(exitCommand);
menu.setCommandListener(this);
www.mobilab.unina.it
La classe in cui viene definito il
displayable è anche un
Command Listener.
(NB: Le istanze della classe
CommandListener devono
implementare il metodo
CommandAction)
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: Event Handling (3/3)
Gestione eventi per Forms
Realizzata implementando l’interfaccia ItemStateListener
•
Gestisce eventi relativi a cambiamenti nello stato interno dei controlli dei
forms
Variazione valore gauge bar, immissione testo in un Text field,
immissione date in Date field, selezione valore in Choice Group
•
Il listener deve implementare il metodo itemStateChanged(Item item)
•
All’atto della creazione deve essere registrato il suo listener
•
E’ compito del listener distinguere a quale degli items del form l’evento
faccia riferimento ed effettuare il casting opportuno
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: RMS (1/6)
•
La memorizzazione persistente dei dati è una caratteristica desiderabile in tutti i
dispositivi
•
In J2SE il problema viene risolto mediante JDBC, che prevede l’esistenza di
drivers (Java, parzialmente nativi, o totalmente nativi) per connettersi ad un
DBMS
•
In sistemi caratterizzati da risorse notevolmente limitate tutto ciò non è
possibile
•
J2ME per la configurazione CLDC prevede una semplice API, il Record
Management System (RMS)
•
RMS non è assolutamente un DBMS. Fornisce un semplice meccanismo per
gestire un insieme di records resi univoci mediante un ID intero incrementale
•
RMS fornisce metodi per gestire “record stores” ed inserire, aggiornare ed
eliminare records
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: RMS (2/6)
• Le API sono contenute nel package javax.microedition.rms
• Una record store è una collezione di record unicamente identificati da un ID
intero incrementale.
• Le record stores non sono assolutamente paragonabili ai database relazionali
• La rappresentazione delle record stores (files binari) è dipendente dalla
piattaforma
• I nomi delle record stores sono case sensitive e non posso superare i
32 caratteri di lunghezza
• Due record stores nella stessa Midlet suite non possono avere lo stesso nome
• Le record stores vengono memorizzate in una sottocartella dell’applicazione
chiamata NOJAM
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: RMS (3/6)
Gestione di Record Stores
Apre (e se del caso crea) una record store. Se la stessa record store è già aperta da
un’altra MidLet nella stessa suite restituisce un riferimento alla record store già aperta.
public static RecordStore openRecordStore(String recordStoreName,
boolean createIfNecessary)
throws RecordStoreException,
RecordStoreFullException,
RecordStoreNotFoundException
Elimina una record store. In caso di problemi di diritti d’accesso solleva un eccezione.
public static void deleteRecordStore(String recordStoreName)
throws RecordStoreException,
RecordStoreNotFoundException
Restituisce l’elenco dei nomi delle record stores gestite dalla MidLet suite corrente
public static String[] listRecordStores()
Restituisce il numero di records contenuti nella record store
public int getNumRecords() throws RecordStoreNotOpenException
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: RMS (4/6)
Lettura di records
•Il metodo getRecord restituisce un array di bytes contenente uno specifico record ID
•La dimensione del record può essere ottenuta mediante il metodo getRecordSize
•NB: I record non sono strutturati per campi, il parsing dell’array di byte recuperato è
lasciato all’utente
for (int i = 1; i <= recStore.getNumRecords(); i++)
{
// Allocate more storage if necessary
if (recStore.getRecordSize(i) > recData.length)
recData = new byte[recStore.getRecordSize(i)];
len = recStore.getRecord(i, recData, 0);
System.out.println("Record ID#" + i + ": " +
new String(recData, 0, len));
}
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
European Master on Critical Networked Systems
Mobilab
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: RMS (5/6)
Aggiunta/Modifica Records
1. Trasformare i dati da scrivere in array di bytes
2. Utilizzare il metodo addRecord
• Il primo parametro è l’array di bytes da scrivere
• Il secondo parametro è l’offset al quale iniziare la scrittura
• Il terzo parametro è il numero di bytes da scrivere
byte[] rec = str.getBytes();
try {
recStore.addRecord(rec, 0, rec.length);
System.out.println("Writing record: " + str);
} catch (Exception e) {
System.err.println(e.toString());
}
Per modificare records si può utilizzare il metodo setRecord
NB: E’ necessario conoscere l’ID del record da modificare
www.mobilab.unina.it
[email protected]
Mobile Systems
S. Russo
Mobilab
European Master on Critical Networked Systems
Napoli,
Maggio-Giugno 07
::. Sviluppo MIDP: RMS (6/6)
Eliminazione Records
L’eliminazione è possibile attraverso il metodo deleteRecord
NB: Anche in questo caso è necessario conoscere l’ID del record da eliminare
La classe RecordStore non fornisce alcun metodo per ottenere l’ID del record
WorkAround:
1. Ogni volta che un record viene creato
aggiungere l’ID del record ad un
opportuna struttura dati
2. Per individuare il record da
aggiornare/eliminare bisogna iterare su
tale vettore
www.mobilab.unina.it
Vector recordIDs = new Vector();
int lastID = 1;
//Add a record....parameters are missing here
db.addRecord();
// Now add the ID to the vector
recordIDs.addElement(new Integer(++lastID));
Enumeration IDs = recordIDs.elements();
while(IDs.hasMoreElements()) {
int id = ((Integer)
IDs.nextElement()).intValue();
//Compare to see if this is your record
//Then call db.deleteRecord(id);
}
[email protected]
Mobile Systems
S. Russo

Documenti analoghi

Embedded Linux

Embedded Linux • Agigungere librerie di software. 1. make menuconfig: per selezionare le librerie da aggiungere/eliminare, un altro kernel, un diverso file system…; 2. make: compila i sorgenti del kernel secondo ...

Dettagli

lezione 14

lezione 14 • Eclipse è un framework concepito per lo sviluppo di una vasta gamma di applicazioni • Il progetto Eclipse – MTJ (Mobile Tools for Java) si propone di offrire un framework completo per lo sviluppo...

Dettagli

Microsoft PowerPoint - 6_LezioneSOA_TerminaliMobili [modalit\340

Microsoft PowerPoint - 6_LezioneSOA_TerminaliMobili [modalit\340 evitare conflitti di risorse e consumo di batteria public void pauseApp() {

Dettagli

Programmazione J2ME - Gianpiero Di Blasi

Programmazione J2ME - Gianpiero Di Blasi Oltre alle limitazioni di memoria e di potenza di elaborazione, J2ME deve adattarsi anche a display particolarmente ridotti (ad esempio un piccolo telefono cellulare può disporre di 12.288 pixel, 9...

Dettagli