API per Android 4.1

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.

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

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