API per Android 4.1

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 fornitoIntent. 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.

Router multimediale. Le nuove API MediaRouter, MediaRouteActionProvider e MediaRouteButton forniscono meccanismi e interfacce utente standard per scegliere dove riprodurre i contenuti multimediali.

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 con SYSTEM_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 con SYSTEM_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/o SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION per assicurarti che, quando chiami fitSystemWindows() 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.