Livello API: 16
Android 4.1 (JELLY_BEAN
)
è una versione avanzata della piattaforma che offre un miglioramento
del rendimento e dell'esperienza utente. Aggiunge nuove funzionalità per gli utenti e gli sviluppatori di app. Questo documento fornisce un'introduzione alle nuove API più importanti e utili per gli sviluppatori di app.
In qualità di sviluppatore di app, Android 4.1 è disponibile in SDK Manager come immagine di sistema che puoi eseguire nell'emulatore Android e come piattaforma SDK su cui puoi creare la tua app. Ti consigliamo di scaricare l'immagine di sistema e la piattaforma il prima possibile per creare e testare la tua app su Android 4.1.
Per ottimizzare meglio la tua app per i dispositivi con Android 4.1,
devi impostare targetSdkVersion
su
"16"
, installarla su un'immagine di sistema Android 4.1,
testarla e poi pubblicare un aggiornamento con questa modifica.
Puoi
utilizzare le API in Android 4.1 e supportare contemporaneamente le versioni precedenti aggiungendo
condizioni al codice che controllano il livello dell'API di sistema prima di eseguire
le API non supportate dal tuo minSdkVersion
.
Per scoprire di più su come mantenere la compatibilità con le versioni precedenti, leggi l'articolo Creare UI compatibili con le versioni precedenti.
Per saperne di più sul funzionamento dei livelli API, consulta Che cos'è il livello API?
Componenti dell'app
Servizi isolati
Se specifichi android:isolatedProcess="true"
nel
tag <service>
, Service
verrà eseguito
sotto il proprio processo ID utente isolato che non ha autorizzazioni proprie.
Gestione della memoria
Nuove costanti ComponentCallbacks2
come TRIM_MEMORY_RUNNING_LOW
e TRIM_MEMORY_RUNNING_CRITICAL
forniscono ai processi in primo piano maggiori informazioni sullo stato della memoria prima che il sistema chiami onLowMemory()
.
Il nuovo metodo getMyMemoryState(ActivityManager.RunningAppProcessInfo)
consente di recuperare lo stato della memoria generale.
Fornitori di contenuti
Un nuovo metodo, acquireUnstableContentProviderClient()
, ti consente di accedere a un ContentProviderClient
che potrebbe essere "instabile" in modo che la tua app non abbia arresti anomali se il fornitore di contenuti ne ha uno. È utile quando interagisci con i fornitori di contenuti in un'app distinta.
Sfondi animati
Nuovo protocollo di intent per avviare direttamente l'attività di anteprima dello sfondo animato, in modo da aiutare gli utenti a selezionare facilmente lo sfondo animato senza dover uscire dalla tua app e navigare nel selettore di sfondi della schermata Home.
Per avviare il selettore di sfondi animati, chiama startActivity()
con un Intent
utilizzando
ACTION_CHANGE_LIVE_WALLPAPER
e un extra
che specifica lo sfondo animato ComponentName
come stringa in EXTRA_LIVE_WALLPAPER_COMPONENT
.
Navigazione nello stack di app
Android 4.1 semplifica notevolmente l'implementazione dei pattern di design appropriati per la navigazione verso l'alto.
Devi solo aggiungere android:parentActivityName
a ogni elemento <activity>
nel
tuo file manifest. Il sistema utilizza queste informazioni per aprire l'attività appropriata quando l'utente
preme il pulsante Su nella barra delle azioni (e termina anche l'attività corrente). Pertanto, se dichiari android:parentActivityName
per ogni attività, non hai bisogno del metodo onOptionsItemSelected()
per gestire gli eventi di clic sull'icona dell'app della barra delle app. Ora il sistema gestisce questo evento e riprende o crea l'attività appropriata.
Questa funzionalità è particolarmente utile per gli scenari in cui l'utente accede a una delle attività della tua app tramite un'intent di "approfondimento", ad esempio da una notifica o da un'intent di un'altra app (come descritto nella guida alla progettazione per la navigazione tra le app). Quando
l'utente accede alla tua attività in questo modo, la tua app potrebbe non avere naturalmente una serie di attività
precedenti che possono essere riprese quando l'utente torna indietro. Tuttavia, quando fornisci l'attributo android:parentActivityName
per le tue attività, il sistema riconosce
se la tua app contiene già uno stack di attività principali e, in caso contrario, crea
uno stack sintetico che contiene tutte le attività principali.
Nota: quando l'utente accede a un'attività secondaria nella tua app e crea una nuova attività per la tua app, il sistema inserisce effettivamente la serie di attività principali nell'attività. Di conseguenza, puoi anche premere il pulsante Indietro per tornare indietro nello stack di attività principali.
Quando il sistema crea uno stack a ritroso sintetico per la tua app, genera un Intent
di base per creare una nuova istanza di ogni attività principale. Pertanto, non esiste alcun stato salvato per le attività principali, come ci si aspetterebbe se l'utente avesse navigato in modo naturale in ogni attività. Se una delle attività principali mostra normalmente un'interfaccia utente che dipende dal contesto dell'utente, queste informazioni sul contesto non saranno presenti e dovrai fornirle quando l'utente torna indietro nello stack. Ad esempio, se l'utente sta visualizzando un album in un'app di musica, la navigazione verso l'alto potrebbe portarlo a un'attività che elenca tutti gli album di un determinato genere musicale. In questo caso, se è necessario creare lo stack, è necessario comunicare all'attività principale a quale genere appartiene l'album corrente, in modo che possa visualizzare l'elenco corretto se l'utente proveniva effettivamente da quell'attività. Per fornire queste informazioni a un'attività principale sintetica, devi sostituire il metodo onPrepareNavigateUpTaskStack()
. In questo modo
viene fornito un oggetto TaskStackBuilder
creato dal sistema per
sintetizzare le attività padre. TaskStackBuilder
contiene oggetti Intent
che il sistema utilizza per creare ogni attività principale. Nell'implementazione di onPrepareNavigateUpTaskStack()
, puoi modificare Intent
appropriato per aggiungere dati aggiuntivi che l'attività principale può utilizzare per determinare il contesto appropriato e visualizzare l'interfaccia utente appropriata.
Quando il sistema crea TaskStackBuilder
, aggiunge gli oggetti Intent
utilizzati per creare le attività principali nell'ordine logico, partendo dalla parte superiore dell'albero delle attività. Pertanto, l'ultimo Intent
aggiunto all'array interno è il diretto superiore dell'attività corrente. Se
vuoi modificare Intent
per l'elemento principale dell'attività, determina prima
la lunghezza dell'array con getIntentCount()
e passa questo
valore a editIntentAt()
.
Se la struttura dell'app è più complessa, sono disponibili diverse altre API che ti consentono di gestire il comportamento della navigazione Azione precedente e personalizzare completamente la pila di ritorno sintetica. Ecco alcune delle API che ti offrono un controllo aggiuntivo:
onNavigateUp()
- Sostituisci questo valore per eseguire un'azione personalizzata quando l'utente preme il pulsante Su.
navigateUpTo(Intent)
- Chiama questa funzione per completare l'attività corrente e passare all'attività indicata dal valore fornito
Intent
. Se l'attività esiste nello stack posteriore, ma non è l'attività principale più prossima, anche tutte le altre attività tra l'attività corrente e quella specificata con l'intent vengono terminate anch'essa. getParentActivityIntent()
- Chiama questo metodo per ottenere il
Intent
che avvia l'elemento parente logico per l'attività corrente. shouldUpRecreateTask(Intent)
- Chiama questo metodo per verificare se è necessario creare uno stack di ritorno sintetico per eseguire la navigazione verso l'alto. Restituisce true se è necessario creare uno stack sintetico, false se lo stack appropriato esiste già.
finishAffinity()
- Chiama questo metodo per completare l'attività corrente e tutte le attività principali con la stessa affinità di attività che sono collegate all'attività corrente.
Se sostituisci i comportamenti predefiniti come
onNavigateUp()
, devi chiamare questo metodo quando crei una pila di ritorno sintetica durante la navigazione verso l'alto. onCreateNavigateUpTaskStack
- Sostituisci questo valore se devi controllare completamente la modalità di creazione della serie di attività sintetiche. Se vuoi semplicemente aggiungere alcuni dati aggiuntivi agli intent per la pila di ritorno, devi sostituire
onPrepareNavigateUpTaskStack()
Tuttavia, la maggior parte delle app non ha bisogno di utilizzare queste API o di implementare onPrepareNavigateUpTaskStack()
, ma può ottenere il comportamento corretto semplicemente aggiungendo android:parentActivityName
a ogni elemento <activity>
.
Multimediale
Codec multimediali
La classe MediaCodec
fornisce l'accesso ai codec multimediali di basso livello per la codifica
e la decodifica dei contenuti multimediali. Puoi creare un'istanza di MediaCodec
chiamando createEncoderByType()
per codificare i contenuti multimediali o chiamando createDecoderByType()
per decodificarli. Ognuno di questi metodi accetta un tipo MIME per il tipo di contenuti multimediali che vuoi codificare o decodificare, ad esempio "video/3gpp"
o "audio/vorbis"
.
Dopo aver creato un'istanza di MediaCodec
, puoi chiamare configure()
per specificare proprietà come il formato multimediale o se i contenuti sono criptati o meno.
Indipendentemente dal fatto che tu stia codificando o decodificando i contenuti multimediali, il resto della procedura è lo stesso dopo aver creato il file MediaCodec
. Per prima cosa, chiama getInputBuffers()
per ottenere un array di oggetti ByteBuffer
di input e getOutputBuffers()
per ottenere un array di oggetti ByteBuffer
di output.
Quando è tutto pronto per la codifica o la decodifica, chiama dequeueInputBuffer()
per ottenere la posizione dell'indice di ByteBuffer
(dall'array di buffer di input) da utilizzare per inserire i contenuti media di origine. Dopo aver compilato ByteBuffer
con i tuoi contenuti multimediali di origine, rilascia la proprietà
del buffer chiamando queueInputBuffer()
.
Analogamente per il buffer di output, chiama dequeueOutputBuffer()
per ottenere la posizione dell'indice di ByteBuffer
dove riceverai i risultati. Dopo aver letto l'output da ByteBuffer
, svincola la proprietà chiamando releaseOutputBuffer()
.
Puoi gestire i dati multimediali criptati nei codec chiamando queueSecureInputBuffer()
in combinazione con le API MediaCrypto
anziché il normale queueInputBuffer()
.
Per ulteriori informazioni su come utilizzare i codec, consulta la documentazione di MediaCodec
.
Registrare l'audio su cue
Il nuovo metodo startRecording()
consente di avviare la registrazione audio in base a un cue definito da un MediaSyncEvent
.
L'MediaSyncEvent
specifica una sessione audio
(ad esempio quella definita da MediaPlayer
) che, una volta completata, attiva
il registratore audio per iniziare la registrazione. Ad esempio, puoi utilizzare questa funzionalità per riprodurre un segnale acustico che indica l'inizio di una sessione di registrazione e che la registrazione inizia automaticamente, in modo da non dover sincronizzare manualmente il tono e l'inizio della registrazione.
Tracce di testo sincronizzato
MediaPlayer
ora gestisce sia le tracce di testo in banda sia quelle out-of-band.
Le tracce di testo in banda sono disponibili come tracce di testo all'interno di una sorgente multimediale MP4 o 3GPP. I canali di testo out-of-band possono essere aggiunti come origine testo esterna tramite il metodo addTimedTextSource()
. Dopo aver aggiunto tutte le origini di canali di testo esterni, deve essere chiamato getTrackInfo()
per ottenere l'elenco aggiornato di tutti i canali disponibili in un'origine dati.
Per impostare la traccia da usare con MediaPlayer
, devi chiamare selectTrack()
usando la posizione di indice della traccia che vuoi utilizzare.
Per ricevere una notifica quando la traccia di testo è pronta per la riproduzione, implementa l'interfaccia MediaPlayer.OnTimedTextListener
e passala a setOnTimedTextListener()
.
Effetti audio
La classe AudioEffect
ora supporta tipi di pre-elaborazione audio aggiuntivi durante l'acquisizione dell'audio:
- La funzionalità di cancellazione dell'eco acustico (AEC) con
AcousticEchoCanceler
rimuove il contributo del segnale ricevuto dalla parte remota dal segnale audio acquisito. - Il controllo automatico del guadagno (AGC) con
AutomaticGainControl
normalizza automaticamente l'uscita del segnale acquisito. - La funzionalità di soppressione del rumore (NS) con
NoiseSuppressor
rimuove il rumore di fondo dal segnale acquisito.
Puoi applicare questi effetti di preelaborazione all'audio acquisito con un AudioRecord
utilizzando una delle sottoclassi AudioEffect
.
Nota: non è garantito che tutti i dispositivi supportino questi effetti, quindi devi sempre verificare prima la disponibilità chiamando isAvailable()
sul corrispondente
classe di effetti audio.
Riproduzione senza interruzioni
Ora puoi eseguire la riproduzione senza interruzioni tra due oggettiMediaPlayer
distinti. In qualsiasi momento prima del termine del primo MediaPlayer
, chiama setNextMediaPlayer()
e Android tenta di avviare il secondo player nel momento in cui si arresta il primo.
Fotocamera
Movimento della messa a fuoco automatica
La nuova interfaccia Camera.AutoFocusMoveCallback
ti consente di ascoltare
le modifiche al movimento dell'autofocus. Puoi registrare la tua interfaccia con setAutoFocusMoveCallback()
. Quando la fotocamera è in modalità di messa a fuoco automatica continua (FOCUS_MODE_CONTINUOUS_VIDEO
o FOCUS_MODE_CONTINUOUS_PICTURE
), riceverai una chiamata al numero onAutoFocusMoving()
, che ti indica se la messa a fuoco automatica ha iniziato o interrotto il movimento.
Suoni fotocamera
La classe MediaActionSound
fornisce un semplice set di API per produrre
suoni standard emessi dalla videocamera o da altre azioni multimediali. Devi utilizzare queste API per riprodurre
il suono appropriato quando crei una fotocamera o una videocamera personalizzata.
Per riprodurre un suono, crea semplicemente un'istanza per un oggetto MediaActionSound
, richiama
load()
per precaricare il suono desiderato, quindi
chiama play()
al momento opportuno.
Connettività
Android Beam
Android Beam™ ora supporta i trasferimenti di payload di grandi dimensioni tramite Bluetooth. Quando definisci i dati
da trasferire con il nuovo metodo setBeamPushUris()
o con la nuova interfaccia di callback NfcAdapter.CreateBeamUrisCallback
, Android
trasferisce i dati al Bluetooth o a un altro mezzo di trasporto alternativo
per ottenere velocità di trasferimento più elevate. Questa opzione è particolarmente utile per payload di grandi dimensioni, come file di immagini e audio, e non richiede l'accoppiamento visibile tra i dispositivi. Non è richiesta alcuna operazione aggiuntiva da parte della tua app per usufruire dei trasferimenti tramite Bluetooth.
Il metodo setBeamPushUris()
accetta un array di oggetti Uri
che specificano i dati che vuoi trasferire dalla tua app. In alternativa, puoi implementare l'interfaccia NfcAdapter.CreateBeamUrisCallback
, che puoi specificare per la tua attività chiamando setBeamPushUrisCallback()
.
Quando utilizzi l'interfaccia di callback, il sistema chiama il metodo createBeamUris()
dell'interfaccia quando l'utente esegue una condivisione con Android Beam in modo da poter definire gli URI da condividere al momento della condivisione.
Questa operazione è utile se gli URI da condividere possono variare a seconda del contesto dell'utente all'interno dell'attività, mentre la chiamata a setBeamPushUris()
è utile quando gli URI da condividere sono invariati e puoi definirli in sicurezza in anticipo.
Rilevamento servizi di rete
Android 4.1 aggiunge il supporto per il rilevamento dei servizi basato su DNS multicast, che ti consente di trovare e connetterti ai servizi offerti da dispositivi peer tramite Wi-Fi, come dispositivi mobili, stampanti, fotocamere, lettori multimediali e altri dispositivi registrati sulla rete locale.
Il nuovo pacchetto android.net.nsd
contiene le nuove API che ti consentono di trasmettere i tuoi servizi sulla rete locale, rilevare i dispositivi locali sulla rete e connetterti ai dispositivi.
Per registrare il servizio, devi prima creare un oggetto NsdServiceInfo
e definire le varie proprietà del servizio con metodi come
setServiceName()
,
setServiceType()
e
setPort()
.
Poi devi implementare NsdManager.RegistrationListener
e passarlo a registerService()
con il tuo NsdServiceInfo
.
Per scoprire i servizi sulla rete, implementa NsdManager.DiscoveryListener
e passalo a discoverServices()
.
Quando NsdManager.DiscoveryListener
riceve chiamate di ritorno relative ai servizi trovati, devi risolvere il servizio chiamando resolveService()
, passandogli un'implementazione di NsdManager.ResolveListener
che riceve un oggetto NsdServiceInfo
contenente informazioni sul servizio scoperto, in modo da poter avviare la connessione.
Rilevamento dei servizi P2P Wi-Fi
Le API Wi-Fi P2P sono state migliorate in Android 4.1 per supportare il rilevamento dei servizi di preassociazione nel WifiP2pManager
. In questo modo puoi rilevare e filtrare i dispositivi nelle vicinanze in base ai servizi che utilizzano il Wi-Fi P2P prima di connetterti a uno, mentre la funzionalità Rilevamento servizi di rete ti consente di rilevare un servizio su una rete connessa esistente (ad esempio una rete Wi-Fi locale).
Per trasmettere la tua app come servizio tramite Wi-Fi in modo che altri dispositivi possano rilevare
la tua app e connettersi, chiama addLocalService()
con un
oggetto WifiP2pServiceInfo
che descriva i servizi dell'app.
Per avviare il rilevamento dei dispositivi nelle vicinanze tramite Wi-Fi, devi prima decidere se comunicare utilizzando Bonjour o UPnP. Per utilizzare Bonjour, configura prima alcuni ascoltatori di callback con setDnsSdResponseListeners()
, che accetta sia WifiP2pManager.DnsSdServiceResponseListener
che WifiP2pManager.DnsSdTxtRecordListener
. Per utilizzare Upnp, chiama
setUpnpServiceResponseListener()
, che accetta un WifiP2pManager.UpnpServiceResponseListener
.
Prima di poter iniziare a scoprire i servizi sui dispositivi locali, devi anche chiamare addServiceRequest()
. Quando WifiP2pManager.ActionListener
passato a questo metodo riceve un callback corretto, puoi iniziare a scoprire i servizi sui dispositivi locali chiamando discoverServices()
.
Quando vengono rilevati i servizi locali, riceverai una chiamata al numero WifiP2pManager.DnsSdServiceResponseListener
o WifiP2pManager.UpnpServiceResponseListener
, a seconda che tu abbia eseguito la registrazione per l'utilizzo di Bonjour o Upnp. Il callback ricevuto in entrambi i casi contiene un oggetto WifiP2pDevice
che rappresenta il dispositivo peer.
Utilizzo della rete
Il nuovo metodo isActiveNetworkMetered()
ti consente di controllare se il dispositivo è attualmente connesso a una rete con misuratore. Controllando questo stato
prima di eseguire transazioni di rete intensive, puoi gestire l'utilizzo dei dati che potrebbe comportare dei costi per gli utenti e prendere
decisioni informate se eseguire le transazioni ora o in un secondo momento (ad esempio quando
il dispositivo si connette alla rete Wi-Fi).
Accessibilità
API dei servizi di accessibilità
La copertura delle API di servizi di accessibilità è aumentata notevolmente in Android 4.1. Ora consente di creare servizi che monitorano e rispondono a più eventi di input, come gesti complessi, utilizzando onGesture()
e altri eventi di input tramite aggiunte alle classi AccessibilityEvent
, AccessibilityNodeInfo
e AccessibilityRecord
.
I servizi di accessibilità possono anche eseguire azioni per conto dell'utente, tra cui fare clic, scorrimento e spostamento del testo utilizzando performAction
e setMovementGranularities
. Il metodo performGlobalAction()
consente inoltre ai servizi di eseguire azioni come Indietro, Home e aprire App e notifiche recenti.
Navigazione nell'app personalizzabile
Quando crei un'app per Android, ora puoi personalizzare gli schemi di navigazione individuando gli elementi e i widget di input che possono essere attivati utilizzando findFocus()
e focusSearch()
e impostando il focus utilizzando setAccessibilityFocused()
.
Widget più accessibili
La nuova classe android.view.accessibility.AccessibilityNodeProvider
consente di mostrare visualizzazioni personalizzate complesse ai servizi di accessibilità in modo che possano presentare le informazioni in modo più accessibile. android.view.accessibility.AccessibilityNodeProvider
consente a un widget per gli utenti con contenuti avanzati, ad esempio una griglia del calendario, di presentare una struttura semantica logica per i servizi di accessibilità completamente separata dalla struttura del layout del widget. Questa struttura semantica consente ai servizi di accessibilità di presentare un modello di interazione più utile per gli utenti con disturbi visivi.
Copy and Paste
Copia e incolla con intent
Ora puoi associare un oggetto ClipData
a un Intent
utilizzando il metodo setClipData()
.
Questo è particolarmente utile quando utilizzi un'intent per trasferire più URI content:
a un'altra applicazione, ad esempio quando condividi più documenti. Gli URI content:
forniti in questo modo rispetteranno anche i flag dell'intent per offrire l'accesso in lettura o scrittura, consentendoti di concedere l'accesso a più URI in un intent. Quando si avvia un intent ACTION_SEND
o ACTION_SEND_MULTIPLE
, gli URI forniti nell'intent vengono ora propagati automaticamente all'intent ClipData
in modo che il destinatario possa concedergli l'accesso.
Supporto per gli stili HTML e stringa
La classe ClipData
ora supporta il testo con stili applicati (come stringhe con stile HTML o
Android). Puoi aggiungere testo con stile HTML a ClipData
con newHtmlText()
.
Renderscript
La funzionalità di calcolo di Renderscript è stata migliorata con le seguenti funzionalità:
- Supporto di più kernel all'interno di uno script.
- Supporto per la lettura dall'allocazione con sampler filtrati da Compute in una nuova API di script
rsSample
. - Supporto di diversi livelli di precisione FP in
#pragma
. - Supporto per eseguire query su informazioni aggiuntive dagli oggetti RS da uno script di calcolo.
- Numerosi miglioramenti delle prestazioni.
Sono disponibili anche nuovi pragma per definire la precisione in virgola mobile richiesta dai Renderscript di calcolo. In questo modo puoi attivare operazioni NEON come le operazioni matematiche vettoriali rapide sul percorso della CPU che altrimenti non sarebbero possibili con lo standard IEEE 754-2008 completo.
Nota:il motore grafico sperimentale Renderscript è stato ritirato.
Animazione
Animazioni di avvio dell'attività
Ora puoi lanciare Activity
utilizzando animazioni di zoom o animazioni personalizzate. Per specificare l'animazione che preferisci, utilizza le API ActivityOptions
per creare un Bundle
che puoi poi passare a uno dei metodi che avviano un'attività, ad esempio startActivity()
.
La classe ActivityOptions
include un metodo diverso per ogni
tipo di animazione che potresti voler mostrare all'apertura dell'attività:
makeScaleUpAnimation()
- Crea un'animazione che aumenta le dimensioni della finestra delle attività da una posizione iniziale specificata sullo schermo e da una dimensione iniziale specificata. Ad esempio, la schermata Home di Android 4.1 lo utilizza quando apri un'app.
makeThumbnailScaleUpAnimation()
- Crea un'animazione che aumenta le dimensioni della finestra delle attività a partire da una posizione specificata e da un'immagine in miniatura fornita. Ad esempio, la finestra App recenti in Android 4.1 lo utilizza quando si torna a un'app.
makeCustomAnimation()
- Crea un'animazione definita dalle tue risorse: una per l'apertura dell'attività e un'altra per l'interruzione dell'attività.
Animatore temporale
Il nuovo TimeAnimator
fornisce un semplice meccanismo di callback con TimeAnimator.TimeListener
che ti invia una notifica per ogni frame dell'animazione. Questo animatore non prevede impostazioni di durata, interpolazione o valore dell'oggetto. Il callback dell'ascoltatore riceve informazioni per ogni frame, tra cui il tempo totale trascorso e il tempo trascorso dal frame dell'animazione precedente.
Interfaccia utente
Notifiche
In Android 4.1, puoi creare notifiche con aree di contenuti più grandi, anteprime di immagini grandi, più pulsanti di azione e priorità configurabile.
Stili di notifica
Il nuovo metodo setStyle()
ti consente di specificare uno dei tre nuovi stili per le notifiche, ognuno dei quali offre una regione di contenuti più ampia. Per
specificare lo stile per la regione di contenuti di grandi dimensioni, passa setStyle()
uno dei seguenti oggetti:
Notification.BigPictureStyle
- Per le notifiche che includono un allegato di immagini di grandi dimensioni.
Notification.BigTextStyle
- Per le notifiche che includono molto testo, ad esempio una singola email.
Notification.InboxStyle
- Per le notifiche che includono un elenco di stringhe, ad esempio snippet di più email.
Azioni di notifica
Ora è supportato l'uso di un massimo di due pulsanti di azione nella parte inferiore del messaggio di notifica, indipendentemente dallo stile della notifica (normale o più grande).
Per aggiungere un pulsante di azione, chiama addAction()
. Questo metodo accetta tre argomenti: una risorsa drawable per un'icona, il testo del pulsante e un PendingIntent
che definisce l'azione da eseguire.
Priorità
Ora puoi indicare al sistema l'importanza della notifica per influire sull'ordine della notifica nell'elenco impostando la priorità con setPriority()
. Puoi passare uno dei cinque diversi livelli di priorità definiti dalle costanti PRIORITY_*
nella classe Notification
. Il valore predefinito è PRIORITY_DEFAULT
e sono disponibili due livelli superiori e due inferiori.
Le notifiche ad alta priorità sono quelle a cui gli utenti in genere vogliono rispondere rapidamente, come un nuovo messaggio istantaneo, un messaggio o un promemoria di un evento imminente. Le notifiche con priorità bassa sono, ad esempio, eventi nel calendario scaduti o promozioni di app.
Controlli per l'interfaccia utente di sistema
Android 4.0 (Ice Cream Sandwich) ha aggiunto nuovi flag per controllare la visibilità degli elementi dell'interfaccia utente di sistema, ad esempio per attenuare l'aspetto della barra di sistema o farla scomparire completamente sui cellulari.
Android 4.1 aggiunge alcuni altri flag che ti consentono di controllare ulteriormente l'aspetto degli elementi UI di sistema e il layout dell'attività in relazione a questi ultimi richiamando setSystemUiVisibility()
e passando i seguenti flag:
SYSTEM_UI_FLAG_FULLSCREEN
- Nasconde l'interfaccia utente di sistema non critica (ad esempio la barra di stato).
Se la tua attività utilizza la barra delle app in modalità overlay (attivando
android:windowActionBarOverlay
), questo flag nasconde anche la barra delle app e lo fa con un'animazione coordinata quando nasconde e mostra entrambe. SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- Imposta il layout dell'attività in modo da utilizzare la stessa area dello schermo disponibile quando hai attivato
SYSTEM_UI_FLAG_FULLSCREEN
anche se gli elementi dell'interfaccia utente di sistema sono ancora visibili. Anche se parti del layout verranno sovrapposte dall'UI di sistema, questa opzione è utile se la tua app nasconde e mostra spesso l'UI di sistema conSYSTEM_UI_FLAG_FULLSCREEN
, perché evita che il layout si adatti ai nuovi limiti di layout ogni volta che l'UI di sistema viene nascosta o visualizzata. SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- Imposta il layout delle attività in modo che utilizzi la stessa area dello schermo disponibile quando hai attivato
SYSTEM_UI_FLAG_HIDE_NAVIGATION
(aggiunto in Android 4.0) anche se gli elementi dell'interfaccia utente di sistema sono ancora visibili. Anche se alcune parti del layout verranno sovrapposte dalla barra di navigazione, questa opzione è utile se la tua app nasconde e mostra spesso la barra di navigazione conSYSTEM_UI_FLAG_HIDE_NAVIGATION
, perché evita che il layout si adatti ai nuovi limiti del layout ogni volta che la barra di navigazione viene nascosta o visualizzata. SYSTEM_UI_FLAG_LAYOUT_STABLE
- Ti consigliamo di aggiungere questo flag se utilizzi
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
e/oSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
per assicurarti che, quando chiamifitSystemWindows()
in una visualizzazione, i confini definiti rimangano coerenti rispetto allo spazio sullo schermo disponibile. In altre parole, con questo flag impostato,fitSystemWindows()
si comporterà come se la visibilità degli elementi dell'interfaccia utente di sistema rimanesse invariata anche dopo aver nascosto tutta l'interfaccia utente di sistema.
Per ulteriori discussioni sugli altri flag dell'interfaccia utente di sistema correlati, leggi informazioni su quelli aggiunti in Android 4.0.
Visualizzazioni remote
GridLayout
e ViewStub
ora sono visualizzazioni rimovibili, quindi puoi utilizzarle nei layout per i widget delle app e i layout personalizzati delle notifiche.
Famiglie di caratteri
Android 4.1 aggiunge altre varianti dello stile del carattere Roboto per un totale di 10 varianti, tutte utilizzabili dalle app. Ora le tue app hanno accesso all'intero insieme di varianti sia chiare che condensate.
L'insieme completo di varianti dei caratteri Roboto disponibili è:
- Periodici
- Corsivo
- Grassetto
- Grassetto corsivo
- Chiaro
- Corsivo chiaro
- Regolare condensato
- Corsivo condensato
- Grassetto condensato
- Condensed grassetto corsivo
Puoi applicare una di queste opzioni con il nuovo attributo fontFamily
in combinazione con l'attributo textStyle
.
I valori supportati per fontFamily
sono:
"sans-serif"
per Roboto normale"sans-serif-light"
per Roboto Light"sans-serif-condensed"
per Roboto Condensed
Puoi quindi applicare il grassetto e/o il corsivo con i valori textStyle
"bold"
e "italic"
. Puoi applicare entrambi come segue: android:textStyle="bold|italic"
.
Puoi anche usare Typeface.create()
.
Ad esempio, Typeface.create("sans-serif-light", Typeface.NORMAL)
.
Framework di input
Più dispositivi di input
La nuova classe InputManager
ti consente di eseguire query sull'insieme di dispositivi di input attualmente connessi e di registrarti per ricevere una notifica quando un nuovo dispositivo viene aggiunto, modificato o rimosso. Ciò è particolarmente utile se stai creando un gioco che supporta più giocatori e vuoi rilevare quanti controller sono collegati e quando vengono apportate modifiche al numero di controller.
Puoi eseguire query su tutti i dispositivi di input connessi chiamando
getInputDeviceIds()
. Restituisce un array di numeri interi, ciascuno dei quali è un ID per un dispositivo di input diverso. Puoi quindi chiamare
getInputDevice()
per acquisire
un InputDevice
per un ID dispositivo di input specificato.
Se vuoi ricevere notifiche quando i nuovi dispositivi di input vengono collegati, modificati o disconnessi,
implementa l'interfaccia InputManager.InputDeviceListener
e
registrala con registerInputDeviceListener()
.
Vibrazione per i controller di input
Se i dispositivi di input connessi hanno le proprie funzionalità di vibrazione, ora puoi controllarne la vibrazione utilizzando le API Vibrator
esistenti semplicemente chiamando getVibrator()
su InputDevice
.
Autorizzazioni
Di seguito sono riportate le nuove autorizzazioni:
READ_EXTERNAL_STORAGE
- Fornisce accesso in lettura protetto allo spazio di archiviazione esterno. In Android 4.1, per impostazione predefinita, tutte le applicazioni hanno ancora accesso in lettura. Questo cambierà in una release futura per richiedere che le applicazioni richiedano esplicitamente l'accesso in lettura utilizzando questa autorizzazione. Se la tua applicazione richiede già l'accesso in scrittura, otterrà automaticamente anche l'accesso in lettura. Esiste una nuova opzione per gli sviluppatori per attivare la limitazione dell'accesso in lettura, in modo che possano testare le proprie applicazioni in base al comportamento di Android in futuro.
- android.Manifest.permission.READ_USER_DICTIONARY
- Consente a un'applicazione di leggere il dizionario utente. Questo dovrebbe essere richiesto solo da un editor di dizionario come l'app Impostazioni o da un editor di dizionario come l'app Impostazioni.
READ_CALL_LOG
- Consente a un'applicazione di leggere il registro chiamate del sistema che contiene informazioni sulle chiamate in arrivo e in uscita.
WRITE_CALL_LOG
- Consente a un'applicazione di modificare il registro chiamate di sistema memorizzato sullo smartphone
- android.Manifest.permission.WRITE_USER_DICTIONARY
- Consente a un'applicazione di scrivere nel dizionario di parole dell'utente.
Funzionalità del dispositivo
Android 4.1 include una nuova dichiarazione di funzionalità per i dispositivi dedicati alla visualizzazione dell'interfaccia utente sullo schermo di una TV: FEATURE_TELEVISION
. Per dichiarare che la tua app richiede un'interfaccia TV, dichiara questa funzionalità nel file manifest con l'elemento <uses-feature>
:
<manifest ... > <uses-feature android:name="android.hardware.type.television" android:required="true" /> ... </manifest>
Questa funzionalità definisce "televisione" come una tipica esperienza televisiva in salotto: visualizzata su un grande schermo, con l'utente seduto lontano e la forma dominante di input è qualcosa come un d-pad e generalmente non tramite tocco o mouse/dispositivo con cursore.