Livello API: 16
Android 4.1 (JELLY_BEAN
) è un avanzamento della piattaforma che offre prestazioni ed esperienza utente migliorate. Aggiunge nuove funzioni per utenti
e sviluppatori di app. Questo documento offre un'introduzione alle nuove API più importanti
e utili per gli sviluppatori di app.
In qualità di sviluppatore di app, Android 4.1 è disponibile su SDK Manager come immagine di sistema eseguibile nell'emulatore Android e su una piattaforma SDK su cui puoi creare la tua app. Dovresti scaricare l'immagine e la piattaforma di sistema 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 codice condizioni che controllano il livello API di sistema prima di eseguire le API non supportate da minSdkVersion
.
Per scoprire di più sul mantenimento della compatibilità con le versioni precedenti, consulta la sezione Creare UI compatibili con le versioni precedenti.
Per ulteriori informazioni 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 nel proprio processo ID utente isolato e 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 chiami 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 una ContentProviderClient
che potrebbe essere "instabile", in modo che la tua 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 animato.
Per avviare il selettore dello sfondo animato, chiama startActivity()
con un Intent
utilizzando ACTION_CHANGE_LIVE_WALLPAPER
e un altro elemento che specifica lo 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 soltanto 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 (mentre termina anche l'attività corrente). Pertanto, se dichiari android:parentActivityName
per ogni attività, non è necessario il metodo onOptionsItemSelected()
per gestire gli eventi di clic sull'icona dell'app nella barra delle azioni: il sistema ora gestisce quell'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 Navigare tra app). Quando
l'utente inizia la tua attività in questo modo, naturalmente la tua app potrebbe non avere uno stack precedente di
attività che possono essere riprese mentre l'utente sale di livello. Tuttavia, quando fornisci l'attributo android:parentActivityName
per le tue attività, il sistema riconosce se la tua app contiene già uno stack posteriore di attività principali e, in caso negativo, 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 nello stack di attività principali.
Quando il sistema crea uno stack di backup sintetico per la tua app, crea un elemento Intent
di base per creare una nuova istanza di ogni attività padre. Non è quindi disponibile uno stato salvato per le attività principali, come ti aspetteresti se l'utente navigasse naturalmente tra le attività. Se una delle attività principali mostra di solito un'interfaccia utente dipendente dal contesto dell'utente, queste informazioni non saranno disponibili e dovrai fornirle quando l'utente tornerà nello stack. Ad esempio, se l'utente sta visualizzando un album in un'app di musica e la navigazione 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 il genere a cui appartiene l'album corrente, in modo che l'elemento 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()
. Fornisce un oggetto TaskStackBuilder
creato dal sistema per sintetizzare le attività principali. L'elemento TaskStackBuilder
contiene Intent
oggetti che il sistema utilizza per creare ciascuna attività padre. Nell'implementazione di onPrepareNavigateUpTaskStack()
, puoi modificare l'elemento Intent
appropriato per aggiungere ulteriori dati che l'attività principale può utilizzare per determinare il contesto appropriato e visualizzare l'UI 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 dell'albero delle attività. Quindi, l'ultimo Intent
aggiunto all'array interno è l'elemento padre diretto dell'attività corrente. Se vuoi modificare Intent
per l'elemento padre dell'attività, prima determina la lunghezza dell'array con getIntentCount()
e trasmetti quel valore a editIntentAt()
.
Se la struttura della tua app è più complessa, sono disponibili molte altre API che ti consentono di gestire il comportamento della navigazione verso l'alto e personalizzare completamente lo stack di back sintetico. Alcune delle API che offrono un controllo aggiuntivo sono:
onNavigateUp()
- Esegui l'override di questa impostazione per eseguire un'azione personalizzata quando l'utente preme il pulsante Su.
navigateUpTo(Intent)
- Chiama questa funzione per terminare l'attività corrente e andare all'attività indicata dal
Intent
fornito. Se l'attività è presente nello stack di riserva, 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 questa funzione per ottenere il
Intent
che avvierà il padre logico per l'attività corrente. shouldUpRecreateTask(Intent)
- Richiama questa funzionalità per eseguire una query se è necessario creare uno stack di back sintetico per andare in alto. Restituisce true se è necessario creare uno stack sintetico, false se lo stack appropriato esiste già.
finishAffinity()
- Richiama questa funzione per completare l'attività corrente e tutte le attività principali con la stessa affinità attività che sono concatenate all'attività corrente.
Se esegui l'override dei comportamenti predefiniti come
onNavigateUp()
, devi richiamare questo metodo quando crei uno stack di backup sintetico durante la navigazione verso l'alto. onCreateNavigateUpTaskStack
- Esegui l'override 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 raggiungere il comportamento corretto semplicemente
aggiungendo android:parentActivityName
a ogni elemento <activity>
.
Multimediale
Codec multimediali
La classe MediaCodec
consente di accedere a codec multimediali di basso livello per la codifica e la decodifica dei tuoi contenuti multimediali. Puoi creare un'istanza di MediaCodec
chiamando 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 supporto 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 la codifica o la decodifica, chiama dequeueInputBuffer()
per ottenere la posizione dell'indice di ByteBuffer
(dall'array di buffer di input) da utilizzare per il feed nel supporto di origine. Dopo aver compilato il campo 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 dell'elemento 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 consiglio definito da un MediaSyncEvent
.
MediaSyncEvent
specifica una sessione audio
(ad esempio quella definita da MediaPlayer
) che, al termine, attiva
il registratore audio per iniziare a registrare. Ad esempio, puoi usare questa funzionalità per riprodurre un segnale audio che indichi l'inizio di una sessione di registrazione e la registrazione inizia automaticamente in modo da non dover sincronizzare manualmente il tono e l'inizio della registrazione.
Tracce di testo a tempo
MediaPlayer
ora gestisce le tracce di testo sia in banda che fuori banda.
Le tracce di testo in-band vengono visualizzate 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, deve essere chiamato getTrackInfo()
per ottenere l'elenco aggiornato di tutte le tracce disponibili in un'origine dati.
Per impostare la traccia da utilizzare con MediaPlayer
, devi chiamare selectTrack()
, utilizzando la posizione dell'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:
- L'AEC (Acoustic Echo Canceler) 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. - L'eliminazione rumore (NS) con
NoiseSuppressor
rimuove i rumori di fondo dal segnale acquisito.
Puoi applicare questi effetti del pre-processore all'audio acquisito con AudioRecord
utilizzando una delle sottoclassi AudioEffect
.
Nota: non è garantito che tutti i dispositivi supportino questi effetti, quindi devi sempre verificare la disponibilità chiamando isAvailable()
sulla classe di effetti audio corrispondente.
Riproduzione senza interruzioni
Ora puoi eseguire una riproduzione senza interruzioni tra due oggetti MediaPlayer
separati. In qualsiasi momento prima che finisca il primo giocatore (MediaPlayer
), chiama il numero setNextMediaPlayer()
e Android proverà ad avviare il secondo player nel momento in cui si ferma il primo.
Fotocamera
Movimento automatico della messa a fuoco
La nuova interfaccia Camera.AutoFocusMoveCallback
consente di ascoltare
le variazioni del 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 si è interrotta.
Suoni fotocamera
La classe MediaActionSound
fornisce un semplice set di API per produrre
suoni standard creati dalla fotocamera o da altre azioni multimediali. Utilizza queste API per riprodurre
il suono appropriato quando crei un fermo immagine o una videocamera personalizzata.
Per riprodurre un suono, crea un'istanza di un oggetto MediaActionSound
, chiama
load()
per precaricare il suono desiderato e, al
momento appropriato, chiama play()
.
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 consegna il trasferimento dei dati al Bluetooth o a un altro trasporto alternativo per ottenere velocità di trasferimento più elevate. Questa funzionalità è particolarmente utile per payload di grandi dimensioni, come file di immagine e audio, e non richiede accoppiamento visibile tra i dispositivi. Per sfruttare i trasferimenti tramite Bluetooth, la tua app non richiede interventi aggiuntivi.
Il metodo setBeamPushUris()
utilizza 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()
.
Se utilizzi l'interfaccia di callback, il sistema chiama il metodo createBeamUris()
dell'interfaccia quando l'utente esegue una condivisione con Android Beam. In questo modo puoi 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 sicurezza in anticipo.
Rilevamento servizi di rete
Android 4.1 aggiunge il supporto per il rilevamento dei servizi basato su DNS multicast, che consente di trovare e connettersi ai servizi offerti da dispositivi peer tramite Wi-Fi, come dispositivi mobili, stampanti, fotocamere, lettori multimediali 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 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 trasmetterlo a registerService()
con il tuo NsdServiceInfo
.
Per rilevare i servizi sulla rete, implementa NsdManager.DiscoveryListener
e trasmettilo a discoverServices()
.
Quando NsdManager.DiscoveryListener
riceve callback relativi ai 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 questo modo puoi avviare la connessione.
rilevamento servizio Wi-Fi P2P
Le API Wi-Fi P2P sono state migliorate in Android 4.1 per supportare il rilevamento del servizio di pre-associazione in WifiP2pManager
. In questo modo puoi scoprire e filtrare i dispositivi nelle vicinanze in base ai servizi utilizzando Wi-Fi P2P prima di connetterti a uno, 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 rilevarla e connettersi, chiama addLocalService()
con un oggetto WifiP2pServiceInfo
che descrive i servizi della tua 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
sia WifiP2pManager.DnsSdTxtRecordListener
. Per utilizzare Upnp, chiama
setUpnpServiceResponseListener()
, che richiede WifiP2pManager.UpnpServiceResponseListener
.
Prima di poter iniziare a rilevare i servizi sui dispositivi locali, devi anche chiamare addServiceRequest()
. Quando l'elemento WifiP2pManager.ActionListener
che passi a questo metodo riceve un callback riuscito, puoi iniziare a rilevare i servizi sui dispositivi locali chiamando il numero discoverServices()
.
Quando vengono rilevati servizi locali, riceverai un callback per WifiP2pManager.DnsSdServiceResponseListener
o WifiP2pManager.UpnpServiceResponseListener
, a seconda che ti sei registrato 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 impegnative, puoi gestire l'utilizzo dei dati che potrebbe comportare costi per gli utenti e prendere decisioni informate sull'esecuzione delle transazioni ora o in un secondo momento (ad esempio quando il dispositivo si connette a una rete Wi-Fi).
Accessibilità
API Accessibility Service
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 un maggior numero di eventi di input, ad esempio gesti complessi, utilizzando onGesture()
e altri eventi di input tramite l'aggiunta delle 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 dell'app personalizzabile
Quando crei un'app per Android, ora puoi personalizzare gli schemi di navigazione trovando elementi attivabili e widget di immissione tramite findFocus()
e focusSearch()
, nonché impostando lo stato attivo tramite 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 utente con contenuti avanzati, ad esempio una griglia del calendario, di presentare una struttura semantica logica per i servizi di accessibilità che è completamente separata dalla struttura di 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 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 a ClipData
in modo che il destinatario possa concedere l'accesso.
Supporto di HTML e stili 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 caratteristiche:
- Supporto per più kernel in un unico script.
- Supporto per la lettura dall'allocazione con campionatori filtrati dal calcolo in una nuova API script
rsSample
. - Supporto di diversi livelli di precisione FP in
#pragma
. - Supporto per l'esecuzione di query su informazioni aggiuntive da 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. In questo modo puoi abilitare operazioni simili a NEON, come operazioni matematiche veloci vettoriali sul percorso della CPU, che altrimenti non sarebbero possibili con lo standard completo IEEE 754-2008.
Nota: il motore grafico Renderscript sperimentale è stato ritirato.
Animazione
Animazioni per l'avvio delle attività
Ora puoi avviare una Activity
usando animazioni zoom o
con le tue animazioni personalizzate. Per specificare l'animazione che preferisci, utilizza le API ActivityOptions
per creare una 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 scala la finestra dell'attività da una posizione iniziale specificata sullo schermo e da una dimensione iniziale specificata. Ad esempio, la schermata Home di Android 4.1 lo usa quando si apre un'app.
makeThumbnailScaleUpAnimation()
- Crea un'animazione che scala la finestra dell'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 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 su ogni frame dell'animazione. Con questo Animator non è possibile impostare durata, interpolazione o valore dell'oggetto. Il callback del listener riceve informazioni per ogni frame, tra cui il tempo totale trascorso e il tempo trascorso dal frame di animazione precedente.
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()
consente di specificare uno dei tre nuovi stili per la notifica, ciascuno dei quali offre una regione di contenuti più ampia. Per specificare lo stile per la vasta regione di contenuti, 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, ad esempio snippet di più email.
Azioni di notifica
Ora è disponibile il supporto per un massimo di due pulsanti di azione visualizzati nella parte inferiore del messaggio di notifica, indipendentemente dal fatto che la notifica utilizzi lo stile normale o uno stile più grande.
Per aggiungere un pulsante di azione, chiama addAction()
. Questo metodo prevede tre argomenti: una risorsa disegnabile per un'icona,
un testo per il pulsante e un PendingIntent
che definisce l'azione
da eseguire.
Priorità
Ora puoi indicare al sistema l'importanza della notifica relativa all'ordine delle notifiche nell'elenco impostandone la priorità con setPriority()
. Puoi
superare questo uno dei cinque diversi livelli di priorità definiti dalle costanti PRIORITY_*
nella classe Notification
. Il valore predefinito è PRIORITY_DEFAULT
, con due livelli più alto e due livelli inferiori.
Le notifiche ad alta priorità sono elementi a cui gli utenti in genere vogliono rispondere rapidamente, come un nuovo messaggio immediato, un SMS o un promemoria di evento imminente. Le notifiche a bassa priorità sono, ad esempio, 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 sui telefoni.
Android 4.1 aggiunge altri flag che ti consentono di controllare ulteriormente l'aspetto degli elementi UI di sistema e il layout della tua attività in relazione ad essi chiamando setSystemUiVisibility()
e passando i seguenti flag:
SYSTEM_UI_FLAG_FULLSCREEN
- Nasconde l'UI 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 entrambi vengono nascosti e mostrati. SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- Imposta il layout dell'attività in modo da utilizzare la stessa area dello schermo disponibile dopo aver
attivato
SYSTEM_UI_FLAG_FULLSCREEN
, anche se gli elementi dell'interfaccia utente di sistema sono ancora visibili. Anche se alcune parti del layout verranno sovrapposte all'interfaccia utente di sistema, questa opzione è utile se l'app nasconde e mostra spesso l'interfaccia utente di sistema conSYSTEM_UI_FLAG_FULLSCREEN
, perché evita che il layout si adatti ai nuovi limiti del layout ogni volta che l'UI di sistema viene nascosta o visualizzata. SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- Imposta il layout dell'attività in modo da utilizzare 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 saranno sovrapposte alla barra di navigazione, questa opzione è utile se l'app nasconde e mostra spesso 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
- Ti consigliamo di aggiungere questo flag se usi
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
e/oSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
per assicurarti che quando chiamifitSystemWindows()
su una vista 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 di sistema rimanesse invariata anche dopo aver nascosto l'intera UI di sistema.
Per maggiori dettagli sugli altri flag dell'interfaccia utente di sistema correlati, scopri di più 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 tue app e per i 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 dei caratteri Roboto disponibili è:
- Periodici
- Corsivo
- Grassetto
- Grassetto-corsivo
- Leggero
- Corsivo chiaro
- Normale ridotta
- Corsivo ridotto
- Grassetto ridotto
- Corsivo grassetto ridotto
Puoi applicare uno qualsiasi di questi elementi 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 entrambe 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
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 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, ognuno 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 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 hanno le proprie funzionalità di vibrazione, ora puoi controllare la vibrazione di questi dispositivi utilizzando le API Vibrator
esistenti semplicemente chiamando getVibrator()
sul InputDevice
.
Autorizzazioni
Di seguito sono riportate le nuove autorizzazioni:
READ_EXTERNAL_STORAGE
- Fornisce accesso protetto in lettura all'unità di archiviazione esterna. In Android 4.1 per impostazione predefinita tutte le applicazioni hanno ancora accesso in lettura. Questa autorizzazione verrà modificata 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 loro 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, 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 sul telefono
- android.Manifest.permission.WRITE_USER_DICTIONARY
- Consente a un'applicazione di scrivere nel dizionario delle parole dell'utente.
Funzionalità dispositivo
Android 4.1 include una nuova dichiarazione relativa alle funzionalità per i dispositivi dedicati
a mostrare l'interfaccia utente su uno schermo televisivo: FEATURE_TELEVISION
. Per dichiarare che la tua app richiede
un'interfaccia del televisore, 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 caratteristica definisce la "televisione" come la tipica esperienza televisiva di un salotto: viene mostrata su uno schermo di grandi dimensioni, dove l'utente è seduto lontano e la forma di input dominante è qualcosa come un d-pad, generalmente non tramite tocco o un mouse/pointer.