Livello API: 16
Android 4.1 (JELLY_BEAN
) è un avanzamento della piattaforma che offre prestazioni ed esperienza utente migliorate. Aggiunge nuove funzionalità per utenti
e sviluppatori di app. Questo documento offre un'introduzione alle nuove API più utili
per gli sviluppatori di app.
In qualità di sviluppatore di app, puoi accedere ad Android 4.1 da SDK Manager come immagine di sistema che puoi eseguire nell'emulatore Android e come piattaforma SDK in base alla quale creare la tua app. Devi 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 pubblicare un aggiornamento con questa modifica.
Puoi
utilizzare le API in Android 4.1 e al contempo supportare le versioni precedenti aggiungendo
al tuo codice condizioni che controllano il livello API di sistema prima di eseguire
API non supportate da minSdkVersion
.
Per scoprire di più sul mantenimento della compatibilità con le versioni precedenti, consulta la sezione Creazione di UI compatibili con le versioni precedenti.
Per ulteriori informazioni su come funzionano i livelli API, consulta Che cos'è il livello API?
Componenti dell'app
Servizi isolati
Se specifichi android:isolatedProcess="true"
nel tag <service>
, Service
verrà eseguito nell'ambito del proprio processo User-ID isolato, privo di autorizzazioni proprie.
Gestione della memoria
Le nuove costanti ComponentCallbacks2
come TRIM_MEMORY_RUNNING_LOW
e TRIM_MEMORY_RUNNING_CRITICAL
forniscono ai processi in primo piano ulteriori informazioni sullo stato della memoria prima che il sistema effettui chiamate onLowMemory()
.
Il nuovo metodo getMyMemoryState(ActivityManager.RunningAppProcessInfo)
consente di recuperare lo stato generale della memoria.
Fornitori di contenuti
Un nuovo metodo, acquireUnstableContentProviderClient()
, ti consente di accedere a un ContentProviderClient
che potrebbe essere "instabile", in modo che l'app non si arresti in modo anomalo se
il fornitore di contenuti lo fa. È utile quando interagisci con i fornitori di contenuti in un'app separata.
Sfondi animati
Nuovo protocollo per intent per avviare direttamente l'attività di anteprima dello sfondo animato, in modo da poter aiutare gli utenti a selezionare facilmente il tuo sfondo animato senza costringerli a uscire dall'app e a navigare nel selettore dello sfondo Home.
Per avviare il selettore di sfondi animati, chiama startActivity()
con un Intent
usando ACTION_CHANGE_LIVE_WALLPAPER
e un extra che specifica il tuo sfondo animato ComponentName
come stringa in EXTRA_LIVE_WALLPAPER_COMPONENT
.
Navigazione dello stack di app
Android 4.1 semplifica l'implementazione dei pattern di progettazione appropriati per la navigazione verso l'alto.
Devi solo aggiungere android:parentActivityName
a ogni elemento <activity>
nel
file manifest. Il sistema utilizza queste informazioni per aprire l'attività appropriata quando l'utente preme il pulsante Su nella barra delle azioni (interrompendo anche l'attività corrente). Pertanto, se dichiari l'elemento android:parentActivityName
per ogni attività, non avrai bisogno del metodo onOptionsItemSelected()
per gestire gli eventi relativi ai clic sull'icona dell'app nella barra delle azioni: il sistema ora gestisce l'evento e riprende o crea l'attività appropriata.
Questa funzionalità è particolarmente efficace per gli scenari in cui l'utente inserisce una delle attività dell'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 Navigazione tra app). Quando
l'utente inserisce la tua attività in questo modo, naturalmente l'app potrebbe non avere uno stack precedente di
attività che possono essere riprese mentre l'utente procede alla navigazione verso l'alto. Tuttavia, quando fornisci l'attributo android:parentActivityName
per le tue attività, il sistema riconosce se la tua app contiene già uno stack di attività padre e, in caso contrario, crea uno stack di back-stack sintetico contenente tutte le attività principali.
Nota: quando l'utente inserisce un'attività approfondita nella tua app e crea una nuova attività per l'app, il sistema inserisce in realtà lo stack di attività principali nell'attività. Di conseguenza, premendo il pulsante Indietro puoi anche tornare indietro attraverso lo stack di attività padre.
Quando il sistema crea uno back stack sintetico per la tua app, crea un Intent
di base per creare una nuova istanza di ciascuna attività principale. Non viene quindi salvato
per le attività principali, come ti aspetteresti che l'utente abbia navigato
in modo naturale su ogni attività. Se una delle attività principali mostra normalmente un'interfaccia utente che dipende dal contesto dell'utente, le relative informazioni non saranno disponibili e dovrai fornirle quando l'utente torna indietro nello stack. Ad esempio, se l'utente sta visualizzando un album in un'app di musica e navigando, potrebbe venire indirizzato a un'attività che elenca tutti gli album di un determinato genere musicale. In questo caso, se è necessario creare lo stack, è necessario indicare all'attività principale a quale genere appartiene l'album corrente in modo che l'album principale possa visualizzare l'elenco corretto come se l'utente provenisse effettivamente da quell'attività. Per inviare queste informazioni a un'attività principale sintetica, devi eseguire l'override del metodo onPrepareNavigateUpTaskStack()
. Questo
fornisce un oggetto TaskStackBuilder
creato dal sistema per
sintetizzare le attività padre. L'elemento TaskStackBuilder
contiene Intent
oggetti che il sistema utilizza per creare ciascuna attività padre. Nell'implementazione di onPrepareNavigateUpTaskStack()
, puoi modificare il valore Intent
appropriato per aggiungere altri dati 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 nel loro ordine logico, a partire dalla parte superiore della struttura ad albero delle attività. Di conseguenza, l'ultimo Intent
aggiunto all'array interno è l'elemento padre diretto dell'attività corrente. Se
vuoi modificare il valore Intent
per l'attività principale dell'attività, devi prima determinare
la lunghezza dell'array con getIntentCount()
e passare questo
valore a editIntentAt()
.
Se la struttura della tua app è più complessa, sono disponibili diverse altre API che ti permettono di gestire il comportamento della navigazione Up e personalizzare completamente lo stack di back sintetico. Alcune delle API che offrono ulteriori controlli includono:
onNavigateUp()
- Esegui l'override di questa opzione per eseguire un'azione personalizzata quando l'utente preme il pulsante Su.
navigateUpTo(Intent)
- Chiama questa opzione per terminare l'attività corrente e passare a quella indicata dall'elemento
Intent
fornito. Se l'attività è presente nel back stack, ma non è l'attività principale più vicina, vengono terminate anche tutte le altre attività tra l'attività corrente e quella specificata con l'intent. getParentActivityIntent()
- Chiama questo elemento per ottenere il
Intent
che avvierà il padre logico per l'attività corrente. shouldUpRecreateTask(Intent)
- Richiama questo pulsante per eseguire una query se è necessario creare uno stack di back-stack sintetico per poter navigare verso l'alto. Restituisce true se è necessario creare uno stack sintetico, false se lo stack appropriato esiste già.
finishAffinity()
- Chiama questa opzione per completare l'attività corrente e tutte le attività principali con la stessa affinità delle attività concatenate all'attività corrente.
Se esegui l'override dei comportamenti predefiniti come
onNavigateUp()
, devi chiamare questo metodo quando crei uno stack di backup sintetico durante la navigazione verso l'alto. onCreateNavigateUpTaskStack
- Esegui l'override di questa opzione se hai bisogno di controllare completamente il modo in cui viene creato lo stack di attività sintetico. Se vuoi semplicemente aggiungere alcuni dati extra agli intent per il tuo back stack, dovresti invece sostituire
onPrepareNavigateUpTaskStack()
Tuttavia, la maggior parte delle app non richiede l'uso di queste API o l'implementazione di onPrepareNavigateUpTaskStack()
, ma possono ottenere il comportamento corretto semplicemente aggiungendo android:parentActivityName
a ogni elemento <activity>
.
Multimediale
Codec multimediali
La classe MediaCodec
fornisce l'accesso a codec multimediali di basso livello per la codifica e la decodifica dei tuoi contenuti multimediali. Puoi creare un'istanza di MediaCodec
chiamando il numero createEncoderByType()
per codificare i contenuti multimediali o chiamando il numero createDecoderByType()
per la decodifica dei contenuti multimediali. Ciascuno di questi
metodi utilizza un tipo MIME per il tipo di contenuti multimediali che vuoi codificare o decodificare, ad esempio "video/3gpp"
o "audio/vorbis"
.
Con un'istanza di MediaCodec
creata, puoi chiamare configure()
per specificare proprietà come il formato multimediale o
se i contenuti sono criptati o meno.
A prescindere dal fatto che tu stia codificando o decodificando i tuoi contenuti multimediali, il resto del processo sarà lo stesso dopo la creazione di MediaCodec
. Prima 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 codificare o decodificare, chiama dequeueInputBuffer()
per ottenere la posizione dell'indice di ByteBuffer
(dall'array di buffer di input) da utilizzare per il feed nel tuo supporto di origine. Dopo aver compilato ByteBuffer
con i contenuti multimediali di origine, rilascia la proprietà del buffer chiamando queueInputBuffer()
.
Allo stesso modo, per il buffer di output, chiama dequeueOutputBuffer()
per ottenere la posizione dell'indice del ByteBuffer
in cui riceverai i risultati. Dopo aver letto l'output da ByteBuffer
, rilascia la proprietà chiamando releaseOutputBuffer()
.
Puoi gestire i dati multimediali criptati nei codec chiamando queueSecureInputBuffer()
insieme alle
API MediaCrypto
, anziché il normale queueInputBuffer()
.
Per ulteriori informazioni sull'utilizzo dei codec, consulta la documentazione di MediaCodec
.
Registra audio al momento
Il nuovo metodo startRecording()
ti consente
di avviare la registrazione audio in base a un segnale definito da un MediaSyncEvent
.
L'elemento MediaSyncEvent
specifica una sessione audio
(ad esempio, definita da MediaPlayer
) che, una volta completata, attiva
l'avvio della registrazione del registratore audio. Ad esempio, puoi utilizzare questa funzionalità per riprodurre un segnale acustico che indica l'inizio di una sessione di registrazione e la registrazione inizia automaticamente, senza dover sincronizzare manualmente il tono e l'inizio della registrazione.
Tracce di testo con timestamp
L'MediaPlayer
ora gestisce le tracce di testo in banda e fuori banda.
Le tracce di testo in-band vengono fornite come tracce di testo all'interno di un'origine multimediale MP4 o 3GPP. Le tracce di testo fuori banda possono essere aggiunte come origine di testo esterna tramite il metodo addTimedTextSource()
. Dopo aver aggiunto tutte le origini di tracce di testo esterne, è necessario chiamare getTrackInfo()
per ottenere l'elenco aggiornato di tutte le tracce disponibili in un'origine dati.
Per impostare la traccia da utilizzare con MediaPlayer
, devi richiamare selectTrack()
, utilizzando 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:
- Il sistema 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 pre-processore all'audio acquisito con un elemento AudioRecord
utilizzando una delle sottoclassi AudioEffect
.
Nota: non è garantito che tutti i dispositivi supportino questi effetti, quindi dovresti sempre verificare la disponibilità chiamando isAvailable()
sulla classe di effetti audio corrispondente.
Riproduzione senza intervalli
Ora puoi eseguire una riproduzione senza intervalli tra due oggetti MediaPlayer
separati. In qualsiasi momento prima che finisca il primo MediaPlayer
,
chiama setNextMediaPlayer()
e Android
tenta di avviare il secondo player nel momento in cui si interrompe il primo.
Fotocamera
Movimento della messa a fuoco automatica
La nuova interfaccia Camera.AutoFocusMoveCallback
consente di ascoltare
le modifiche al movimento della messa a fuoco automatica. 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 comunica se la messa a fuoco automatica ha iniziato a muoversi o se si è interrotta.
Suoni fotocamera
La classe MediaActionSound
fornisce un semplice set di API per produrre
i suoni standard emessi dalla videocamera o da altre azioni multimediali. Usa queste API per riprodurre
il suono appropriato quando crei un fermo immagine o una videocamera personalizzata.
Per riprodurre un suono, devi semplicemente creare un'istanza di un oggetto MediaActionSound
, chiamare
load()
per precaricare l'audio desiderato, quindi
chiamare play()
al
momento giusto.
Connettività
Android Beam
Android BeamTM ora supporta 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 il trasferimento di dati al Bluetooth o a un altro mezzo di trasporto alternativo per ottenere velocità di trasferimento più elevate. Ciò è particolarmente utile per payload di grandi dimensioni, come file di immagini e audio, e non richiede associazione visibile tra i dispositivi. Per usufruire dei trasferimenti tramite Bluetooth non è necessario alcun intervento aggiuntivo da parte della tua app.
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 che tu possa definire gli URI da condividere durante la condivisione.
Questo è 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 non cambiano e puoi definirli in anticipo in modo sicuro.
Rilevamento servizi di rete
Android 4.1 aggiunge il supporto per il rilevamento di servizi basato su DNS multicast, che consente di trovare e connettersi a servizi offerti da dispositivi peer tramite Wi-Fi, come dispositivi mobili, stampanti, fotocamere, media player e altri 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 rilevare servizi sulla rete, implementa NsdManager.DiscoveryListener
e trasmettilo a discoverServices()
.
Quando NsdManager.DiscoveryListener
riceve callback sui servizi trovati, devi risolvere il servizio chiamando
resolveService()
, passando un'implementazione di NsdManager.ResolveListener
che riceve
un oggetto NsdServiceInfo
contenente informazioni sul
servizio rilevato, in modo da poter avviare la connessione.
Rilevamento servizio Wi-Fi P2P
Le API Wi-Fi P2P sono state migliorate in Android 4.1 per supportare il rilevamento dei servizi di pre-associazione in WifiP2pManager
. In questo modo puoi scoprire e filtrare i dispositivi nelle vicinanze in base ai servizi tramite Wi-Fi P2P prima di connetterti a uno di questi servizi, mentre Network Service Discovery 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 descrive 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 listener di callback con setDnsSdResponseListeners()
, che accetta sia WifiP2pManager.DnsSdServiceResponseListener
che WifiP2pManager.DnsSdTxtRecordListener
. Per utilizzare Upnp, chiama
setUpnpServiceResponseListener()
, che richiede WifiP2pManager.UpnpServiceResponseListener
.
Prima di poter iniziare a scoprire servizi sui dispositivi locali, dovrai anche chiamare addServiceRequest()
. Quando il WifiP2pManager.ActionListener
che passi a questo metodo riceve un callback riuscito, puoi iniziare a rilevare servizi sui dispositivi locali chiamando il numero discoverServices()
.
Quando vengono rilevati servizi locali, riceverai un callback a WifiP2pManager.DnsSdServiceResponseListener
o WifiP2pManager.UpnpServiceResponseListener
, a seconda che tu abbia effettuato la registrazione per utilizzare 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
verificare se il dispositivo è attualmente connesso a una rete a consumo. Controllando questo stato
prima di eseguire transazioni di rete ingombranti, puoi gestire l'utilizzo dei dati che potrebbe comportare costi per i tuoi utenti e prendere
decisioni informate se eseguire le transazioni ora o in un secondo momento (ad esempio quando il dispositivo
si connette a una rete Wi-Fi).
Accessibilità
API dei servizi di accessibilità
La portata delle API dei servizi di accessibilità è stata notevolmente aumentata in Android 4.1. Ora ti consente di creare servizi che monitorano e rispondono a più eventi di input, ad esempio gesti complessi, utilizzando onGesture()
e altri eventi di input tramite l'aggiunta alle classi AccessibilityEvent
, AccessibilityNodeInfo
e AccessibilityRecord
.
I servizi di accessibilità possono anche eseguire azioni per conto dell'utente, ad esempio fare clic, scorrere e scorrere il 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 delle app personalizzabile
Quando crei un'app per Android, ora puoi personalizzare gli schemi di navigazione individuando gli elementi attivabili e i widget di immissione tramite findFocus()
e focusSearch()
, nonché impostare lo stato attivo tramite setAccessibilityFocused()
.
Widget più accessibili
La nuova classe android.view.accessibility.AccessibilityNodeProvider
ti consente di
mostrare visualizzazioni personalizzate complesse sui servizi di accessibilità in modo che possano presentare le informazioni in
modo più accessibile. android.view.accessibility.AccessibilityNodeProvider
consente a un widget utente con contenuti avanzati, ad esempio una griglia di calendario, di presentare una struttura semantica logica per i servizi di accessibilità, che è 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 disabilità visiva.
Copy and Paste
Copia e incolla con gli intent
Ora puoi associare un oggetto ClipData
a un Intent
utilizzando il metodo setClipData()
.
Questo è particolarmente utile quando si utilizza un intent per trasferire più URI content:
a un'altra applicazione, ad esempio quando si condividono 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 avvii un intent ACTION_SEND
o ACTION_SEND_MULTIPLE
, gli URI forniti nell'intent vengono ora propagati
automaticamente in ClipData
in modo che il destinatario possa
concedere loro l'accesso.
Supporto di stili HTML e stringhe
La classe ClipData
ora supporta il testo con stile (come stringhe HTML o
Android). Puoi aggiungere a ClipData
testo con stile HTML con newHtmlText()
.
RenderScript
La funzionalità di calcolo di Renderscript è stata migliorata con le seguenti caratteristiche:
- Supporto per più kernel in un unico script.
- Supporto per la lettura dall'allocazione con campionamenti filtrati dal computing in una nuova API script
rsSample
. - Supporto di diversi livelli di precisione FP in
#pragma
. - Supporto per l'esecuzione di query aggiuntive su informazioni dagli oggetti RS da uno script di computing.
- Numerosi miglioramenti delle prestazioni.
Sono disponibili anche nuovi pragma per definire la precisione in virgola mobile richiesta dai tuoi Renderscript di calcolo. Ciò consente di abilitare operazioni come NEON, come operazioni matematiche vettoriali veloci, sul percorso della CPU, che non sarebbero altrimenti possibili con lo standard completo IEEE 754-2008.
Nota: il motore grafico sperimentale Renderscript ora è deprecato.
Animazione
Animazioni per l'avvio delle attività
Ora puoi avviare Activity
usando animazioni zoom o animazioni personalizzate. Per specificare l'animazione che vuoi, usa le API ActivityOptions
per creare una Bundle
che puoi
quindi passare a uno qualsiasi dei
metodi che avviano un'attività, ad esempio startActivity()
.
La classe ActivityOptions
include un metodo diverso per ogni
tipo di animazione che vuoi mostrare all'apertura dell'attività:
makeScaleUpAnimation()
- Crea un'animazione che scala la finestra dell'attività a partire da una posizione iniziale specificata sullo schermo e a una dimensione iniziale specificata. Ad esempio, la schermata Home in Android 4.1 la usa quando si apre un'app.
makeThumbnailScaleUpAnimation()
- Crea un'animazione che scala la finestra dell'attività a partire da una posizione specificata e un'immagine in miniatura fornita. Ad esempio, la finestra App recenti in Android 4.1 usa questa opzione quando torni su un'app.
makeCustomAnimation()
- Crea un'animazione definita dalle tue risorse: una che definisce l'animazione per l'apertura dell'attività e un'altra per l'attività interrotta.
Animatore temporale
Il nuovo TimeAnimator
fornisce un semplice meccanismo di callback con TimeAnimator.TimeListener
che ti avvisa ogni volta che viene mostrato ogni frame dell'animazione. Non è possibile impostare durata, interpolazione o valore dell'oggetto con questo Animator. Il callback del listener riceve informazioni per ogni frame, inclusi il tempo totale trascorso e il tempo trascorso dal precedente frame dell'animazione.
Interfaccia utente
Notifiche
In Android 4.1 puoi creare notifiche con regioni 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 la notifica, ognuno dei quali offre una regione di contenuti più ampia. Per specificare lo stile per la regione di contenuti di grandi dimensioni, trasmetti setStyle()
uno dei seguenti oggetti:
Notification.BigPictureStyle
- Per le notifiche che includono un'immagine allegata 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, come snippet di più email.
Azioni di notifica
Ora sono supportati fino a due pulsanti di azione nella parte inferiore del messaggio di notifica, indipendentemente dal fatto che la notifica utilizzi lo stile normale o più grande.
Per aggiungere un pulsante di azione, chiama addAction()
. Questo metodo accetta tre argomenti: una risorsa disegnabile per un'icona,
il testo per il pulsante e un elemento PendingIntent
che definisce l'azione
da eseguire.
Priorità
Ora puoi suggerire al sistema in che misura la notifica incide sull'ordine della notifica nell'elenco impostando la priorità su setPriority()
. Puoi
superare questo uno dei cinque diversi livelli di priorità definiti dalle costanti PRIORITY_*
nella classe Notification
. Il valore predefinito è PRIORITY_DEFAULT
e ci sono due livelli più alti e due livelli inferiori.
Le notifiche ad alta priorità sono quelle a cui gli utenti solitamente vogliono rispondere rapidamente, ad esempio un nuovo messaggio immediato, un SMS o un promemoria di un evento imminente. Le notifiche a bassa priorità sono eventi di 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 sugli smartphone.
Android 4.1 aggiunge altri flag che ti consentono di controllare ulteriormente l'aspetto degli elementi dell'interfaccia utente di sistema e il layout delle tue attività in relazione ad essi chiamando setSystemUiVisibility()
e passando i seguenti flag:
SYSTEM_UI_FLAG_FULLSCREEN
- Nascondi l'interfaccia utente di sistema non critica (ad esempio la barra di stato).
Se la tua attività utilizza la barra delle azioni in modalità overlay (attivando
android:windowActionBarOverlay
), questo flag nasconde anche la barra delle azioni e lo fa con un'animazione coordinata quando entrambe vengono nascoste e mostrate. SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- Imposta il layout delle attività in modo che utilizzi la stessa area dello schermo disponibile quando hai
abilitato
SYSTEM_UI_FLAG_FULLSCREEN
anche se gli elementi dell'interfaccia utente del sistema sono ancora visibili. Anche se alcune parti del layout saranno sovrapposte all'interfaccia utente di sistema, ciò è utile se la tua app spesso nasconde e mostra l'interfaccia utente di sistema conSYSTEM_UI_FLAG_FULLSCREEN
, perché evita che il layout si adatti ai nuovi limiti ogni volta che l'interfaccia utente 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 attivi
SYSTEM_UI_FLAG_HIDE_NAVIGATION
(aggiunto in Android 4.0) anche se gli elementi dell'interfaccia utente del sistema sono ancora visibili. Anche se alcune parti del layout saranno sovrapposte alla barra di navigazione, ciò è utile se l'app spesso nasconde e mostra la barra di navigazione conSYSTEM_UI_FLAG_HIDE_NAVIGATION
, perché evita che il layout si adatti ai nuovi limiti ogni volta che la barra di navigazione viene nascosta o visualizzata. SYSTEM_UI_FLAG_LAYOUT_STABLE
- Potresti aggiungere questo flag se usi
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
e/oSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
per assicurarti che quando chiamifitSystemWindows()
in una visualizzazione i limiti definiti rimangano coerenti per quanto riguarda lo spazio disponibile sullo schermo. In altre parole, con questo flag impostato,fitSystemWindows()
si comporterà come se la visibilità degli elementi dell'interfaccia utente del sistema rimane invariata anche dopo aver nascosto l'intera UI del sistema.
Per ulteriori informazioni sugli altri flag dell'interfaccia utente di sistema correlati, leggi ulteriori informazioni su quelli aggiunti in Android 4.0.
Visualizzazioni remote
GridLayout
e ViewStub
ora sono visualizzazioni rimovibili in modo da poterle utilizzare nei layout per
i widget delle app e nei layout personalizzati delle notifiche.
Famiglie di caratteri
Android 4.1 aggiunge molte altre varianti dello stile del carattere Roboto per un totale di 10 varianti, tutte utilizzabili dalle app. Le tue app ora hanno accesso al set completo di varianti leggere e ridotte.
Il set completo di varianti di caratteri Roboto disponibile è:
- Periodici
- Corsivo
- Grassetto
- Grassetto-corsivo
- Leggero
- Corsivo chiaro
- Normale ridotta
- Corsivo ridotto
- Grassetto ridotto
- Grassetto corsivo ridotto
Puoi applicare uno qualsiasi di questi valori 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 grassetto e/o corsivo con i valori textStyle
"bold"
e "italic"
. Puoi applicare entrambi in questo modo: 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 registrare 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 il numero di controller viene modificato.
Puoi eseguire query su tutti i dispositivi di input connessi chiamando
getInputDeviceIds()
. Questo restituisce
un array di numeri interi, ognuno dei quali è un ID per un diverso dispositivo di input. Puoi quindi chiamare
getInputDevice()
per acquisire
un InputDevice
per un ID dispositivo di input specificato.
Se vuoi ricevere una notifica quando vengono connessi, modificati o disconnessi nuovi dispositivi di input, implementa l'interfaccia InputManager.InputDeviceListener
e registrala con registerInputDeviceListener()
.
Vibrazione per controller di input
Se i dispositivi di input connessi dispongono di funzionalità di vibrazione proprie, ora puoi controllare la vibrazione di questi dispositivi utilizzando le API Vibrator
esistenti semplicemente chiamando getVibrator()
sul numero InputDevice
.
Autorizzazioni
Di seguito sono riportate nuove autorizzazioni:
READ_EXTERNAL_STORAGE
- Fornisce l'accesso protetto in lettura all'unità di archiviazione esterna. In Android 4.1 per impostazione predefinita tutte le applicazioni hanno ancora accesso in lettura. Questo verrà modificato 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. È disponibile una nuova opzione per gli sviluppatori che consente di attivare la limitazione dell'accesso in lettura per testare le loro applicazioni in base al comportamento futuro di Android.
- android.Manifest.permission.READ_USER_DICTIONARY
- Consente a un'applicazione di leggere il dizionario utente. Questa operazione dovrebbe essere richiesta solo da un IME o da un editor di dizionario come l'app Impostazioni.
READ_CALL_LOG
- Consente a un'applicazione di leggere il registro chiamate del sistema, contenente informazioni sulle chiamate in arrivo e in uscita.
WRITE_CALL_LOG
- Consente a un'applicazione di modificare il registro chiamate del sistema memorizzato sul telefono
- android.Manifest.permission.WRITE_USER_DICTIONARY
- Consente a un'applicazione di scrivere nel dizionario di parole dell'utente.
Funzionalità dispositivo
Android 4.1 include una nuova dichiarazione relativa alle funzionalità per i dispositivi dedicati a visualizzare l'interfaccia utente sugli schermi di un televisore: FEATURE_TELEVISION
. Per dichiarare che la tua app richiede
un'interfaccia televisiva, 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 la "televisione" come una tipica esperienza televisiva del salotto: mostrata su un grande schermo, dove l'utente è seduto lontano e la forma principale di input è quella di un D-pad e in genere non tramite tocco o un mouse/dispositivo di puntamento.