API per Android 4.0

Livello API: 14

Android 4.0 (ICE_CREAM_SANDWICH) è una release principale della piattaforma che aggiunge una serie di nuove funzionalità per utenti e sviluppatori di app. Oltre a tutte le nuove funzionalità e API illustrate di seguito, Android 4.0 è una release della piattaforma importante, perché porta l'ampio set di API e temi olografici di Android 3.x su schermi più piccoli. In qualità di sviluppatore di app, ora disponi di un'unica piattaforma e di un framework API unificato che ti consente di sviluppare e pubblicare la tua applicazione con un unico APK che offre un'esperienza utente ottimizzata per smartphone, tablet e altri dispositivi quando esegui la stessa versione di Android: Android 4.0 (livello API 14) o versioni successive.

Per gli sviluppatori, la piattaforma Android 4.0 è disponibile come componente scaricabile per l'SDK Android. La piattaforma scaricabile include una libreria Android e un'immagine di sistema, oltre a una serie di skin di emulatori e altro ancora. Per iniziare a sviluppare o testare versioni su Android 4.0, utilizza Android SDK Manager per scaricare la piattaforma nel tuo SDK.

Panoramica dell'API

Le sezioni che seguono forniscono una panoramica tecnica delle nuove API in Android 4.0.

API social nel provider di contatti

Le API di contatto definite dal provider ContactsContract sono state estese per supportare nuove funzionalità orientate ai social, come un profilo personale per il proprietario del dispositivo e la possibilità per gli utenti di invitare singoli contatti ai social network installati sul dispositivo.

Profilo utente

Android ora include un profilo personale che rappresenta il proprietario del dispositivo, come definito dalla tabella ContactsContract.Profile. Le app social che mantengono l'identità dell'utente possono contribuire ai dati del profilo dell'utente creando una nuova voce ContactsContract.RawContacts all'interno di ContactsContract.Profile. Ciò significa che i contatti non elaborati che rappresentano l'utente del dispositivo non appartengono alla tradizionale tabella dei contatti non elaborati definita dall'URI ContactsContract.RawContacts; devi invece aggiungere un contatto non elaborato del profilo nella tabella all'indirizzo CONTENT_RAW_CONTACTS_URI. I contatti non elaborati in questa tabella vengono poi aggregati nel singolo profilo visibile all'utente denominato "Io".

L'aggiunta di un nuovo contatto non elaborato per il profilo richiede l'autorizzazione android.Manifest.permission#WRITE_PROFILE. Analogamente, per leggere dalla tabella dei profili, devi richiedere l'autorizzazione android.Manifest.permission#READ_PROFILE. Tuttavia, per la maggior parte delle app non dovrebbe essere necessario leggere il profilo utente, anche quando contribuiscono dati al profilo. La lettura del profilo utente è un'autorizzazione sensibile e gli utenti dovrebbero essere scettici nei confronti delle app che la richiedono.

Intenzione di invito

L'azione intent INVITE_CONTACT consente a un'app di richiamare un'azione che indica che l'utente vuole aggiungere un contatto a un social network. L'app che riceve l'app la utilizza per invitare il contatto specificato nel social network. La maggior parte delle app sarà alla ricezione di questa operazione. Ad esempio, l'app Persone integrata richiama l'intent di invito quando l'utente seleziona "Aggiungi connessione" per una specifica app social elencata nei dettagli di contatto di una persona.

Per rendere visibile l'app nell'elenco "Aggiungi connessione", l'app deve fornire un adattatore di sincronizzazione per sincronizzare le informazioni di contatto dal social network. Devi quindi indicare al sistema che la tua app risponde all'intent INVITE_CONTACT aggiungendo l'attributo inviteContactActivity al file di configurazione della sincronizzazione dell'app, con un nome completo dell'attività che il sistema dovrebbe iniziare quando invia l'intent di invito. L'attività che inizia può quindi recuperare l'URI del contatto in questione dai dati dell'intent ed eseguire il lavoro necessario per invitare il contatto alla rete o per aggiungere la persona alle connessioni dell'utente.

Foto grandi

Android ora supporta le foto ad alta risoluzione per i contatti. Ora, quando esegui il push di una foto in un record di contatti, il sistema la elabora sia in una miniatura 96 x 96 (come in precedenza) sia in una "foto display" 256 x 256 archiviata in un nuovo archivio di foto basato su file (le dimensioni esatte scelte dal sistema possono variare in futuro). Puoi aggiungere una foto di grandi dimensioni a un contatto inserendo una foto di grandi dimensioni nella consueta colonna PHOTO di una riga di dati, che il sistema elaborerà poi nella miniatura appropriata e mostrerà i record fotografici.

Feedback sull'utilizzo dei contatti

Le nuove API ContactsContract.DataUsageFeedback consentono di tenere traccia della frequenza con cui l'utente utilizza determinati metodi per contattare le persone, ad esempio la frequenza con cui l'utente utilizza ogni numero di telefono o indirizzo email. Queste informazioni aiutano a migliorare il ranking di ogni metodo di contatto associato a ogni persona e forniscono suggerimenti migliori per contattare ogni persona.

Fornitore di calendari

Le nuove API di calendario consentono di leggere, aggiungere, modificare ed eliminare calendari, eventi, partecipanti, promemoria e avvisi, che sono archiviati nel provider di calendari.

Queste API possono essere utilizzate da diverse app e widget per leggere e modificare gli eventi di calendario. Tuttavia, alcuni dei casi d'uso più interessanti sono gli adattatori di sincronizzazione che sincronizzano il calendario dell'utente da altri servizi di calendario con il provider di calendari, al fine di offrire una posizione unificata per tutti gli eventi dell'utente. Gli eventi di Google Calendar, ad esempio, vengono sincronizzati con il fornitore di calendari tramite l'adattatore di sincronizzazione di Google Calendar, in modo da poterli visualizzare con l'app di calendario integrata di Android.

Il modello dei dati per i calendari e le informazioni relative agli eventi nel fornitore di calendari è definito da CalendarContract. Tutti i dati del calendario dell'utente sono archiviati in una serie di tabelle definite da varie sottoclassi di CalendarContract:

  • La tabella CalendarContract.Calendars contiene le informazioni specifiche del calendario. Ogni riga di questa tabella contiene i dettagli di un singolo calendario, come nome, colore, informazioni di sincronizzazione e così via.
  • La tabella CalendarContract.Events contiene informazioni specifiche sugli eventi. Ogni riga di questa tabella contiene le informazioni relative a un singolo evento, come il titolo, la località, l'ora di inizio, l'ora di fine e così via. L'evento può verificarsi una sola volta o più volte. I partecipanti, i promemoria e le proprietà estese vengono archiviati in tabelle separate e utilizzano il _ID dell'evento per collegarli all'evento.
  • La tabella CalendarContract.Instances contiene l'ora di inizio e di fine delle occorrenze di un evento. Ogni riga di questa tabella rappresenta una singola occorrenza. Per gli eventi singoli, è disponibile una mappatura one-to-one delle istanze e degli eventi. Per gli eventi ricorrenti, vengono generate automaticamente più righe per corrispondere alle occorrenze multiple dell'evento.
  • La tabella CalendarContract.Attendees contiene le informazioni sul partecipante o sull'invitato all'evento. Ogni riga rappresenta un singolo invitato a un evento. Specifica il tipo di invitato e la sua risposta all'evento.
  • La tabella CalendarContract.Reminders contiene i dati dell'avviso/delle notifiche. Ogni riga rappresenta un singolo avviso per un evento. Un evento può avere più promemoria. Il numero di promemoria per evento è specificato nel campo MAX_REMINDERS, che viene impostato dall'adattatore di sincronizzazione proprietario del calendario in questione. I promemoria vengono specificati in minuti prima della programmazione dell'evento e specificano un metodo di allarme, ad esempio un avviso, un'email o un SMS per ricordare all'utente.
  • La tabella CalendarContract.ExtendedProperties contiene campi di dati opachi utilizzati dall'adattatore di sincronizzazione. Il provider non intraprende alcuna azione sugli elementi di questa tabella, tranne per eliminarli quando vengono eliminati i relativi eventi correlati.

Per accedere ai dati del calendario di un utente con il fornitore di calendari, la tua applicazione deve richiedere l'autorizzazione READ_CALENDAR (per l'accesso in lettura) e WRITE_CALENDAR (per l'accesso in scrittura).

Intenzione dell'evento

Se vuoi solo aggiungere un evento al calendario dell'utente, puoi utilizzare un intent ACTION_INSERT con i dati definiti da Events.CONTENT_URI per avviare un'attività nell'app Calendar che crea nuovi eventi. L'utilizzo dell'intent non richiede alcuna autorizzazione e puoi specificare i dettagli dell'evento con i seguenti extra:

Provider di messaggi vocali

Il nuovo provider di segreteria consente alle applicazioni di aggiungere messaggi vocali al dispositivo, in modo da presentare tutti i messaggi vocali dell'utente in un'unica presentazione visiva. Ad esempio, è possibile che un utente abbia più sorgenti di segreteria, ad esempio una del fornitore di servizi del telefono e un'altra del VoIP o di altri servizi vocali alternativi. Queste app possono utilizzare le API del provider di messaggi vocali per aggiungere i messaggi vocali al dispositivo. L'applicazione Telefono integrata presenta quindi tutti i messaggi vocali all'utente in una presentazione unificata. Sebbene l'applicazione Telefono del sistema sia l'unica in grado di leggere tutti i messaggi vocali, ogni applicazione che fornisce messaggi vocali può leggere quelli aggiunti al sistema (ma non può leggere quelli di altri servizi).

Poiché le API attualmente non consentono alle app di terze parti di leggere tutti i messaggi vocali del sistema, le uniche app di terze parti che dovrebbero utilizzare le API Messaggio vocale sono quelle che dispongono di messaggi vocali per recapitare all'utente.

La classe VoicemailContract definisce il fornitore di contenuti per il provder di segreteria. Le sottoclassi VoicemailContract.Voicemails e VoicemailContract.Status forniscono tabelle in cui le app possono inserire i dati dei messaggi vocali per l'archiviazione sul dispositivo. Per un esempio di app del fornitore di messaggi vocali, vedi la demo per il fornitore di messaggi vocali.

Multimediale

Android 4.0 aggiunge diverse nuove API per le applicazioni che interagiscono con contenuti multimediali come foto, video e musica.

Effetti multimediali

Un nuovo framework di effetti multimediali ti consente di applicare una varietà di effetti visivi a immagini e video. Ad esempio, gli effetti dell'immagine consentono di correggere facilmente gli occhi rossi, convertire un'immagine in scala di grigi, regolare la luminosità, regolare la saturazione, ruotare un'immagine, applicare un effetto fisheye e molto altro. Il sistema esegue l'elaborazione di tutti gli effetti sulla GPU per ottenere le massime prestazioni.

Per ottenere le massime prestazioni, gli effetti vengono applicati direttamente alle texture OpenGL, quindi l'applicazione deve avere un contesto OpenGL valido prima di poter utilizzare le API degli effetti. Le texture a cui applichi gli effetti possono provenire da bitmap, video o persino dalla fotocamera. Tuttavia, le texture devono rispettare alcune limitazioni:

  1. Devono essere associati a un'immagine texture GL_TEXTURE_2D
  2. Devono contenere almeno un livello di mipmap

Un oggetto Effect definisce un singolo effetto multimediale che puoi applicare a un frame immagine. Il flusso di lavoro di base per creare un Effect è:

  1. Chiama EffectContext.createWithCurrentGlContext() dal tuo contesto OpenGL ES 2.0.
  2. Utilizza il valore EffectContext restituito per chiamare EffectContext.getFactory(), che restituisce un'istanza di EffectFactory.
  3. Richiama createEffect(), trasmettendo un nome effetto da @link android.media.effect.EffectFactory}, ad esempio EFFECT_FISHEYE o EFFECT_VIGNETTE.

Puoi regolare i parametri di un effetto chiamando setParameter() e trasmettendo un nome e un valore parametro. Ogni tipo di effetto accetta parametri diversi, documentati con il nome dell'effetto. Ad esempio, EFFECT_FISHEYE ha un parametro per il valore scale della distorsione.

Per applicare un effetto a una texture, richiama apply() su Effect e passa la texture di input, la larghezza e l'altezza e la texture di output. La texture di input deve essere associata a un'immagine texture GL_TEXTURE_2D (in genere viene eseguita chiamando la funzione glTexImage2D()). Puoi fornire più livelli di mipmap. Se la texture di output non è stata associata a un'immagine texture, verrà associata automaticamente dall'effetto come GL_TEXTURE_2D e con un livello di mipmap (0), che avrà le stesse dimensioni dell'input.

È garantito che tutti gli effetti elencati in EffectFactory siano supportati. Tuttavia, alcuni effetti aggiuntivi disponibili dalle librerie esterne non sono supportati da tutti i dispositivi, quindi devi prima verificare se l'effetto desiderato della libreria esterna è supportato chiamando isEffectSupported().

Client di controllo remoto

Il nuovo RemoteControlClient consente ai lettori multimediali di abilitare i controlli di riproduzione dai client di controllo remoto, ad esempio la schermata di blocco del dispositivo. I lettori multimediali possono inoltre mostrare informazioni sui contenuti multimediali attualmente in riproduzione per la visualizzazione sul telecomando, ad esempio informazioni sulle tracce e copertine degli album.

Per abilitare i client di controllo remoto per il tuo media player, crea un'istanza di RemoteControlClient con il relativo costruttore, passando un PendingIntent che trasmette ACTION_MEDIA_BUTTON. L'intent deve anche dichiarare il componente esplicito BroadcastReceiver nella tua app che gestisce l'evento ACTION_MEDIA_BUTTON.

Per dichiarare quali input di controllo dei contenuti multimediali possono essere gestiti dal player, devi chiamare setTransportControlFlags() sul tuo RemoteControlClient, trasmettendo un insieme di flag FLAG_KEY_MEDIA_*, ad esempio FLAG_KEY_MEDIA_PREVIOUS e FLAG_KEY_MEDIA_NEXT.

Devi quindi registrare il tuo RemoteControlClient passandolo a MediaManager.registerRemoteControlClient(). Una volta registrato, il ricevitore di trasmissione dichiarato quando hai creato un'istanza RemoteControlClient riceverà eventi ACTION_MEDIA_BUTTON quando viene premuto un pulsante da un telecomando. L'intent che ricevi include il KeyEvent del tasto multimediale premuto, che puoi recuperare dall'intent con getParcelableExtra(Intent.EXTRA_KEY_EVENT).

Per visualizzare sul telecomando le informazioni relative ai contenuti multimediali in riproduzione, chiama editMetaData() e aggiungi i metadati al RemoteControlClient.MetadataEditor restituito. Puoi fornire una bitmap per artwork multimediali, informazioni numeriche come il tempo trascorso e informazioni di testo come il titolo della traccia. Per informazioni sulle chiavi disponibili, consulta i flag METADATA_KEY_* in MediaMetadataRetriever.

Per un'implementazione di esempio, consulta il sito Random Music Player, che offre una logica di compatibilità tale da abilitare il client di controllo remoto sui dispositivi Android 4.0, continuando a supportare i dispositivi fino ad Android 2.1.

Lettori multimediali

  • Per lo streaming di contenuti multimediali online da MediaPlayer ora è necessaria l'autorizzazione INTERNET. Se utilizzi MediaPlayer per riprodurre contenuti su Internet, assicurati di aggiungere l'autorizzazione INTERNET al file manifest, altrimenti la riproduzione di contenuti multimediali non funzionerà a partire da Android 4.0.
  • setSurface() consente di definire un Surface che si comporti come il sink video.
  • setDataSource() ti consente di inviare intestazioni HTTP aggiuntive con la tua richiesta, il che può essere utile per il live streaming HTTP(S)
  • Il live streaming HTTP(S) ora rispetta i cookie HTTP nelle richieste

Tipi di elementi multimediali

Android 4.0 aggiunge il supporto di:

  • Protocollo di live streaming HTTP/HTTPS versione 3
  • Codifica audio AAC non elaborata di ADTS
  • Immagini WEBP
  • Video Matroska

Per ulteriori informazioni, consulta la sezione Formati multimediali supportati.

Fotocamera

La classe Camera ora include API per il rilevamento dei volti e il controllo delle aree di interesse e misurazione.

Riconoscimento facciale

Le app Fotocamera ora possono migliorare le loro capacità grazie alle API di rilevamento dei volti di Android, che non solo rilevano il volto di un soggetto, ma anche caratteristiche facciali specifiche, come occhi e bocca.

Per rilevare i volti nell'applicazione della fotocamera, devi registrare un Camera.FaceDetectionListener chiamando il numero setFaceDetectionListener(). Puoi quindi avviare la superficie della fotocamera e iniziare a rilevare i volti chiamando il numero startFaceDetection().

Quando il sistema rileva uno o più volti nella scena della videocamera, richiama il callback onFaceDetection() nell'implementazione di Camera.FaceDetectionListener, includendo un array di oggetti Camera.Face.

Un'istanza della classe Camera.Face fornisce varie informazioni sul volto rilevato, tra cui:

  • Un elemento Rect che specifica i limiti del volto rispetto al campo visivo corrente della videocamera
  • Un numero intero compreso tra 1 e 100 che indica il grado di sicurezza del sistema che l'oggetto sia un volto umano
  • Un ID univoco per monitorare più volti
  • Diversi oggetti Point che indicano dove si trovano gli occhi e la bocca

Nota: il riconoscimento facciale potrebbe non essere supportato su alcuni dispositivi, quindi devi controllare chiamando il numero getMaxNumDetectedFaces() e assicurarti che il valore restituito sia maggiore di zero. Inoltre, alcuni dispositivi potrebbero non supportare l'identificazione di occhi e bocca, nel qual caso, i campi nell'oggetto Camera.Face saranno nulli.

Aree di messa a fuoco e misurazione

Le app della fotocamera ora possono controllare le aree utilizzate dalla fotocamera per la messa a fuoco e per la misurazione del bilanciamento del bianco e dell'esposizione automatica. Entrambe le funzionalità utilizzano la nuova classe Camera.Area per specificare l'area dell'inquadratura corrente della videocamera che deve essere messa a fuoco o a consumo. Un'istanza della classe Camera.Area definisce i limiti dell'area con un valore Rect e il peso dell'area, che rappresenta il livello di importanza dell'area rispetto ad altre aree prese in considerazione, con un numero intero.

Prima di impostare un'area di messa a fuoco o un'area di misurazione, devi chiamare rispettivamente getMaxNumFocusAreas() o getMaxNumMeteringAreas(). Se restituisce zero, il dispositivo non supporta la funzionalità corrispondente.

Per specificare le aree di messa a fuoco o di misurazione da utilizzare, basta chiamare setFocusAreas() o setMeteringAreas(). Ciascuno richiede List di Camera.Area oggetti che indicano le aree da considerare per la messa a fuoco o la misurazione. Ad esempio, potresti implementare una funzionalità che permette all'utente di impostare l'area di messa a fuoco toccando un'area dell'anteprima, che poi traduci in un oggetto Camera.Area e richiedi alla fotocamera di mettere a fuoco quell'area della scena. La messa a fuoco o l'esposizione in quell'area verranno costantemente aggiornate in base al cambiamento della scena nell'area.

Messa a fuoco automatica continua per le foto

Ora puoi attivare la messa a fuoco automatica continua (CAF) quando scatti le foto. Per abilitare CAF nell'app della fotocamera, passa FOCUS_MODE_CONTINUOUS_PICTURE a setFocusMode(). Quando vuoi scattare una foto, chiama il numero autoFocus(). Il tuo Camera.AutoFocusCallback riceve immediatamente un callback per indicare se è stato raggiunto lo stato attivo. Per riattivare CAF dopo aver ricevuto il callback, devi chiamare il numero cancelAutoFocus().

Nota: la messa a fuoco automatica continua è supportata anche per l'acquisizione di video tramite FOCUS_MODE_CONTINUOUS_VIDEO, aggiunta nel livello API 9.

Altre funzionalità della fotocamera

  • Mentre registri il video, ora puoi chiamare il numero takePicture() per salvare una foto senza interrompere la sessione video. Prima di farlo, devi chiamare isVideoSnapshotSupported() per assicurarti che l'hardware lo supporti.
  • Per evitare che queste proprietà vengano modificate, ora puoi bloccare l'esposizione automatica e il bilanciamento del bianco con le opzioni setAutoExposureLock() e setAutoWhiteBalanceLock().
  • Ora puoi chiamare setDisplayOrientation() mentre è in corso l'anteprima della fotocamera. In precedenza, potevi eseguire la chiamata solo prima di avviare l'anteprima, ma ora puoi modificare l'orientamento in qualsiasi momento.

Intent di trasmissione videocamera

  • Camera.ACTION_NEW_PICTURE: indica che l'utente ha scattato una nuova foto. L'app Fotocamera integrata richiama questa trasmissione dopo aver acquisito una foto e anche le app della fotocamera di terze parti devono trasmettere questo intento dopo aver scattato una foto.
  • Camera.ACTION_NEW_VIDEO: indica che l'utente ha acquisito un nuovo video. L'app Fotocamera integrata richiama questa trasmissione dopo la registrazione di un video e anche le app fotocamera di terze parti devono trasmettere questo intento dopo aver acquisito un video.

Android Beam (NDEF Push con NFC)

Android Beam è una nuova funzione NFC che consente di inviare messaggi NDEF da un dispositivo all'altro (un processo noto anche come "NDEF Push"). Il trasferimento di dati viene avviato quando due dispositivi Android che supportano Android Beam si trovano vicini (circa 4 cm), in genere con lo schiena che si toccano. I dati contenuti nel messaggio NDEF possono contenere qualsiasi dato che vuoi condividere tra i dispositivi. Ad esempio, l'app Persone condivide i contatti, YouTube condivide i video e il browser condivide gli URL tramite Android Beam.

Per trasmettere dati tra dispositivi utilizzando Android Beam, devi creare un NdefMessage che contenga le informazioni che desideri condividere mentre la tua attività è in primo piano. Devi poi passare NdefMessage al sistema in uno dei due seguenti modi:

Se vuoi eseguire un codice specifico dopo che il sistema ha consegnato il messaggio NDEF all'altro dispositivo, puoi implementare NfcAdapter.OnNdefPushCompleteCallback e impostarlo con setNdefPushCompleteCallback(). Il sistema chiamerà quindi onNdefPushComplete() alla consegna del messaggio.

Sul dispositivo ricevente, il sistema invia messaggi push NDEF in modo simile ai normali tag NFC. Il sistema richiama un intent con l'azione ACTION_NDEF_DISCOVERED per avviare un'attività, con un URL o un tipo MIME impostato in base al primo NdefRecord in NdefMessage. Per l'attività a cui vuoi rispondere, puoi dichiarare i filtri per intent per gli URL o i tipi MIME che interessano la tua app. Per ulteriori informazioni sull'invio di tag, consulta la guida per gli sviluppatori NFC.

Se vuoi che NdefMessage trasmetta un URI, ora puoi usare il metodo di convenienza createUri per creare un nuovo NdefRecord basato su una stringa o un oggetto Uri. Se l'URI è un formato speciale che vuoi che l'applicazione riceva anche durante un evento Android Beam, devi creare un filtro di intent per l'attività utilizzando lo stesso schema URI per ricevere il messaggio NDEF in arrivo.

Devi anche passare un "record app Android" con NdefMessage per garantire che l'applicazione gestisca il messaggio NDEF in arrivo, anche se altre applicazioni filtrano per la stessa azione intent. Puoi creare un record dell'applicazione Android chiamando createApplicationRecord() e trasmettendogli il nome del pacchetto dell'applicazione. Quando l'altro dispositivo riceve il messaggio NDEF con il record dell'applicazione e più applicazioni contengono attività che gestiscono l'intent specificato, il sistema consegna sempre il messaggio all'attività nell'applicazione (in base al record dell'applicazione corrispondente). Se sul dispositivo di destinazione non è attualmente installata l'applicazione, il sistema utilizza il record dell'applicazione Android per avviare Google Play e indirizzare l'utente all'applicazione per installarla.

Se la tua applicazione non utilizza API NFC per eseguire i messaggi push NDEF, Android offre un comportamento predefinito: quando l'applicazione è in primo piano su un dispositivo e Android Beam viene richiamato su un altro dispositivo Android, l'altro dispositivo riceve un messaggio NDEF con un record dell'applicazione Android che identifica l'applicazione. Se l'applicazione è installata sul dispositivo ricevente, il sistema la avvia; in caso contrario, Google Play si apre e porta l'utente alla tua applicazione per installarla.

Per ulteriori informazioni su Android Beam e altre funzioni NFC, consulta la guida per gli sviluppatori Nozioni di base su NFC. Per alcuni esempi di codice che utilizzano Android Beam, consulta la demo per Android Beam.

Wi-Fi P2P

Android ora supporta le connessioni Wi-Fi peer-to-peer (P2P) tra dispositivi Android e altri tipi di dispositivi (in conformità con il programma di certificazione Wi-Fi DirectTM di Wi-Fi Alliance) senza un hotspot o una connessione a Internet. Il framework Android fornisce un insieme di API Wi-Fi P2P che consentono di rilevare e connettersi ad altri dispositivi quando ciascuno supporta il Wi-Fi P2P, quindi di comunicare tramite una connessione veloce su distanze molto più lunghe rispetto a una connessione Bluetooth.

Un nuovo pacchetto, android.net.wifi.p2p, contiene tutte le API per eseguire connessioni peer-to-peer con Wi-Fi. La classe principale con cui devi lavorare è WifiP2pManager, che puoi acquisire chiamando getSystemService(WIFI_P2P_SERVICE). L'WifiP2pManager include API che ti consentono di:

  • Inizializza l'applicazione per le connessioni P2P chiamando initialize()
  • Scopri i dispositivi nelle vicinanze chiamando il numero discoverPeers()
  • Avvia una connessione P2P chiamando il numero connect()
  • E altro ancora

Sono necessarie anche molte altre interfacce e classi, ad esempio:

  • L'interfaccia WifiP2pManager.ActionListener consente di ricevere callback quando un'operazione come il rilevamento dei peer o la connessione ai peer ha esito positivo o negativo.
  • L'interfaccia di WifiP2pManager.PeerListListener ti consente di ricevere informazioni sui peer rilevati. Il callback fornisce un WifiP2pDeviceList, da cui puoi recuperare un oggetto WifiP2pDevice per ogni dispositivo nel raggio d'azione e ottenere informazioni quali nome, indirizzo, tipo di dispositivo, configurazioni WPS supportate dal dispositivo e altro ancora.
  • L'interfaccia WifiP2pManager.GroupInfoListener consente di ricevere informazioni su un gruppo P2P. Il callback fornisce un oggetto WifiP2pGroup, che fornisce informazioni sul gruppo come il proprietario, il nome della rete e la passphrase.
  • L'interfaccia di WifiP2pManager.ConnectionInfoListener consente di ricevere informazioni sulla connessione attuale. Il callback fornisce un oggetto WifiP2pInfo che contiene informazioni, ad esempio se un gruppo è stato formato e chi è il relativo proprietario.

Per poter usare le API Wi-Fi P2P, la tua app deve richiedere le seguenti autorizzazioni utente:

  • ACCESS_WIFI_STATE
  • CHANGE_WIFI_STATE
  • INTERNET (anche se la tua app non si connette tecnicamente a internet, la comunicazione con peer Wi-Fi P2P tramite socket Java standard richiede l'autorizzazione a Internet).

Il sistema Android trasmette anche diverse azioni durante determinati eventi Wi-Fi P2P:

Per saperne di più, consulta la documentazione relativa a WifiP2pManager. Guarda anche l'applicazione di esempio Demo Wi-Fi P2P.

Dispositivi Bluetooth per la salute

Android ora supporta i dispositivi Bluetooth Health Profile, che ti consentono di creare applicazioni che utilizzano il Bluetooth per comunicare con dispositivi per la salute che supportano Bluetooth, come monitor del battito cardiaco, misuratori del sangue, termometri e bilance.

Come per le cuffie normali e i dispositivi con profilo A2DP, devi chiamare getProfileProxy() con un tipo di profilo BluetoothProfile.ServiceListener e HEALTH per stabilire una connessione con l'oggetto proxy del profilo.

Una volta acquisito il proxy del profilo salute (l'oggetto BluetoothHealth), la connessione e la comunicazione con dispositivi sanitari accoppiati prevede le seguenti nuove classi Bluetooth:

  • BluetoothHealthCallback: devi estendere questa classe e implementare i metodi di callback per ricevere aggiornamenti sulle modifiche dello stato di registrazione e dello stato del canale Bluetooth dell'applicazione.
  • BluetoothHealthAppConfiguration: durante i callback al tuo BluetoothHealthCallback, riceverai un'istanza di questo oggetto, che fornisce informazioni di configurazione sul dispositivo di integrità Bluetooth disponibile, che devi utilizzare per eseguire varie operazioni, come avviare e terminare connessioni con le API BluetoothHealth.

Per ulteriori informazioni sull'uso del Profilo Salute Bluetooth, consulta la documentazione di BluetoothHealth.

Accessibilità

Android 4.0 migliora l'accessibilità per gli utenti con problemi di vista grazie alla nuova modalità Esplora al tocco e alle API estese che consentono di fornire maggiori informazioni sulla visualizzazione dei contenuti o di sviluppare servizi di accessibilità avanzati.

Modalità Esplora al tocco

Gli utenti ipovedenti possono ora esplorare lo schermo toccando e trascinando un dito sullo schermo per ascoltare le descrizioni vocali dei contenuti. La modalità Esplora al tocco funziona come un cursore virtuale, pertanto consente agli screen reader di identificare il testo descrittivo come fanno gli screen reader quando l'utente naviga con un D-pad o una trackball, leggendo le informazioni fornite da android:contentDescription e setContentDescription() durante un evento di passaggio del mouse simulato. Tieni quindi presente che questo promemoria ti ricorda che devi fornire un testo descrittivo per le viste nella tua applicazione, in particolare per ImageButton, EditText, ImageView e altri widget che potrebbero non contenere testo descrittivo.

Accessibilità per le visualizzazioni

Per migliorare le informazioni disponibili per i servizi di accessibilità come gli screen reader, puoi implementare nuovi metodi di callback per gli eventi di accessibilità nei componenti View personalizzati.

È importante notare innanzitutto che il comportamento del metodo sendAccessibilityEvent() è cambiato in Android 4.0. Come nella versione precedente di Android, quando l'utente attiva i servizi di accessibilità sul dispositivo e si verifica un evento di input come un clic o un passaggio del mouse, la rispettiva visualizzazione riceve una notifica con una chiamata al numero sendAccessibilityEvent(). In precedenza, l'implementazione di sendAccessibilityEvent() veniva inizializzato con AccessibilityEvent e inviato a AccessibilityManager. Il nuovo comportamento prevede alcuni metodi di callback aggiuntivi che consentono alla visualizzazione e ai relativi elementi padre di aggiungere ulteriori informazioni contestuali all'evento:

  1. Quando richiamati, i metodi sendAccessibilityEvent() e sendAccessibilityEventUnchecked() rimandano a onInitializeAccessibilityEvent().

    Le implementazioni personalizzate di View potrebbero voler implementare onInitializeAccessibilityEvent() per aggiungere informazioni sull'accessibilità aggiuntive a AccessibilityEvent, ma devono anche chiamare la super implementazione per fornire informazioni predefinite come la descrizione dei contenuti standard, l'indice degli elementi e altro ancora. Tuttavia, non dovresti aggiungere altri contenuti di testo a questo callback (che verrà fatto successivamente).

  2. Una volta inizializzato, se l'evento è uno dei vari tipi che dovrebbero essere completati con informazioni testuali, la vista riceve una chiamata a dispatchPopulateAccessibilityEvent(), che rimanda al callback onPopulateAccessibilityEvent().

    Le implementazioni personalizzate dell'elemento View di solito dovrebbero implementare onPopulateAccessibilityEvent() per aggiungere contenuti di testo aggiuntivi a AccessibilityEvent se il testo android:contentDescription manca o è insufficiente. Per aggiungere altra descrizione testuale a AccessibilityEvent, chiama il numero getText().add().

  3. A questo punto, View passa l'evento al livello della gerarchia delle viste chiamando requestSendAccessibilityEvent() nella vista principale. Ogni vista padre ha quindi la possibilità di aumentare le informazioni sull'accessibilità aggiungendo un AccessibilityRecord, fino a quando non raggiunge la vista principale, il che invia l'evento a AccessibilityManager con sendAccessibilityEvent().

Oltre ai nuovi metodi precedenti, che sono utili quando si estende la classe View, puoi anche intercettare questi callback di eventi su qualsiasi View estendendo AccessibilityDelegate e impostandolo nella visualizzazione con setAccessibilityDelegate(). Quando esegui questa operazione, ogni metodo di accessibilità nella vista reindirizza la chiamata al metodo corrispondente nel delegato. Ad esempio, quando la vista riceve una chiamata a onPopulateAccessibilityEvent(), la passa allo stesso metodo in View.AccessibilityDelegate. Tutti i metodi non gestiti dal delegato vengono restituiti direttamente alla visualizzazione per impostazione predefinita. In questo modo puoi eseguire l'override solo dei metodi necessari per una determinata visualizzazione senza estendere la classe View.

Se vuoi mantenere la compatibilità con versioni di Android precedenti alla 4.0, supportando anche le nuove API di accessibilità, puoi farlo con la versione più recente della libreria di supporto v4 (in Pacchetto di compatibilità r4) utilizzando un insieme di classi di utilità che forniscono le nuove API di accessibilità in un design compatibile con le versioni precedenti.

Servizi di accessibilità

Se stai sviluppando un servizio di accessibilità, le informazioni sui vari eventi di accessibilità sono state notevolmente ampliate per consentire agli utenti feedback sull'accessibilità più avanzati. In particolare, gli eventi vengono generati in base alla composizione delle viste, fornendo migliori informazioni di contesto e consentendo ai servizi di accessibilità di attraversare le gerarchie delle viste per ottenere ulteriori informazioni sulle viste e gestire casi speciali.

Se stai sviluppando un servizio di accessibilità (ad esempio uno screen reader), puoi accedere a ulteriori informazioni sui contenuti e attraversare le gerarchie di visualizzazione con la seguente procedura:

  1. Dopo aver ricevuto un AccessibilityEvent da un'applicazione, chiama AccessibilityEvent.getRecord() per recuperare un AccessibilityRecord specifico (potrebbero esserci diversi record allegati all'evento).
  2. Da AccessibilityEvent o da un singolo AccessibilityRecord, puoi chiamare getSource() per recuperare un oggetto AccessibilityNodeInfo.

    Un AccessibilityNodeInfo rappresenta un singolo nodo dei contenuti della finestra in un formato che consente di eseguire query sulle informazioni sull'accessibilità relative a quel nodo. L'oggetto AccessibilityNodeInfo restituito da AccessibilityEvent descrive l'origine evento, mentre l'origine da un AccessibilityRecord descrive il predecessore dell'origine evento.

  3. Con AccessibilityNodeInfo, puoi eseguire query sullo stesso, chiamare getParent() o getChild() per attraversare la gerarchia delle viste e persino aggiungere viste secondarie al nodo.

Per poter essere pubblicata nel sistema come servizio di accessibilità, l'applicazione deve dichiarare un file di configurazione XML corrispondente a AccessibilityServiceInfo. Per ulteriori informazioni sulla creazione di un servizio di accessibilità, consulta AccessibilityService e SERVICE_META_DATA per informazioni sulla configurazione XML.

Altre API per l'accessibilità

Se ti interessa conoscere lo stato di accessibilità del dispositivo, AccessibilityManager ha alcune nuove API come:

Servizi di controllo ortografico

Un nuovo framework di controllo ortografico consente alle app di creare controlli ortografici in modo simile al framework del metodo di input (per gli IME). Per creare una nuova funzione di controllo ortografico, devi implementare un servizio che estenda SpellCheckerService ed estendi la classe SpellCheckerService.Session per fornire suggerimenti ortografici basati sul testo fornito dai metodi di callback dell'interfaccia. Nei metodi di callback SpellCheckerService.Session, devi restituire i suggerimenti di ortografia come oggetti SuggestionsInfo.

Le applicazioni con un servizio di controllo ortografico devono dichiarare l'autorizzazione BIND_TEXT_SERVICE come richiesto dal servizio. Il servizio deve anche dichiarare un filtro per intent con <action android:name="android.service.textservice.SpellCheckerService" /> come azione dell'intent e deve includere un elemento <meta-data> che dichiari le informazioni di configurazione per il controllo ortografico.

Consulta l'app Servizio di controllo ortografico e l'app Client del controllo ortografico per visualizzare il codice di esempio.

Motori di sintesi vocale

Le API di sintesi vocale (TTS) di Android sono state notevolmente estese per consentire alle applicazioni di implementare più facilmente motori di sintesi vocale personalizzati, mentre le applicazioni che vogliono utilizzare un motore di sintesi vocale dispongono di un paio di nuove API per la selezione di un motore.

Utilizzo dei motori di sintesi vocale

Nelle versioni precedenti di Android, potevi utilizzare la classe TextToSpeech per eseguire operazioni di sintesi vocale (TTS) utilizzando il motore di sintesi vocale fornito dal sistema o impostare un motore personalizzato utilizzando setEngineByPackageName(). In Android 4.0, il metodo setEngineByPackageName() è stato ritirato e ora puoi specificare il motore da utilizzare con un nuovo costruttore TextToSpeech che accetta il nome di pacchetto di un motore di sintesi vocale.

Puoi anche eseguire query sui motori di sintesi vocale disponibili con getEngines(). Questo metodo restituisce un elenco di oggetti TextToSpeech.EngineInfo che includono metadati come l'icona, l'etichetta e il nome del pacchetto del motore.

Creazione di motori di sintesi vocale

In precedenza, i motori personalizzati richiedevano che il motore venisse creato utilizzando un file di intestazione nativo non documentato. In Android 4.0, è disponibile un set completo di API framework per la creazione di motori TTS.

La configurazione di base richiede un'implementazione di TextToSpeechService che risponda all'intent INTENT_ACTION_TTS_SERVICE. Il lavoro principale per un motore di sintesi vocale avviene durante il callback onSynthesizeText() in un servizio che estende TextToSpeechService. Il sistema fornisce questo metodo con due oggetti:

  • SynthesisRequest: contiene vari dati, tra cui il testo da sintetizzare, le impostazioni internazionali, la velocità della voce e il tono della voce.
  • SynthesisCallback: è l'interfaccia tramite la quale il motore di sintesi vocale fornisce i dati vocali risultanti come audio in streaming. Innanzitutto il motore deve chiamare start() per indicare che è pronto a pubblicare l'audio, quindi chiamare audioAvailable(), passando i dati audio in un buffer di byte. Dopo che il motore ha passato tutto l'audio attraverso il buffer, chiama done().

Ora che il framework supporta un'API vera per la creazione di motori TTS, il supporto per l'implementazione del codice nativo è stato rimosso. Cerca un post del blog su un livello di compatibilità utilizzabile per convertire i vecchi motori di sintesi vocale nel nuovo framework.

Per un motore di sintesi vocale di esempio che utilizza le nuove API, vedi l'app di esempio Text To Speech Engine.

Utilizzo della rete

Android 4.0 offre agli utenti una visibilità precisa sulla quantità di dati di rete utilizzati dalle loro applicazioni. L'app Impostazioni fornisce controlli che consentono agli utenti di gestire l'impostazione di limiti per l'utilizzo dei dati di rete e persino di disattivare l'uso dei dati in background per singole app. Per evitare che gli utenti disattivino l'accesso della tua app ai dati in background, devi sviluppare strategie per utilizzare la connessione dati in modo efficiente e regolare l'utilizzo in base al tipo di connessione disponibile.

Se la tua applicazione esegue molte transazioni di rete, dovresti fornire impostazioni che consentano agli utenti di controllare le abitudini di utilizzo dei dati dell'app, ad esempio la frequenza di sincronizzazione dei dati, se eseguire caricamenti/download solo quando il dispositivo è connesso a una rete Wi-Fi, se utilizzare i dati in roaming e così via. Con questi controlli a loro disposizione, è molto meno probabile che gli utenti disattivino l'accesso dell'app ai dati quando si avvicinano ai limiti perché possono usare la tua app in modo preciso. Se fornisci un'attività di preferenza con queste impostazioni, devi includere nel file manifest la dichiarazione di un filtro per intent per l'azione ACTION_MANAGE_NETWORK_USAGE. Ecco alcuni esempi:

<activity android:name="DataPreferences" android:label="@string/title_preferences">
    <intent-filter>
       <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
       <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Questo filtro di intent indica al sistema che si tratta dell'attività che controlla l'utilizzo dei dati dell'applicazione. Pertanto, quando l'utente controlla la quantità di dati utilizzata dalla tua app dall'app Impostazioni, è disponibile un pulsante "Visualizza impostazioni applicazione" che avvia l'attività di preferenza in modo che l'utente possa perfezionare la quantità di dati utilizzata dall'app.

Tieni inoltre presente che getBackgroundDataSetting() ora è deprecato e restituisce sempre true. Utilizza getActiveNetworkInfo(). Prima di tentare qualsiasi transazione di rete, devi sempre chiamare getActiveNetworkInfo() per ottenere il NetworkInfo che rappresenta la rete attuale e eseguire la query isConnected() per verificare se il dispositivo dispone di una connessione. Puoi quindi controllare altre proprietà della connessione, ad esempio se il dispositivo è in roaming o connesso alla rete Wi-Fi.

Enterprise

Android 4.0 espande le funzionalità per le applicazioni aziendali con le seguenti funzionalità.

Servizi VPN

Il nuovo VpnService consente alle applicazioni di creare la propria VPN (rete privata virtuale), in esecuzione come Service. Un servizio VPN crea un'interfaccia per una rete virtuale con il proprio indirizzo e le proprie regole di routing ed esegue tutte le operazioni di lettura e scrittura con un descrittore di file.

Per creare un servizio VPN, utilizza VpnService.Builder, che ti consente di specificare l'indirizzo di rete, il server DNS, la route di rete e altro ancora. Al termine, puoi stabilire l'interfaccia chiamando establish(), che restituisce un ParcelFileDescriptor.

Dato che un servizio VPN può intercettare i pacchetti, esistono implicazioni in termini di sicurezza. Di conseguenza, se implementi VpnService, il servizio deve richiedere BIND_VPN_SERVICE per garantire che solo il sistema possa eseguire l'associazione (solo al sistema viene concessa questa autorizzazione e le app non possono richiederla). Per utilizzarlo, gli utenti devono abilitarlo manualmente nelle impostazioni di sistema.

Criteri relativi ai dispositivi

Le applicazioni che gestiscono le limitazioni relative ai dispositivi ora possono disattivare la videocamera utilizzando setCameraDisabled() e la proprietà USES_POLICY_DISABLE_CAMERA (applicata con un elemento <disable-camera /> nel file di configurazione dei criteri).

Gestione dei certificati

La nuova classe KeyChain fornisce API che consentono di importare e accedere ai certificati nell'archivio chiavi di sistema. I certificati semplificano l'installazione sia dei certificati client (per convalidare l'identità dell'utente) sia di certificati dell'autorità di certificazione (per verificare l'identità del server). Applicazioni come browser web o client di posta possono accedere ai certificati installati per autenticare gli utenti sui server. Per ulteriori informazioni, consulta la documentazione di KeyChain.

Sensori del dispositivo

In Android 4.0 sono stati aggiunti due nuovi tipi di sensori:

Se un dispositivo dispone di sensori TYPE_AMBIENT_TEMPERATURE e TYPE_RELATIVE_HUMIDITY, puoi utilizzarli per calcolare il punto di rugiada e l'umidità assoluta.

Il precedente sensore di temperatura, TYPE_TEMPERATURE, è stato ritirato. Dovresti usare il sensore TYPE_AMBIENT_TEMPERATURE.

Inoltre, i tre sensori sintetici di Android sono stati notevolmente migliorati e ora presentano una latenza inferiore e un output più fluido. Questi sensori includono il sensore di gravità (TYPE_GRAVITY), il sensore del vettore di rotazione (TYPE_ROTATION_VECTOR) e il sensore di accelerazione lineare (TYPE_LINEAR_ACCELERATION). I sensori migliorati si basano sul sensore del giroscopio per migliorarne l'output, pertanto i sensori appaiono solo su dispositivi dotati di giroscopio.

Barra delle azioni

ActionBar è stato aggiornato per supportare diversi nuovi comportamenti. Soprattutto, il sistema gestisce agevolmente le dimensioni e la configurazione della barra delle azioni quando viene eseguita su schermi più piccoli per offrire un'esperienza utente ottimale su schermi di tutte le dimensioni. Ad esempio, quando lo schermo è stretto (come quando il telefono è in orientamento verticale), le schede di navigazione della barra delle azioni vengono visualizzate in una "barra in pila", che viene visualizzata direttamente sotto la barra principale. Puoi anche attivare una "barra delle azioni divisa", che posiziona tutte le attività in una barra separata nella parte inferiore dello schermo quando lo schermo è stretto.

Dividi barra delle azioni

Se la barra delle azioni include più attività, non tutte potranno essere inserite nella barra delle azioni su uno schermo stretto, pertanto il sistema ne inserirà altri nel menu extra. Tuttavia, Android 4.0 consente di attivare la "barra delle azioni divisa" in modo che più attività possano essere visualizzate sullo schermo in una barra separata nella parte inferiore dello schermo. Per attivare la barra delle azioni divisa, aggiungi android:uiOptions con "splitActionBarWhenNarrow" al tag <application> o ai singoli tag <activity> nel file manifest. Se questa opzione è attiva, il sistema aggiungerà un'ulteriore barra nella parte inferiore dello schermo per tutte le attività quando lo schermo è stretto (non verrà visualizzata alcuna attività nella barra delle azioni principale).

Se vuoi utilizzare le schede di navigazione fornite dalle API ActionBar.Tab, ma non hai bisogno della barra delle azioni principale in alto (vuoi che solo le schede vengano visualizzate in alto), attiva la barra delle azioni divisa come descritto sopra e chiama anche setDisplayShowHomeEnabled(false) per disattivare l'icona dell'applicazione nella barra delle azioni. Se non è più presente nella barra delle azioni principale, scompare; rimangono solo le schede di navigazione in alto e le attività nella parte inferiore dello schermo.

Stili della barra delle azioni

Se vuoi applicare uno stile personalizzato alla barra delle azioni, puoi usare le nuove proprietà di stile backgroundStacked e backgroundSplit per applicare un colore o un disegno di sfondo alla barra in pila e alla barra divisa rispettivamente. Puoi anche impostare questi stili in fase di runtime con setStackedBackgroundDrawable() e setSplitBackgroundDrawable().

Fornitore di azioni

La nuova classe ActionProvider consente di creare un gestore specializzato per le attività. Un fornitore di azioni può definire una visualizzazione delle azioni, un comportamento predefinito delle azioni e un sottomenu per ogni attività a cui è associato. Quando vuoi creare un'attività con comportamenti dinamici (come una visualizzazione ad azione variabile, un'azione predefinita o un sottomenu), l'estensione ActionProvider è una buona soluzione per creare un componente riutilizzabile, invece di gestire le varie trasformazioni dell'elemento azione nel frammento o nell'attività.

Ad esempio, ShareActionProvider è un'estensione di ActionProvider che facilita un'azione di "condivisione" dalla barra delle azioni. Anziché utilizzare un'attività tradizionale che richiama l'intent ACTION_SEND, puoi utilizzare questo provider di azioni per presentare una visualizzazione azione con un elenco a discesa di applicazioni che gestiscono l'intent ACTION_SEND. Quando l'utente seleziona un'applicazione da utilizzare per l'azione, ShareActionProvider memorizza la selezione e la inserisce nella visualizzazione azione per consentire un accesso più rapido alla condivisione con quell'app.

Per dichiarare un fornitore di azioni per un'attività, includi l'attributo android:actionProviderClass nell'elemento <item> del menu opzioni dell'attività, specificando il nome della classe dell'azione come valore. Ecco alcuni esempi:

<item android:id="@+id/menu_share"
      android:title="Share"
      android:showAsAction="ifRoom"
      android:actionProviderClass="android.widget.ShareActionProvider" />

Nel metodo di callback onCreateOptionsMenu() dell'attività, recupera un'istanza del provider dell'azione dalla voce di menu e imposta l'intent:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options, menu)
    val shareActionProvider = menu.findItem(R.id.menu_share)?.actionProvider as? ShareActionProvider
    // Set the share intent of the share action provider.
    shareActionProvider?.setShareIntent(createShareIntent())
    ...
    return super.onCreateOptionsMenu(menu)
}

Java

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.options, menu);
    ShareActionProvider shareActionProvider =
          (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();
    // Set the share intent of the share action provider.
    shareActionProvider.setShareIntent(createShareIntent());
    ...
    return super.onCreateOptionsMenu(menu);
}

Per un esempio in cui viene utilizzato ShareActionProvider, consulta ActionBarShareActionProviderActivity in ApiDemos.

Visualizzazioni di azioni comprimibili

Ora le attività che forniscono una visualizzazione azione possono passare dallo stato visualizzazione azione allo stato tradizionale dell'attività. In precedenza, solo la compressione SearchView supportava la compressione quando utilizzata come visualizzazione azione, ma ora puoi aggiungere una visualizzazione azione per qualsiasi attività e passare dallo stato espanso (la visualizzazione Azione è visibile) a quello compresso (l'elemento azione è visibile).

Per dichiarare che un'attività contenente una visualizzazione Azione può essere comprimibile, includi il flag “collapseActionView" nell'attributo android:showAsAction dell'elemento <item> nel file XML del menu.

Per ricevere callback quando una visualizzazione delle azioni passa dalla visualizzazione espansa a quella compressa e viceversa, registra un'istanza di MenuItem.OnActionExpandListener con il rispettivo MenuItem chiamando setOnActionExpandListener(). In genere, dovresti farlo durante il callback onCreateOptionsMenu().

Per controllare una visualizzazione comprimibile dell'azione, puoi chiamare collapseActionView() e expandActionView() sul rispettivo MenuItem.

Quando crei una visualizzazione delle azioni personalizzate, puoi anche implementare la nuova interfaccia CollapsibleActionView per ricevere callback quando la visualizzazione viene espansa e compressa.

Altre API per la barra delle azioni

  • setHomeButtonEnabled() consente di specificare se l'icona o il logo si comporta come un pulsante per andare alla schermata Home o come pulsante per andare alla schermata Home oppure verso l'alto (passa "true" per fare in modo che si comporti come un pulsante).
  • setIcon() e setLogo() consentono di definire l'icona o il logo della barra delle azioni in fase di esecuzione.
  • Fragment.setMenuVisibility() consente di attivare o disattivare la visibilità delle voci del menu opzioni dichiarate dal frammento. Questa operazione è utile se il frammento è stato aggiunto all'attività, ma non è visibile, pertanto le voci di menu devono essere nascoste.
  • FragmentManager.invalidateOptionsMenu() consente di invalidare il menu opzioni attività durante i vari stati del ciclo di vita dei frammenti in cui l'utilizzo del metodo equivalente di Activity potrebbe non essere disponibile.

Interfaccia utente e visualizzazioni

Android 4.0 introduce una serie di nuove viste e altri componenti dell'interfaccia utente.

Layout griglia

GridLayout è un nuovo gruppo di visualizzazioni che posiziona le visualizzazioni secondarie in una griglia rettangolare. A differenza di TableLayout, GridLayout si basa su una gerarchia piatta e non si avvale di viste intermedie, come le righe di una tabella, per fornire la struttura. Al contrario, gli elementi secondari specificano le righe e le colonne da occupare (le celle possono estendersi su più righe e/o colonne) e, per impostazione predefinita, vengono disposte in sequenza su tutte le righe e le colonne della griglia. L'orientamento GridLayout determina se gli elementi secondari sequenziali sono disposti orizzontalmente o verticalmente per impostazione predefinita. Lo spazio tra gli elementi secondari può essere specificato utilizzando le istanze della nuova vista Space o impostando i relativi parametri di margine sugli elementi secondari.

Consulta ApiDemos per alcuni esempi che utilizzano GridLayout.

Visualizzazione texture

TextureView è una nuova visualizzazione che ti consente di mostrare uno stream di contenuti, ad esempio un video o una scena OpenGL. Nonostante sia simile a SurfaceView, TextureView è univoco in quanto si comporta come una visualizzazione normale, anziché creare una finestra separata, quindi puoi considerarla come qualsiasi altro oggetto View. Ad esempio, puoi applicare trasformazioni, animarlo utilizzando ViewPropertyAnimator o regolarne l'opacità con setAlpha().

Tieni presente che TextureView funziona solo all'interno di una finestra con accelerazione hardware.

Per saperne di più, consulta la documentazione di TextureView.

Cambia widget

Il nuovo widget Switch è un pulsante di attivazione/disattivazione a due stati che gli utenti possono trascinare da un lato all'altro (o semplicemente toccare) per passare da un'opzione all'altra.

Puoi utilizzare gli attributi android:textOn e android:textOff per specificare il testo da visualizzare sull'opzione quando è attiva l'impostazione di attivazione e disattivazione. L'attributo android:text ti permette inoltre di applicare un'etichetta accanto all'opzione.

Per un esempio di utilizzo dei sensori, consulta il file di layout switches.xml e la rispettiva attività Switch .

Android 3.0 ha introdotto PopupMenu per creare brevi menu contestuali che vengono visualizzati in un punto di ancoraggio da te specificato (di solito nel punto dell'elemento selezionato). Android 4.0 estende PopupMenu con un paio di funzionalità utili:

Preferenze

Una nuova classe astratta TwoStatePreference funge da base per le preferenze che forniscono un'opzione di selezione a due stati. La nuova SwitchPreference è un'estensione di TwoStatePreference che fornisce un widget Switch nella visualizzazione delle preferenze per consentire agli utenti di attivare o disattivare un'impostazione senza dover aprire un'ulteriore schermata o finestra di dialogo di preferenza. Ad esempio, l'applicazione Impostazioni utilizza un SwitchPreference per le impostazioni Wi-Fi e Bluetooth.

Temi di sistema

Il tema predefinito per tutte le applicazioni destinate ad Android 4.0 (impostando targetSdkVersion o minSdkVersion su “14" o versioni successive) è ora il tema "predefinito del dispositivo": Theme.DeviceDefault. Potrebbe trattarsi del tema scuro Holo o di un tema scuro diverso definito dal dispositivo specifico.

La famiglia di temi Theme.Holo non cambia da un dispositivo all'altro quando viene eseguita la stessa versione di Android. Se applichi esplicitamente uno dei temi Theme.Holo alle tue attività, puoi essere certo che questo tema non cambierà carattere su dispositivi diversi all'interno della stessa versione della piattaforma.

Se vuoi che la tua app si integri con il tema generale del dispositivo (ad esempio quando diversi OEM forniscono temi predefiniti diversi per il sistema), devi applicare esplicitamente i temi della famiglia Theme.DeviceDefault.

Pulsante del menu Opzioni

A partire da Android 4.0, noterai che i telefoni non richiedono più un pulsante hardware Menu. Tuttavia, non devi preoccuparti se l'applicazione esistente fornisce un menu opzioni e prevede che sia presente un pulsante Menu. Per garantire che le app esistenti continuino a funzionare come previsto, il sistema fornisce un pulsante Menu sullo schermo per le app progettate per versioni precedenti di Android.

Per una migliore esperienza utente, le app nuove e aggiornate dovrebbero invece utilizzare ActionBar per fornire l'accesso alle voci di menu e impostare targetSdkVersion su "14" per sfruttare i comportamenti predefiniti del framework più recenti.

Controlli per la visibilità dell'interfaccia utente di sistema

Fin dagli esordi di Android, il sistema ha gestito un componente dell'interfaccia utente noto come barra di stato, che si trova nella parte superiore dei dispositivi degli smartphone per fornire informazioni quali l'indicatore dell'operatore, l'ora, le notifiche e così via. Android 3.0 ha aggiunto la barra di sistema per i tablet, che si trova nella parte inferiore dello schermo per fornire controlli di navigazione del sistema (Home, Indietro e così via), nonché un'interfaccia per gli elementi tradizionalmente forniti dalla barra di stato. In Android 4.0, il sistema offre un nuovo tipo di interfaccia utente di sistema chiamata barra di navigazione. Puoi considerare la barra di navigazione una versione ottimizzata della barra di sistema progettata per gli smartphone, in quanto fornisce controlli di navigazione per i dispositivi che non hanno controparti hardware per la navigazione nel sistema, ma esclude l'interfaccia utente di notifica e i controlli delle impostazioni della barra di sistema. Pertanto, un dispositivo che fornisce la barra di navigazione ha anche la barra di stato in alto.

Fino ad oggi, puoi nascondere la barra di stato sui telefoni utilizzando il flag FLAG_FULLSCREEN. In Android 4.0, le API che controllano la visibilità della barra di sistema sono state aggiornate per riflettere meglio il comportamento della barra di sistema e della barra di navigazione:

  • Il flag SYSTEM_UI_FLAG_LOW_PROFILE sostituisce il flag STATUS_BAR_HIDDEN. Se impostato, questo flag attiva la modalità "basso profilo" per la barra di sistema o la barra di navigazione. I pulsanti di navigazione sono attenuati e vengono nascosti anche altri elementi nella barra di sistema. L'attivazione di questa opzione è utile per creare giochi più immersivi senza distrazioni per i pulsanti di navigazione del sistema.
  • Il flag SYSTEM_UI_FLAG_VISIBLE sostituisce il flag STATUS_BAR_VISIBLE per richiedere che la barra di sistema o la barra di navigazione siano visibili.
  • SYSTEM_UI_FLAG_HIDE_NAVIGATION è un nuovo flag che richiede che la barra di navigazione venga nascosta completamente. Tieni presente che funziona solo per la barra di navigazione utilizzata da alcuni telefoni (non nasconde la barra di sistema sui tablet). La barra di navigazione torna a essere visualizzata non appena il sistema riceve l'input dell'utente. Pertanto, questa modalità è utile principalmente per la riproduzione di video o per altri casi in cui è necessario l'intero schermo, ma non l'input dell'utente.

Puoi impostare ciascuna di queste segnalazioni per la barra di sistema e la barra di navigazione chiamando setSystemUiVisibility() in qualsiasi vista della tua attività. Gestione finestre unisce (OR insieme) tutti i flag di tutte le visualizzazioni nella finestra e li applica all'interfaccia utente di sistema purché la finestra sia impostata sullo stato attivo per l'input. Quando la finestra perde lo stato attivo per l'input (l'utente esce dall'app o viene visualizzata una finestra di dialogo), i flag non sono più validi. Analogamente, se rimuovi queste viste dalla gerarchia delle viste, i relativi flag non saranno più validi.

Per sincronizzare altri eventi della tua attività con modifiche alla visibilità dell'interfaccia utente del sistema (ad esempio, per nascondere la barra delle azioni o altri controlli dell'interfaccia utente quando l'UI di sistema è nascosta), devi registrare un View.OnSystemUiVisibilityChangeListener per ricevere una notifica quando la visibilità della barra di sistema o della barra di navigazione cambia.

Consulta la classe OverscanActivity per una dimostrazione delle diverse opzioni dell'interfaccia utente di sistema.

Framework di input

Android 4.0 aggiunge il supporto per gli eventi di passaggio del cursore e nuovi eventi con stilo e pulsanti del mouse.

Eventi di passaggio del mouse

La classe View ora supporta eventi "al passaggio del mouse" per consentire interazioni più complete mediante l'uso di dispositivi puntatori (come un mouse o altri dispositivi che azionano un cursore sullo schermo).

Per ricevere eventi di passaggio del mouse su una vista, implementa View.OnHoverListener e registralo con setOnHoverListener(). Quando si verifica un evento di passaggio del mouse nella visualizzazione, il listener riceve una chiamata a onHover(), che fornisce l'elemento View che ha ricevuto l'evento e un MotionEvent che descrive il tipo di evento di passaggio del mouse che si è verificato. L'evento di passaggio del mouse può essere uno dei seguenti:

View.OnHoverListener dovrebbe restituire un valore true da onHover() se gestisce l'evento di passaggio del mouse. Se l'ascoltatore restituisce false, l'evento di passaggio del mouse verrà inviato alla vista principale come di consueto.

Se la tua applicazione utilizza pulsanti o altri widget che cambiano aspetto in base allo stato corrente, puoi usare l'attributo android:state_hovered in un elenco di stati disegnabile per fornire uno sfondo diverso da disegnare quando il cursore passa sopra la visualizzazione.

Per una dimostrazione dei nuovi eventi di passaggio del mouse, consulta la classe Hover in ApiDemos.

Eventi relativi allo stilo e al pulsante del mouse

Android ora fornisce API per ricevere input da un dispositivo di input con lo stilo, come una periferica per tablet digitalizzatore o un touchscreen abilitato per stilo.

L'input dello stilo funziona in modo simile all'input del tocco o del mouse. Quando lo stilo è a contatto con il digitalizzatore, le applicazioni ricevono eventi touch come quando si utilizza un dito per toccare il display. Quando lo stilo passa sopra il digitalizzatore, le applicazioni ricevono eventi di passaggio del mouse come quando il puntatore del mouse viene spostato sul display quando non viene premuto alcun pulsante.

L'applicazione può distinguere tra input dito, mouse, stilo e gomma eseguendo una query sul "tipo di strumento" associato a ciascun puntatore in MotionEvent utilizzando getToolType(). I tipi di strumenti attualmente definiti sono: TOOL_TYPE_UNKNOWN, TOOL_TYPE_FINGER, TOOL_TYPE_MOUSE, TOOL_TYPE_STYLUS e TOOL_TYPE_ERASER. Se esegui una query sul tipo di strumento, l'applicazione può scegliere di gestire l'input dello stilo in modi diversi dall'input del dito o del mouse.

L'applicazione può anche eseguire query su quali pulsanti del mouse o dello stilo vengono premuti eseguendo query sullo "stato del pulsante" di un elemento MotionEvent utilizzando getButtonState(). Gli stati del pulsante attualmente definiti sono: BUTTON_PRIMARY, BUTTON_SECONDARY, BUTTON_TERTIARY, BUTTON_BACK e BUTTON_FORWARD. Per praticità, i pulsanti Avanti e Indietro del mouse vengono associati automaticamente ai tasti KEYCODE_BACK e KEYCODE_FORWARD. L'applicazione può gestire questi tasti per supportare la navigazione avanti e indietro basata sui pulsanti del mouse.

Oltre a misurare con precisione la posizione e la pressione di un contatto, alcuni dispositivi di inserimento dello stilo segnalano anche la distanza tra la punta dello stilo e il digitalizzatore, l'angolo di inclinazione dello stilo e l'angolo di orientamento dello stilo. L'applicazione può eseguire query su queste informazioni utilizzando getAxisValue() con i codici degli assi AXIS_DISTANCE, AXIS_TILT e AXIS_ORIENTATION.

Per una dimostrazione dei tipi di strumenti, degli stati dei pulsanti e dei nuovi codici degli assi, consulta la classe TouchPaint in ApiDemos.

Proprietà

La nuova classe Property fornisce un modo rapido, efficiente e semplice per specificare una proprietà su qualsiasi oggetto, consentendo ai chiamanti di impostare/ottenere in modo generico valori sugli oggetti di destinazione. Inoltre, consente la funzionalità di trasferimento dei riferimenti a campi/metodi e permette al codice di impostare/ottenere valori della proprietà senza conoscere i dettagli di quali sono i campi/metodi.

Ad esempio, se vuoi impostare il valore del campo bar sull'oggetto foo, in precedenza devi farlo:

Kotlin

foo.bar = value

Java

foo.bar = value;

In precedenza, se vuoi chiamare il setter per un campo privato sottostante bar, procedi come segue:

Kotlin

foo.setBar(value)

Java

foo.setBar(value);

Tuttavia, se si vuole passare l'istanza foo e avere un altro codice impostato sul valore bar, non c'è modo di farlo prima di Android 4.0.

Utilizzando la classe Property, puoi dichiarare un oggetto Property BAR nella classe Foo in modo da poter impostare il campo sull'istanza foo della classe Foo in questo modo:

Kotlin

BAR.set(foo, value)

Java

BAR.set(foo, value);

La classe View ora sfrutta la classe Property per consentirti di impostare vari campi, ad esempio le proprietà di trasformazione che sono state aggiunte in Android 3.0 (ROTATION, ROTATION_X, TRANSLATION_X e così via).

La classe ObjectAnimator utilizza anche la classe Property, quindi puoi creare un ObjectAnimator con Property, che è più veloce, più efficiente e più sicuro per il tipo rispetto all'approccio basato su stringhe.

Accelerazione hardware

A partire da Android 4.0, l'accelerazione hardware per tutte le finestre è attivata per impostazione predefinita se l'applicazione ha impostato targetSdkVersion o minSdkVersion su “14" o versioni successive. In genere, l'accelerazione hardware genera animazioni più fluide, scorrimento più fluido e prestazioni e risposta all'interazione dell'utente migliori in generale.

Se necessario, puoi disattivare manualmente l'accelerazione hardware con l'attributo hardwareAccelerated per singoli elementi <activity> o per l'elemento <application>. In alternativa, puoi disattivare l'accelerazione hardware per singole viste chiamando setLayerType(LAYER_TYPE_SOFTWARE).

Per ulteriori informazioni sull'accelerazione hardware, incluso un elenco delle operazioni di disegno non supportate, consulta il documento Accelerazione hardware.

Modifiche JNI

Nelle versioni precedenti di Android, i riferimenti locali di JNI non erano handle indiretti; Android utilizzava i puntatori diretti. Questo non era un problema, purché il garbage collector non avesse spostato gli oggetti, ma sembrava funzionare perché consentiva di scrivere codice con bug. In Android 4.0 il sistema usa riferimenti indiretti per rilevare questi bug.

Tutto quello che devi sapere sui riferimenti locali di JNI è descritto in "Riferimenti locali e globali" nei suggerimenti su JNI. In Android 4.0, CheckJNI è stato migliorato per rilevare questi errori. Visita il Blog per sviluppatori Android per leggere il prossimo post sugli errori comuni dei riferimenti JNI e su come correggerli.

Questa modifica all'implementazione JNI riguarda solo le app destinate ad Android 4.0 impostando targetSdkVersion o minSdkVersion su “14" o versioni successive. Se hai impostato questi attributi su un valore inferiore, i riferimenti locali JNI si comportano come nelle versioni precedenti.

WebKit

  • WebKit aggiornato alla versione 534.30
  • Supporto per i caratteri indiani (devanagari, bengalese e tamil, incluso il supporto dei caratteri complessi necessario per combinare i glifi) in WebView e il browser integrato
  • Supporto per i caratteri etiopi, georgiani e armeni in WebView e nel browser integrato
  • Il supporto per WebDriver ti consente di testare più facilmente le app che usano WebView

Browser Android

L'applicazione Browser aggiunge le seguenti funzionalità per supportare le applicazioni web:

Autorizzazioni

Di seguito sono riportate le nuove autorizzazioni:

Funzionalità dispositivo

Di seguito sono riportate le nuove funzionalità dei dispositivi:

  • FEATURE_WIFI_DIRECT: dichiara che l'applicazione utilizza il Wi-Fi per le comunicazioni peer-to-peer.

Per una visualizzazione dettagliata di tutte le modifiche all'API in Android 4.0 (livello API 14), consulta il report sulle differenze delle API.

API precedenti

Oltre a tutto quanto riportato sopra, Android 4.0 supporta naturalmente tutte le API delle release precedenti. Poiché la piattaforma Android 3.x è disponibile solo per i dispositivi con schermi di grandi dimensioni, se stai sviluppando principalmente per smartphone, potresti non essere a conoscenza di tutte le API aggiunte ad Android in queste release recenti.

Ecco alcune delle API più importanti che potresti non aver notato e ora disponibili anche sui telefoni:

Android 3.0
  • Fragment: un componente del framework che consente di separare elementi distinti di un'attività in moduli autonomi che definiscono la propria UI e il proprio ciclo di vita. Consulta la guida per gli sviluppatori relativa ai frammenti.
  • ActionBar: una sostituzione per la tradizionale barra del titolo nella parte superiore della finestra delle attività. Include il logo dell'applicazione nell'angolo a sinistra e fornisce una nuova interfaccia per le voci di menu. Consulta la guida per gli sviluppatori della barra delle azioni.
  • Loader: un componente del framework che facilita il caricamento asincrono dei dati in combinazione con i componenti dell'interfaccia utente per caricare i dati in modo dinamico senza bloccare il thread principale. Consulta la guida per gli sviluppatori relativa ai Caricatori.
  • Appunti di sistema: le applicazioni possono copiare e incollare dati (al di là del semplice testo) da e verso gli appunti di sistema. I dati ritagliati possono essere testo normale, un URI o un intent. Consulta la guida per gli sviluppatori Copia e incolla.
  • Trascinamento: un insieme di API integrate nel framework di visualizzazione che facilita le operazioni di trascinamento. Consulta la guida per gli sviluppatori relativa al trascinamento.
  • Un framework di animazione flessibile completamente nuovo ti consente di animare le proprietà arbitrarie di qualsiasi oggetto (visualizzazione, disegnabile, frammento, oggetto o qualsiasi altro elemento) e di definire aspetti dell'animazione come la durata, l'interpolazione, la ripetizione e altro ancora. Il nuovo framework rende le animazioni in Android più semplici che mai. Consulta la guida per gli sviluppatori Animazione proprietà.
  • Grafica e motore di calcolo RenderScript: RenderScript offre un'API di calcolo e rendering di grafica 3D ad alte prestazioni a livello nativo, che puoi scrivere in C (standard C99), fornendo le prestazioni che ti aspetti da un ambiente nativo, pur mantenendo la portabilità su diverse CPU e GPU. Consulta la guida per gli sviluppatori di RenderScript.
  • Grafica 2D con accelerazione hardware. Ora puoi attivare il renderer OpenGL per la tua applicazione impostando {android:hardwareAccelerated="true"} nell'elemento <application> dell'elemento manifest o per singoli elementi <activity>. In questo modo, le animazioni sono più fluide, lo scorrimento è più fluido e in generale le prestazioni e la risposta all'interazione dell'utente sono migliori.

    Nota: se imposti minSdkVersion o targetSdkVersion dell'applicazione su "14" o su un valore superiore, l'accelerazione hardware è abilitata per impostazione predefinita.

  • E molto altro ancora. Per ulteriori informazioni, leggi le note relative alla piattaforma Android 3.0.
Android 3.1
  • API USB: nuove API potenti per integrare le periferiche connesse con le applicazioni Android. Le API si basano su uno stack USB e su servizi integrati nella piattaforma, compreso il supporto per le interazioni con l'host USB e con i dispositivi. Consulta la guida per gli sviluppatori Host USB e accessori.
  • API MTP/PTP: le applicazioni possono interagire direttamente con le videocamere connesse e altri dispositivi PTP per ricevere notifiche quando i dispositivi vengono collegati e rimossi, per gestire i file e l'archiviazione su tali dispositivi e per trasferire file e metadati da e verso questi dispositivi. L'API MTP implementa il sottoinsieme PTP (Picture Transfer Protocol) della specifica MTP (Media Transfer Protocol). Consulta la documentazione di android.mtp.
  • API RTP: Android espone un'API al suo stack RTP (Real-time Transport Protocol) integrato, che può essere utilizzato dalle applicazioni per gestire lo streaming di dati on demand o interattivo. In particolare, le app che offrono VOIP, push-to-talk, conferenze e streaming audio possono utilizzare l'API per avviare sessioni e trasmettere o ricevere stream di dati su qualsiasi rete disponibile. Consulta la documentazione di android.net.rtp.
  • Supporto per joystick e altri input di movimento generici.
  • Consulta le note sulla piattaforma Android 3.1 per scoprire molte altre nuove API.
Android 3.2
  • Le nuove schermate supportano API che ti consentono di avere un maggiore controllo sulla modalità di visualizzazione delle applicazioni su schermi di dimensioni diverse. L'API estende il modello di supporto schermo esistente con la possibilità di scegliere con precisione come target specifici intervalli di dimensioni degli schermi in base alle dimensioni, misurate in unità di pixel indipendenti dalla densità (ad esempio 600 dp o 720 dp in larghezza), anziché in base alle dimensioni generalizzate dello schermo (ad esempio grande o xlarge). Ad esempio, questo aspetto è importante per distinguere un dispositivo da 5" da un dispositivo da 7", che in genere vengono raggruppati come schermi "grandi". Vedi il post del blog Nuovi strumenti per la gestione delle dimensioni degli schermi.
  • Nuove costanti per <uses-feature> per dichiarare i requisiti di orientamento dello schermo orizzontale o verticale.
  • La configurazione delle "dimensioni dello schermo" del dispositivo ora cambia quando viene modificato l'orientamento dello schermo. Se la tua app ha come target il livello API 13 o successivo, devi gestire la modifica della configurazione di "screenSize" se vuoi gestire anche la modifica della configurazione di "orientation". Per ulteriori informazioni, visita la pagina android:configChanges.
  • Consulta le note sulla piattaforma Android 3.2 per altre nuove API.

Livello API

All'API Android 4.0 viene assegnato un identificatore di numero intero, 14, archiviato nel sistema stesso. Questo identificatore, chiamato "livello API", consente al sistema di determinare correttamente se un'applicazione è compatibile con il sistema prima di installarla.

Per utilizzare nella tua applicazione le API introdotte in Android 4.0, devi compilare l'applicazione su una piattaforma Android che supporti il livello API 14 o successivo. A seconda delle tue esigenze, potresti anche dover aggiungere un attributo android:minSdkVersion="14" all'elemento <uses-sdk>.

Per ulteriori informazioni, consulta Che cos'è il livello API?