Android 8.0 (livello API 26) introduce una serie di nuove caratteristiche per utenti e sviluppatori. Questo documento mette in evidenza le novità per gli sviluppatori.
Assicurati di controllare anche le modifiche al comportamento di Android 8.0 per scoprire le aree in cui le modifiche alla piattaforma potrebbero influire sulle tue app.
Esperienza utente
Modalità Picture in picture
Picture in picture in Android 8.0.
Android 8.0 (livello API 26) consente l'avvio delle attività in modalità Picture in picture (PIP). PIP è un tipo speciale di modalità multi-finestra usato principalmente per la riproduzione di video. La modalità PIP era inizialmente disponibile solo per Android TV; Android 8.0 rende disponibile la funzionalità su altri dispositivi Android.
Quando un'attività è in modalità PIP, è nello stato di pausa ma dovrebbe continuare a mostrare il contenuto. Per questo motivo, assicurati che la tua app non metta in pausa la riproduzione nel relativo gestore onPause()
. Devi mettere in pausa il video in onStop()
e riprendere la riproduzione in onStart()
. Per ulteriori informazioni, consulta
Ciclo di vita
multi-finestra.
Per specificare che l'attività può utilizzare la modalità PIP, imposta android:supportsPictureInPicture
su true nel manifest.
A partire da Android 8.0, PIP non richiede l'attributo del file manifest android:resizeableActivity
.
Tuttavia, devi impostare
android:resizeableActivity
su "true" se la tua attività supporta altre
modalità multi-finestra).
Android 8.0 (livello API 26) introduce un nuovo oggetto, PictureInPictureParams
, che passi ai metodi PIP per specificare il comportamento di un'attività in modalità PIP. Questo oggetto specifica proprietà come
le proporzioni preferite dell'attività.
Ora è possibile utilizzare i metodi PIP esistenti descritti nella sezione Aggiungere Picture in picture su tutti i dispositivi Android, non solo su Android TV. Inoltre, Android 8.0 offre i seguenti metodi per supportare la modalità PIP:
Activity.enterPictureInPictureMode(PictureInPictureParams args)
: imposta l'attività in modalità Picture in picture. Le proporzioni dell'attività e altre impostazioni di configurazione sono specificate da args. Se in args ci sono campi vuoti, il sistema utilizza i valori impostati l'ultima volta che hai chiamatoActivity.setPictureInPictureParams()
.L'attività specificata viene posizionata in un angolo dello schermo; il resto dello schermo è riempito con l'attività precedente sullo schermo. L'attività che si attiva in modalità PIP passa in stato di pausa, ma rimane avviata. Se l'utente tocca l'attività PIP, il sistema mostra un menu con cui l'utente può interagire; nessun evento di tocco raggiunge l'attività mentre è in stato PIP.
-
Activity.setPictureInPictureParams()
: aggiorna le impostazioni di configurazione PIP di un'attività. Se l'attività è attualmente in modalità PIP, le impostazioni vengono aggiornate; ciò è utile se le proporzioni dell'attività cambiano. Se l'attività non è in modalità PIP, queste impostazioni di configurazione vengono utilizzate indipendentemente dal metodoenterPictureInPictureMode()
chiamato.
Notifiche
In Android 8.0 (livello API 26), abbiamo riprogettato le notifiche per fornire un modo più semplice e coerente per gestire il comportamento e le impostazioni delle notifiche. Queste modifiche includono:
- Canali di notifica. Android 8.0 introduce canali di notifica che consentono di creare un canale personalizzabile dall'utente per ogni tipo di notifica che vuoi visualizzare. L'interfaccia utente fa riferimento ai canali di notifica come categorie di notifica. Per scoprire come implementare i canali di notifica, consulta Gestione dei canali di notifica.
- Indicatori di notifica: Android 8.0 introduce il supporto della visualizzazione di punti, o badge, sulle icone di Avvio applicazioni. Gli indicatori di notifica riflettono la presenza di notifiche su cui l'utente non ha ancora ignorato o eseguito azioni. Per scoprire come utilizzare gli indicatori di notifica, consulta Badge di notifica.
- Posticipare: gli utenti possono posticipare le notifiche, quindi le notifiche non vengono più visualizzate per un determinato periodo di tempo prima di essere visualizzate di nuovo. Le notifiche vengono visualizzate con lo stesso livello di importanza con cui sono apparse per la prima volta. Le app possono rimuovere o aggiornare una notifica posticipata, ma l'aggiornamento di una notifica posticipata non ne comporta la visualizzazione di nuovo.
- Timeout delle notifiche: puoi impostare un timeout durante la creazione di una notifica utilizzando
setTimeoutAfter()
. Puoi utilizzare questo metodo per specificare un periodo di tempo dopo il quale deve essere annullata una notifica. Se necessario, puoi annullare una notifica prima che scada la durata del timeout specificata. - Impostazioni di notifica: puoi chiamare
setSettingsText()
per impostare il testo che viene visualizzato quando crei un link alle impostazioni di notifica dell'app da una notifica utilizzando l'intentNotification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES
. Il sistema potrebbe fornire i seguenti extra allo scopo di filtrare le impostazioni che la tua app deve mostrare agli utenti:EXTRA_CHANNEL_ID
,NOTIFICATION_TAG
eNOTIFICATION_ID
. - Chiusura delle notifiche: gli utenti possono ignorare le notifiche autonomamente e le app possono rimuoverle in modo programmatico. Puoi determinare quando una notifica
viene ignorata e il motivo per cui viene ignorata implementando il
metodo
onNotificationRemoved()
dalla classeNotificationListenerService
. - Colori di sfondo. Puoi impostare e attivare un colore di sfondo per una notifica. Dovresti usare questa funzionalità solo nelle notifiche relative alle attività in corso che sono fondamentali per un utente a colpo d'occhio. Ad esempio, puoi impostare un colore di sfondo per le notifiche relative alle indicazioni stradali o a una telefonata in corso. Puoi anche impostare il colore di sfondo che preferisci utilizzando
setColor()
. In questo modo puoi usaresetColorized()
per attivare l'uso di un colore di sfondo per una notifica. - Stile di messaggistica: in Android 8.0, le notifiche che utilizzano la classe
MessagingStyle
mostrano più contenuti nel modulo compresso. Dovresti utilizzare il corsoMessagingStyle
per le notifiche relative ai messaggi. Puoi anche utilizzare il metodoaddHistoricMessage()
per fornire contesto a una conversazione, aggiungendo lo storico dei messaggi alle notifiche relative ai messaggi.
![Una notifica che premi a lungo il menu in Android 8.0 (livello API 26).](https://developer.android.google.cn/static/images/about/versions/oreo/notification-long-press.png?authuser=5&hl=it)
Gli utenti possono premere a lungo sulle icone in Avvio applicazioni per visualizzare le notifiche in Android 8.0.
Framework di compilazione automatica
La creazione dell'account, l'accesso e le transazioni con carta di credito richiedono tempo e sono soggette a errori. Gli utenti possono facilmente sentirsi frustrati con le app che richiedono questo tipo di attività ripetitive.
Con l'introduzione del framework per la compilazione automatica, Android 8.0 (livello API 26) semplifica la compilazione di moduli, ad esempio quelli per l'accesso e per le carte di credito. Le app nuove ed esistenti funzionano con il framework di compilazione automatica dopo che l'utente ha attivato la compilazione automatica.
Puoi seguire alcuni passaggi per ottimizzare il modo in cui la tua app funziona con il framework. Per ulteriori informazioni, consulta la panoramica del framework per la compilazione automatica.
Caratteri scaricabili
Android 8.0 (livello API 26) e Android Support Library 26 consentono di richiedere caratteri da un'applicazione provider anziché raggruppare i caratteri nell'APK o consentire all'APK di scaricare i caratteri. Questa funzionalità riduce le dimensioni dell'APK, aumenta la percentuale di successo delle installazioni di app e consente a più app di condividere lo stesso carattere.
Per ulteriori informazioni sul download dei caratteri, consulta la sezione Caratteri scaricabili.
Caratteri in XML
Android 8.0 (livello API 26) introduce una nuova funzionalità, i caratteri in XML, che consente di utilizzare i caratteri come risorse. Ciò significa che non è necessario raggruppare
i caratteri come asset. I caratteri sono compilati in un file R
e sono automaticamente
disponibili nel sistema come risorsa. Potrai quindi accedere a questi caratteri con l'aiuto
di un nuovo tipo di risorsa, font
.
La Support Library 26 fornisce il supporto completo di questa funzionalità sui dispositivi che eseguono l'API 14 e versioni successive.
Per ulteriori informazioni sull'utilizzo dei caratteri come risorse e sul recupero dei caratteri di sistema, consulta Caratteri in XML.
Ridimensionamento automatico TextView
Android 8.0 (livello API 26) ti consente di impostare automaticamente le dimensioni di espansione o contrazione del testo in base alle dimensioni di TextView. Ciò significa che è molto più semplice ottimizzare le dimensioni del testo su schermi diversi o con contenuti dinamici. Per maggiori informazioni sul ridimensionamento automatico di TextView in Android 8.0, consulta la pagina relativa al ridimensionamento automatico di TextView.
Icone adattive
Android 8.0 (livello API 26) introduce le icone di Avvio applicazioni adattive. Le icone adattive supportano gli effetti visivi e possono visualizzare una varietà di forme in diversi modelli di dispositivi. Per informazioni su come creare icone adattive, consulta la guida delle icone adattive.
Gestione del colore
Gli sviluppatori Android di app di imaging possono ora sfruttare i nuovi dispositivi con un display a colori ad ampia gamma. Per visualizzare immagini con ampia gamma di immagini, le app devono attivare un flag nel file manifest (per attività) e caricare bitmap con un profilo colori ampio incorporato (AdobeRGB, Pro Photo RGB, DCI-P3 e così via).
API WebView
Android 8.0 fornisce diverse API per aiutarti a gestire gli oggetti WebView
che mostrano contenuti web nella tua app. Queste API, che migliorano la stabilità e la sicurezza della tua app, includono quanto segue:
- API Version
- API Google Navigazione sicura
- API Terminazione Handle
- API Renderer Importance
Per scoprire di più su come utilizzare queste API, consulta Gestione dei componenti WebView.
La classe WebView
ora include un'API Navigazione sicura per migliorare la sicurezza
della navigazione sul web. Per ulteriori informazioni, consulta
la pagina relativa all'API Navigazione sicura di Google.
Blocco di scorciatoie e widget
Android 8.0 (livello API 26) introduce il blocco in-app di scorciatoie e widget. Nella tua app puoi creare scorciatoie e widget bloccati per gli strumenti di avvio supportati, soggetti all'autorizzazione dell'utente.
Per ulteriori informazioni, consulta la guida alle funzionalità Blocco di scorciatoie e widget.
Proporzioni massime dello schermo
Android 8.0 (livello API 26) apporta modifiche alle modalità di configurazione delle proporzioni massime di un'app.
Innanzitutto, Android 8.0 introduce l'attributo maxAspettoProporzioni, che puoi utilizzare per impostare le proporzioni massime della tua app. Inoltre, in Android 8.0 e versioni successive, le proporzioni massime predefinite di un'app sono quelle native del dispositivo su cui è in esecuzione l'app.
Per saperne di più sulla dichiarazione delle proporzioni massime, consulta la sezione Supporto di più schermi.
Supporto di più display
A partire da Android 8.0 (livello API 26), la piattaforma offre un supporto avanzato per più display. Se un'attività supporta la modalità multi-finestra ed è in esecuzione su un dispositivo con più display, gli utenti possono spostarla da un display all'altro. Quando un'app avvia un'attività, l'app può specificare su quale display deve essere eseguita l'attività.
Nota: se un'attività supporta la modalità multi-finestra, Android 8.0 attiva automaticamente il supporto multi-display per quell'attività. Devi testare la tua app per assicurarti che funzioni adeguatamente in un ambiente con più display.
È possibile riprendere una sola attività alla volta anche se l'app ha più visualizzazioni. L'attività con lo stato attivo è in stato ripresa; tutte le altre attività visibili sono in pausa, ma non interrotte. Per ulteriori informazioni sul ciclo di vita delle attività quando sono visibili diverse attività, consulta Ciclo di vita multi-finestra.
Quando un utente sposta un'attività da un display all'altro, il sistema ridimensiona l'attività e apporta modifiche al runtime in base alle esigenze. La tua attività può gestire autonomamente la modifica della configurazione o consentire al sistema di eliminare il processo contenente l'attività e ricrearlo con le nuove dimensioni. Per ulteriori informazioni, consulta Gestione delle modifiche alla configurazione.
ActivityOptions
offre due nuovi metodi per supportare più display:
setLaunchDisplayId()
- Specifica su quale display deve essere mostrata l'attività quando viene avviata.
getLaunchDisplayId()
- Restituisce la visualizzazione di avvio corrente dell'attività.
La shell adb è estesa per supportare più display.
Ora il comando shell start
può essere utilizzato per avviare un'attività e per specificare la visualizzazione di destinazione dell'attività:
adb shell start <activity_name> --display <display_id>
Spaziatura interna e margini del layout unificati
Android 8.0 (livello API 26) ti consente di specificare più facilmente situazioni in cui i lati opposti di un elemento View
utilizzano lo stesso margine o la stessa spaziatura interna.
In particolare, ora puoi utilizzare i seguenti attributi nei file XML di layout:
-
layout_marginVertical
, che definiscelayout_marginTop
elayout_marginBottom
contemporaneamente. -
layout_marginHorizontal
, che definiscelayout_marginLeft
elayout_marginRight
contemporaneamente. -
paddingVertical
, che definiscepaddingTop
epaddingBottom
contemporaneamente. -
paddingHorizontal
, che definiscepaddingLeft
epaddingRight
contemporaneamente.
Nota: se personalizzi la logica della tua app in modo che
supporti lingue e culture diverse, inclusa la direzione del testo, tieni presente che questi
attributi non influiscono sui valori di
layout_marginStart
,
layout_marginEnd
,
paddingStart
o
paddingEnd
. Puoi impostare questi valori autonomamente, in aggiunta ai nuovi attributi di layout verticale e orizzontale, per creare un comportamento del layout che dipende dalla direzione del testo.
Acquisizione con puntatore
Alcune app, come giochi, desktop remoto e client di virtualizzazione, traggono grande vantaggio dal controllo del puntatore del mouse. L'acquisizione del puntatore è una nuova funzionalità di Android 8.0 (livello API 26) che offre questo controllo fornendo tutti gli eventi del mouse a una visualizzazione specifica nella tua app.
A partire da Android 8.0, un elemento View
nella tua app può richiedere
l'acquisizione del puntatore e definire un listener per elaborare gli eventi di puntamento acquisiti. In questa modalità il puntatore del mouse è nascosto. La vista può rilasciare l'acquisizione
con il puntatore del mouse. Il sistema può anche rilasciare l'acquisizione del puntatore quando la visualizzazione perde lo stato attivo, ad esempio quando l'utente apre un'altra app.
Per informazioni su come usare questa funzionalità nella tua app, consulta Acquisizione punta.
Categorie di app
Android 8.0 (livello API 26) consente a ogni app di dichiarare una categoria di appartenenza, se pertinente. Queste categorie vengono utilizzate per raggruppare app con scopi o funzioni simili quando le presenti agli utenti, ad esempio in Utilizzo dei dati, Utilizzo della batteria o Utilizzo dello spazio di archiviazione. Puoi definire una categoria per la tua app impostando l'attributo android:appCategory
nel tag manifest <application>
.
Avvio app di Android TV
Android 8.0 (livello API 26) include una nuova esperienza schermata Home di Android TV incentrata sui contenuti, disponibile con l'emulatore di Android TV e l'immagine del dispositivo Nexus Player per Android 8.0. La nuova schermata Home organizza i contenuti video in righe corrispondenti ai canali, in cui ciascuno è compilato con i programmi da un'app sul sistema. Le app possono pubblicare più canali e gli utenti possono configurare quali canali vogliono vedere nella schermata Home. La schermata Home di Android TV include anche una riga Guarda successivo, che viene compilata con i programmi delle app, in base alle abitudini di visualizzazione dell'utente. Le app possono anche fornire anteprime video, che vengono riprodotte automaticamente quando un utente si concentra su un programma. Le API per la compilazione di canali e programmi fanno parte delle API TvProvider, che vengono distribuite come un modulo Android Support Library con Android 8.0.
Insieme di animazioni
A partire da Android 8.0 (livello API 26), l'API AnimatorSet
supporta la ricerca e la riproduzione invertite. La ricerca consente di impostare la posizione dell'animazione impostata su un
punto specifico nel tempo. La riproduzione invertita è utile se l'app include animazioni per azioni annullabili. Invece di definire due insiemi di animazioni separati, puoi riprodurli invertendo la stessa.
Immissione e navigazione
Cluster di navigazione della tastiera
Se un'attività nella tua app utilizza una gerarchia di visualizzazione complessa, come quella della Figura 2, valuta la possibilità di organizzare i gruppi di elementi UI in cluster per semplificare la navigazione da parte della tastiera. Sui dispositivi Chromebook, gli utenti possono premere Meta+Tab o Ricerca+Tab per passare da un cluster all'altro. Ecco alcuni esempi di cluster: riquadri laterali, barre di navigazione, aree di contenuti principali ed elementi che potrebbero contenere molti elementi secondari.
![Un'attività di esempio che include cinque cluster di navigazione in cui l'utente può navigare utilizzando la scorciatoia per il cluster di navigazione da tastiera. I cluster vengono visualizzati nella seguente disposizione: riquadro superiore, riquadro laterale sinistro, area dei contenuti principale, riquadro inferiore e pulsante di azione mobile.](https://developer.android.google.cn/static/images/about/versions/oreo/keyboard-navigation-clusters.png?authuser=5&hl=it)
Per trasformare un elemento View
o ViewGroup
in un cluster, imposta l'attributo
android:keyboardNavigationCluster
su true
nel file XML di layout dell'elemento oppure trasmetti true
a setKeyboardNavigationCluster()
nella logica dell'interfaccia utente dell'app.
Nota: i cluster non possono essere nidificati, anche se i cluster non nidificati possono apparire a livelli diversi della gerarchia. Se tenti di nidificare i cluster, il framework tratta solo l'elemento ViewGroup
più in alto come cluster.
Sui dispositivi dotati di touchscreen, puoi impostare l'elemento android:touchscreenBlocksFocus
di un oggetto ViewGroup
designato in un cluster su true
per consentire la navigazione solo cluster all'interno e all'esterno del cluster. Se applichi questa configurazione a un cluster, gli utenti non possono utilizzare il tasto Tab o i tasti Freccia per entrare o uscire dal cluster, ma devono premere la combinazione della tastiera di navigazione del cluster.
Visualizza stato attivo predefinito
In Android 8.0 (livello API 26), puoi assegnare l'elemento View
che dovrebbe essere attivo dopo che un'attività (ri)creata viene ripresa e l'utente preme un tasto di navigazione da tastiera, ad esempio il tasto Tab. Per applicare questa impostazione "impostata per impostazione predefinita", imposta l'attributo
android:focusedByDefault
di un elemento View
su true
nel file XML di layout contenente l'elemento UI oppure trasmettilo con true
a setFocusedByDefault()
nella logica dell'interfaccia utente dell'app.
Output vocale
Le attività e i servizi possono utilizzare istanze di
TextToSpeech
per dettare e pronunciare i contenuti. A partire da Android 8.0 (livello API 26), la tua app può ottenere informazioni sulla tempistica più precise relative al momento in cui un motore di sintesi vocale inizia a pronunciare singole parole sintetizzate, purché il motore fornisca queste informazioni. Puoi usare questa funzionalità
per richiamare l'attenzione su parole specifiche mentre il motore di sintesi vocale le pronuncia.
Per utilizzare questi miglioramenti del motore di sintesi vocale nella tua app, registra un'istanza di UtteranceProgressListener
. Come parte del processo di registrazione, includi un gestore per il metodo onRangeStart()
.
Il motore di sintesi vocale chiama
rangeStart()
per registrare
il momento in cui si prevede di iniziare la riproduzione audio di un intervallo specifico di
testo. Quando viene avviata la riproduzione dell'audio per quell'intervallo di testo, viene eseguito il metodo onRangeStart()
dell'app. L'app può quindi rispondere a questo callback, ad esempio evidenziando l'intervallo di testo associato all'espressione.
Per ulteriori informazioni sul monitoraggio dell'avanzamento della riproduzione di un motore di sintesi vocale, consulta la documentazione di riferimento della classe UtteranceProgressListener
.
Sistema
Nuovi rilevatori StrictMode
Android 8.0 (livello API 26) aggiunge tre nuovi rilevatori StrictMode per aiutarti a identificare potenziali bug nella tua app:
detectUnbufferedIo()
rileverà quando la tua app legge o scrive dati senza buffering, il che può influire drasticamente sulle prestazioni.detectContentUriWithoutPermission()
rileverà se la tua app dimentica accidentalmente di concedere le autorizzazioni a un'altra app quando avvia un'attività al di fuori dell'app.detectUntaggedSockets()
rileverà quando la tua app esegue traffico di rete senza utilizzaresetThreadStatsTag(int)
per codificare il traffico per scopi di debug.
Dati memorizzati nella cache
Android 8.0 (livello API 26) offre indicazioni e comportamenti migliori in merito ai dati memorizzati nella cache. A ogni app viene ora assegnata una quota di spazio su disco per i dati memorizzati nella cache, come viene restituito da getCacheQuotaBytes(UUID)
.
Quando il sistema ha bisogno di liberare spazio su disco, inizia eliminando i file memorizzati nella cache dalle app che superano di più la quota allocata. Pertanto, se mantieni i dati memorizzati nella cache al di sotto della quota allocata, i file memorizzati nella cache saranno tra gli ultimi nel sistema a essere cancellati quando necessario. Quando il sistema decide quali file memorizzati nella cache eliminare all'interno dell'app, prenderà in considerazione per primi i file meno recenti (in base a quanto stabilito dall'ora di modifica).
Esistono anche due nuovi comportamenti che puoi attivare in base alla directory per controllare in che modo il sistema libera i dati memorizzati nella cache:
StorageManager.setCacheBehaviorAtomic()
può essere usato per indicare che una directory e tutti i suoi contenuti devono essere eliminati come singola unità atomica.setCacheBehaviorTombstone(File, boolean)
può essere utilizzato per indicare che, anziché eliminare i file all'interno di una directory, questi devono essere troncati a 0 byte, lasciando intatto il file vuoto.
Infine, se devi allocare spazio su disco per file di grandi dimensioni, puoi utilizzare la nuova API allocateBytes(FileDescriptor, long)
, che cancellerà automaticamente i file memorizzati nella cache appartenenti ad altre app (se necessario) per soddisfare la tua richiesta. Per stabilire se il dispositivo dispone di spazio su disco sufficiente per contenere i nuovi dati, chiama getAllocatableBytes(UUID)
anziché utilizzare getUsableSpace()
, poiché il dispositivo prenderà in considerazione tutti i dati memorizzati nella cache che il sistema è disposto a cancellare per tuo conto.
Pagina del fornitore di contenuti
Abbiamo aggiornato i fornitori di contenuti in modo da includere il supporto per il caricamento di un set di dati di grandi dimensioni una pagina alla volta. Ad esempio, un'app di foto con molte migliaia di immagini può eseguire una query su un sottoinsieme di dati da presentare in una pagina. Ogni pagina di risultati restituiti da un fornitore di contenuti è rappresentata da un singolo oggetto Cursor. Sia un client che un provider devono implementare il paging per utilizzare questa funzionalità.
Per informazioni dettagliate sulle modifiche ai fornitori di contenuti, consulta
ContentProvider
e
ContentProviderClient
.
Richieste di aggiornamento dei contenuti
I corsi ContentProvider
e ContentResolver
ora includono un metodo refresh()
, che permette ai clienti di sapere più facilmente se le informazioni richieste sono aggiornate.
Puoi aggiungere una logica di aggiornamento dei contenuti personalizzata estendendo
ContentProvider
. Assicurati di eseguire l'override del metodo refresh()
per restituire true
, indicando ai client del tuo provider che hai tentato di aggiornare i dati personalmente.
La tua app client può richiedere esplicitamente contenuti aggiornati chiamando un
metodo diverso, chiamato anche
refresh()
. Quando chiami questo metodo, passa l'URI dei dati da aggiornare.
Nota: poiché potresti richiedere dati tramite una rete,
devi richiamare refresh()
dal
lato client solo se esiste un'indicazione chiara che i contenuti sono obsoleti.
Il motivo più comune per eseguire questo tipo di aggiornamento dei contenuti è la risposta a un gesto di scorri per aggiornare, che richiede esplicitamente all'interfaccia utente corrente di mostrare contenuti aggiornati.
Miglioramenti a JobScheduler
Android 8.0 (livello API 26) introduce una serie di miglioramenti a JobScheduler
. Questi miglioramenti consentono all'app di rispettare più facilmente i nuovi limiti di esecuzione in background, poiché in genere puoi utilizzare i job programmati per sostituire i servizi in background limitati o i ricevitori di trasmissione impliciti.
Gli aggiornamenti a JobScheduler
includono:
-
Ora puoi associare una coda di lavoro a un job pianificato. Per aggiungere un elemento di lavoro alla coda di un job, chiama
JobScheduler.enqueue()
. Quando il job è in esecuzione, può rimuovere il lavoro in sospeso dalla coda ed elaborarlo. Questa funzionalità gestisce molti dei casi d'uso che in precedenza avrebbero richiesto l'avvio di un servizio in background, in particolare i servizi che implementanoIntentService
. -
La libreria di supporto Android 26.0.0 introduce una nuova classe
JobIntentService
, che offre le stesse funzionalità diIntentService
, ma utilizza i job al posto dei servizi su Android 8.0 (livello API 26) o versioni successive. -
Ora puoi chiamare
JobInfo.Builder.setClipData()
per associareClipData
a un job. Questa opzione consente di associare le concessioni URI a un job, in modo simile alla propagazione di queste autorizzazioni aContext.startService()
. Puoi anche utilizzare concessioni di autorizzazioni URI con intent sulle code di lavoro. -
Ora i job pianificati supportano diversi nuovi vincoli:
JobInfo.isRequireStorageNotLow()
- Il job non viene eseguito se lo spazio di archiviazione disponibile sul dispositivo è in esaurimento.
JobInfo.isRequireBatteryNotLow()
- Il job non viene eseguito se il livello della batteria è pari o inferiore alla soglia critica; questo è il livello a cui il dispositivo mostra la finestra di dialogo del sistema di avviso di batteria in esaurimento.
NETWORK_TYPE_METERED
- Il job richiede una connessione di rete a consumo, come la maggior parte dei piani per la rete dati.
Datastore personalizzato
Android 8.0 (livello API 26) ti consente di fornire un datastore personalizzato in base alle tue preferenze, il che può essere utile se la tua app archivia le preferenze in un database cloud o locale oppure se le preferenze sono specifiche del dispositivo. Per scoprire di più sull'implementazione del datastore, consulta la pagina relativa al archivio di dati personalizzati.
Miglioramenti ai contenuti multimediali
Forma volume
C'è un nuovo corso VolumeShaper
. Usalo per eseguire brevi transizioni automatiche del volume come dissolvenze in entrata, in uscita e incrociate.
Per ulteriori informazioni, consulta Controllo dell'ampiezza con VolumeShaper.
Miglioramenti della messa a fuoco audio
Le app audio condividono l'output audio su un dispositivo richiedendo e abbandonando lo stato attivo dell'audio.
Un'app gestisce i cambiamenti di stato attivo avviando o interrompendo la riproduzione o riducendo il volume.
C'è un nuovo corso AudioFocusRequest
. Utilizzando questa classe come parametro di
requestAudioFocus()
,
le app hanno nuove funzionalità per la gestione dei cambiamenti nel focus audio:
attenuazione automatica automatica e
incremento della messa a fuoco ritardata.
Metriche dei media
Un nuovo metodo getMetrics()
restituisce un oggetto PersistableBundle
contenente informazioni sulla configurazione e sulle prestazioni, espresse sotto forma di mappa di attributi e valori.
Il metodo getMetrics()
è definito per queste classi multimediali:
MediaPlayer.getMetrics()
MediaRecorder.getMetrics()
MediaCodec.getMetrics()
MediaExtractor.getMetrics()
Le metriche vengono raccolte separatamente per ogni istanza e vengono mantenute per tutta la durata dell'istanza. Se non sono disponibili metriche, il metodo restituisce null. Le metriche effettive restituite dipendono dalla classe.
Media player
A partire da Android 8.0 (livello API 26), MediaPlayer è in grado di riprodurre materiali protetti da DRM e contenuti multimediali HLS criptati a livello di campione.
Android 8.0 introduce un nuovo comando seekTo()
sovraccarico che offre un controllo granulare quando cerchi di raggiungere un frame. Include un secondo parametro che specifica una modalità di ricerca:
SEEK_PREVIOUS_SYNC
sposta la posizione dell'elemento multimediale in un frame di sincronizzazione (o chiave) associato a un'origine dati che si trova immediatamente prima o in un determinato momento.SEEK_NEXT_SYNC
sposta la posizione dell'elemento multimediale in un frame di sincronizzazione (o chiave) associato a un'origine dati che si trova immediatamente dopo o in un determinato momento.SEEK_CLOSEST_SYNC
sposta la posizione dell'elemento multimediale in un frame di sincronizzazione (o chiave) associato a un'origine dati più vicina o nel momento specificato.SEEK_CLOSEST
sposta la posizione dell'elemento multimediale in un frame (non necessariamente una sincronizzazione o un frame chiave) associato a un'origine dati più vicina o in un determinato momento.
Per la ricerca continua, le app dovrebbero usare una qualsiasi delle modalità SEEK_
anziché SEEK_CLOSEST
, che è relativamente più lenta ma può essere più precisa.
MediaRecorder
- MediaRecorder ora supporta il formato MPEG2_TS, utile per lo streaming:
Kotlin
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS)
Java
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
visita
MediaRecorder.OutputFormat
- Ora
MediaMuxer
può gestire un numero qualsiasi di stream audio e video. Non sei più limitato a una sola traccia audio e/o a una traccia video. UsaaddTrack()
per mixare tutte le tracce che vuoi. MediaMuxer
può anche aggiungere una o più tracce di metadati contenenti informazioni per frame definite dall'utente. Il formato dei metadati è definito dalla tua applicazione. La traccia dei metadati è supportata solo per i container MP4.
I metadati possono essere utili per l'elaborazione offline. Ad esempio, i segnali del giroscopio del sensore potrebbero essere usati per la stabilizzazione video.
Quando aggiungi una traccia di metadati, il formato MIME della traccia deve iniziare con il prefisso "application/". Scrivere metadati equivale a scrivere dati video/audio, ad eccezione del fatto che i dati non provengono da un MediaCodec
. Invece, l'app trasmette un
ByteBuffer
con un timestamp associato al
metodo writeSampleData()
.
Il timestamp deve trovarsi nella stessa base temporale delle tracce video e audio.
Il file MP4 generato utilizza il valore TextMetaDataSampleEntry
definito nella sezione
12.3.3.2 dell'ISOBMFF per segnalare il formato MIME dei metadati. Quando utilizzi MediaExtractor
per estrarre il file con la traccia di metadati, il formato MIME dei metadati viene estratto in MediaFormat
.
Accesso ai file multimediali migliorato
Storage Access Framework (SAF) consente alle app di esporre un elemento DocumentsProvider
personalizzato, che può fornire ad altre app l'accesso ai file di un'origine dati. Un fornitore di documenti può anche fornire l'accesso a file che risiedono nello spazio di archiviazione di rete o che utilizzano un protocollo come Media Transfer Protocol (MTP).
Tuttavia, l'accesso a file multimediali di grandi dimensioni da un'origine dati remota presenta alcune sfide:
- I lettori multimediali richiedono l'accesso ricercabile a un file da un fornitore di documenti. Nei casi in cui un file multimediale di grandi dimensioni si trovi in un'origine dati remota, il fornitore di documenti deve recuperare tutti i dati in anticipo e creare un descrittore del file di snapshot. Il media player non può riprodurre il file senza il descrittore del file, pertanto la riproduzione non può iniziare finché il fornitore dei documenti non completa il download del file.
- I gestori delle raccolte multimediali, come le app di foto, devono attraversare una serie di URI di accesso per raggiungere i contenuti multimediali archiviati su una scheda SD esterna tramite cartelle con ambito. Questo pattern di accesso rende abbastanza lente le operazioni di massa sui supporti, come spostamento, copia ed eliminazione.
- I gestori delle raccolte multimediali non possono determinare la posizione di un documento in base all'URI. Di conseguenza, per questi tipi di app è difficile consentire agli utenti di scegliere dove salvare un file multimediale.
Android 8.0 risolve ognuna di queste sfide migliorando il framework Storage Access.
Fornitori di documenti personalizzati
A partire da Android 8.0, Storage Access Framework consente ai provider di documenti personalizzati di creare descrittori di file ricercabili per i file che risiedono in un'origine dati remota. Il SAF può aprire un file per ottenere un descrittore di file ricercabile nativo. La SAF invia quindi richieste di byte discreti al fornitore di documenti. Questa funzionalità consente a un fornitore di documenti di restituire l'intervallo esatto di byte richiesti da un'app di media player, anziché memorizzare in anticipo la cache dell'intero file.
Per utilizzare questa funzionalità, devi chiamare il nuovo
metodo StorageManager.openProxyFileDescriptor()
. Il metodo openProxyFileDescriptor()
accetta un oggetto ProxyFileDescriptorCallback
come callback. Il SAF richiama il callback ogni volta che un'applicazione client esegue operazioni con il file sul descrittore del file restituito dal fornitore dei documenti.
Accesso diretto ai documenti
A partire da Android 8.0 (livello API 26), puoi usare il metodo getDocumentUri()
per ottenere un URI che faccia riferimento allo stesso documento del mediaUri
specificato.
Tuttavia, poiché l'URI restituito è supportato da DocumentsProvider
, i gestori delle raccolte multimediali possono accedere direttamente al documento senza dover attraversare strutture di directory con ambito.
Di conseguenza, i gestori dei media possono eseguire operazioni con i file sul documento in modo notevolmente più rapido.
Attenzione: il metodo getDocumentUri()
individua solo i file multimediali e non concede alle app l'autorizzazione ad accedere a questi file. Per scoprire di più su come ottenere l'autorizzazione di accesso ai file multimediali, consulta la documentazione di riferimento.
Percorsi dei documenti
Quando usi Storage Access Framework in Android 8.0 (livello API 26), puoi usare il metodo findDocumentPath()
, disponibile in entrambe le classi DocumentsContract
e DocumentsProvider
, per determinare il percorso dalla radice di un file system a partire dall'ID di un documento. Il metodo restituisce questo percorso in un oggetto DocumentsContract.Path
. Nei casi in cui un file system ha più percorsi definiti per lo stesso documento, il metodo restituisce il percorso utilizzato più spesso per raggiungere il documento con l'ID specificato.
Questa funzionalità è particolarmente utile nei seguenti scenari:
- L'app utilizza una finestra di dialogo "Salva con nome" che mostra la posizione di un determinato documento.
- L'app mostra le cartelle in una visualizzazione dei risultati di ricerca e deve caricare i documenti secondari che si trovano in una determinata cartella se l'utente seleziona questa cartella.
Nota: se la tua app è autorizzata ad accedere solo ad alcuni documenti nel percorso, il valore restituito findDocumentPath()
include solo le cartelle e i documenti a cui può accedere l'app.
Monitoraggio della riproduzione audio
Il servizio di sistema AudioManager
gestisce un elenco di oggetti AudioPlaybackConfiguration
attivi, ognuno dei quali contiene informazioni su una determinata sessione di riproduzione audio. La tua app può recuperare l'insieme delle configurazioni attualmente attive chiamando getActivePlaybackConfigurations()
.
A partire da Android 8.0 (livello API 26), puoi registrare un callback che avvisa la tua app quando uno o più oggetti AudioPlaybackConfiguration
sono stati modificati. Per farlo, chiama registerAudioPlaybackCallback()
, passando un'istanza di AudioManager.AudioPlaybackCallback
. La classe AudioManager.AudioPlaybackCallback
contiene il metodo onPlaybackConfigChanged()
, che il sistema chiama quando la configurazione della riproduzione audio cambia.
Connettività
Consapevole al Wi-Fi
Android 8.0 (livello API 26) aggiunge il supporto per Wi-Fi Aware, che è basato sulla specifica Nearby Awareness Networking (NAN). Sui dispositivi con hardware Wi-Fi Aware appropriato, le app e i dispositivi nelle vicinanze possono rilevare e comunicare tramite Wi-Fi senza un punto di accesso a internet. Stiamo collaborando con i nostri partner hardware per introdurre la tecnologia Wi-Fi Aware nei dispositivi il prima possibile. Per informazioni su come integrare Wi-Fi Aware nella tua app, consulta Wi-Fi Aware.
Bluetooth
Android 8.0 (livello API 26) arricchisce il supporto Bluetooth della piattaforma aggiungendo le seguenti funzionalità:
- Supporto per lo standard AVRCP 1.4, che consente la navigazione nelle raccolte di brani.
- Supporto per lo standard Bluetooth Low-Energy (BLE) 5.0.
- Integrazione del codec LDAC di Sony nello stack Bluetooth.
Accoppiamento dispositivo associato
Android 8.0 (livello API 26) fornisce API che consentono di personalizzare la finestra di dialogo della richiesta di accoppiamento quando si cerca di eseguire l'accoppiamento con dispositivi associati tramite Bluetooth, BLE e Wi-Fi. Per maggiori informazioni, consulta la sezione Accoppiamento dispositivo associato.
Per ulteriori informazioni sull'uso del Bluetooth su Android, consulta la guida sul Bluetooth. Per le modifiche al Bluetooth specifiche di Android 8.0 (livello API 26), consulta la sezione Bluetooth nella pagina Modifiche al comportamento di Android 8.0.
Condivisione
Condivisione intelligente
Android 8.0 (livello API 26) apprende le preferenze di condivisione personalizzate degli utenti e comprende meglio ogni tipo di contenuto che rappresenta le app giuste con cui condividere. Ad esempio, se un utente scatta la foto di una ricevuta, Android 8.0 può suggerire un'app per il monitoraggio delle spese; se l'utente scatta un selfie, un'app di social media può gestire meglio l'immagine. Android 8.0 apprende automaticamente tutti questi pattern in base alle preferenze degli utenti.
La condivisione intelligente funziona per tipi di contenuti diversi da image
, ad esempio audio
, video
, text
, URL
e così via.
Per attivare la condivisione intelligente, aggiungi un ArrayList
di massimo tre
annotazioni di stringa all'intent che condivide i contenuti. Le annotazioni devono descrivere i componenti o gli argomenti principali nei contenuti. Il seguente esempio di codice mostra come aggiungere annotazioni all'intent:
Kotlin
val annotations: ArrayList<String> = arrayListOf( "topic1", "topic2", "topic3" ) intent.putStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS, annotations )
Java
ArrayList<String> annotations = new ArrayList<>(); annotations.add("topic1"); annotations.add("topic2"); annotations.add("topic3"); intent.putStringArrayListExtra( Intent.EXTRA_CONTENT_ANNOTATIONS, annotations );
Per informazioni dettagliate sulle annotazioni con condivisione intelligente, consulta
EXTRA_CONTENT_ANNOTATIONS
.
Classificazione del testo
Sui dispositivi compatibili, le app possono usare un nuovo classificatore di testo per verificare se una stringa corrisponde a un tipo di entità classificatore noto e ottenere alternative di selezione suggerite. Le entità riconosciute dal sistema includono indirizzi, URL,
numeri di telefono e indirizzi email. Per ulteriori informazioni, consulta
TextClassifier
.
Accessibilità
Android 8.0 (livello API 26) supporta diverse nuove funzioni di accessibilità per gli sviluppatori che creano i propri servizi di accessibilità:
- Una nuova categoria di volume per la regolazione del volume di accessibilità.
- Gesti con impronta come meccanismo di immissione.
- Funzionalità di sintesi vocale multilingue.
- Una scorciatoia per l'accessibilità basata su hardware per accedere rapidamente a un servizio di accessibilità preferito.
- Supporto per gesti continui o sequenze di tratti programmatiche.
- Un pulsante di accessibilità per richiamare una delle numerose funzioni di accessibilità attive (disponibile solo sui dispositivi che utilizzano un'area di navigazione con rendering software).
- Valori di intervallo unilaterali standardizzati.
- Diverse funzionalità per elaborare il testo più facilmente, inclusi il testo del suggerimento e le posizioni dei caratteri del testo sullo schermo.
Sicurezza e privacy
Autorizzazioni
Android 8.0 (livello API 26) introduce diverse nuove autorizzazioni relative alla telefonia:
- L'autorizzazione
ANSWER_PHONE_CALLS
consente alla tua app di rispondere alle telefonate in arrivo in modo programmatico. Per gestire una chiamata in arrivo nella tua app, puoi utilizzare il metodoacceptRingingCall()
. - L'autorizzazione
READ_PHONE_NUMBERS
concede alla tua app l'accesso in lettura ai numeri di telefono memorizzati su un dispositivo.
Queste autorizzazioni sono entrambe classificate come
pericolose
e fanno parte del gruppo di
autorizzazioni
PHONE
.
Nuove API di accesso e discovery per gli account
Android 8.0 (livello API 26) introduce diversi miglioramenti al modo in cui le app accedono agli account utente. Per gli account che gestiscono, gli autenticati possono utilizzare le proprie norme per decidere se nascondere gli account a un'app o se rivelarli a un'app. Il sistema Android monitora le applicazioni che possono accedere a un determinato account.
Nelle versioni precedenti di Android, le app che volevano monitorare l'elenco degli account utente dovevano ricevere aggiornamenti su tutti gli account, inclusi quelli con tipi non correlati. Android 8.0 aggiunge il metodo addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])
, che consente alle app di specificare un elenco di tipi di account per i quali devono essere ricevute le modifiche dell'account.
Modifiche all'API
AccountManager offre sei nuovi metodi per aiutare gli autenticati a gestire le app che possono visualizzare un account:
setAccountVisibility(android.accounts.Account, java.lang.String, int)
: imposta il livello di visibilità per una combinazione specifica di account utente e pacchetto.-
getAccountVisibility(android.accounts.Account, java.lang.String)
: recupera il livello di visibilità per una combinazione specifica di account utente e pacchetti. -
getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String)
: consente agli autenticati di ottenere gli account e i livelli di visibilità per un determinato pacchetto. -
getPackagesAndVisibilityForAccount(android.accounts.Account)
: consente agli autenticati di ottenere i valori di visibilità archiviati per un determinato account. -
addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>)
: consente agli autenticati di inizializzare i valori di visibilità di un account. -
addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[])
: aggiunge un listenerOnAccountsUpdateListener
all'oggettoAccountManager
. Il sistema chiama questo listener ogni volta che cambia l'elenco di account sul dispositivo.
Android 8.0 (livello API 26) introduce due valori speciali per il nome del pacchetto per specificare i livelli di visibilità per le applicazioni che non sono state impostate utilizzando il metodo setAccountVisibility(android.accounts.Account, java.lang.String, int)
. Il valore di visibilità PACKAGE_NAME_KEY_LEGACY_VISIBLE
viene applicato alle app che hanno l'autorizzazione GET_ACCOUNTS
e alle versioni di destinazione di Android precedenti ad Android 8.0 o le cui firme corrispondono all'autenticatore che ha come target qualsiasi versione di Android.
PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE
fornisce un valore di visibilità predefinito per le app che non sono state impostate in precedenza e per le quali
PACKAGE_NAME_KEY_LEGACY_VISIBLE
non è
applicabile.
Per saperne di più sulle nuove API di accesso e di rilevamento dell'account, consulta la documentazione di riferimento per AccountManager
e OnAccountsUpdateListener
.
Test
Test della strumentazione
Android 8.0 (livello API 26) fornisce i seguenti elementi di supporto aggiuntivo per i test di strumentazione della tua app.
Esegui in base a processi dell'app non predefiniti
Ora puoi specificare che un determinato test di strumentazione deve essere eseguito su un processo al di fuori del processo predefinito dell'app. Questa configurazione è utile se la tua app contiene più attività eseguite in processi diversi.
Per definire la strumentazione di processo non predefinita, vai al file manifest, quindi all'elemento
<instrumentation>
desiderato. Aggiungi l'attributo android:targetProcess
e impostane il valore su uno dei seguenti:
- Il nome di un determinato processo.
- Un elenco di nomi di processi separati da virgole.
- Un carattere jolly (
"*"
), che consente alla strumentazione di essere eseguita su qualsiasi processo avviato che esegue il codice nel pacchetto specificato nell'attributoandroid:targetPackage
.
Mentre è in esecuzione il test della strumentazione, puoi controllare quale processo si sta verificando chiamando getProcessName()
.
Risultati dei report durante un test
Ora puoi generare report sui risultati mentre è in esecuzione il test della strumentazione, anziché in un secondo momento, chiamando addResults()
.
Intenzioni fittizie per i test
Per semplificare la creazione di test isolati e indipendenti dell'interfaccia utente per le attività della tua app, Android 8.0 (livello API 26) introduce il metodo onStartActivity()
. Esegui l'override di questo metodo in una sottoclasse personalizzata della classe Instrumentation.ActivityMonitor
per gestire un particolare intent richiamato dalla tua classe di test.
Quando la classe di test richiama l'intent, il metodo restituisce un oggetto stub Instrumentation.ActivityResult
invece di eseguire l'intent stesso. Utilizzando questa logica di intent fittizia nei tuoi test, puoi concentrarti su come la tua attività prepara e gestisce l'intent che passi a un'attività diversa o a un'app completamente diversa.
Runtime e strumenti
Ottimizzazioni della piattaforma
Android 8.0 (livello API 26) introduce sulla piattaforma ottimizzazioni di runtime e di altro tipo, che apportano una serie di miglioramenti delle prestazioni. Queste ottimizzazioni includono la garbage collection di compattazione simultanea, un uso più efficiente della memoria e la località del codice.
Queste ottimizzazioni si traducono in tempi di avvio più rapidi e in prestazioni migliori sia nel sistema operativo che nelle app.
Supporto del linguaggio Java aggiornato
Android 8.0 (livello API 26) aggiunge il supporto per diverse API OpenJDK Java aggiuntive:
java.time
da OpenJDK 8.java.nio.file
ejava.lang.invoke
da OpenJDK 7.
Per saperne di più sulle classi e sui metodi all'interno di questi pacchetti appena aggiunti, consulta la documentazione di riferimento dell'API.
Se vuoi utilizzare le funzionalità in linguaggio Java 8 in Android Studio, devi scaricare l'ultima versione di anteprima.
API ICU4J Android Framework aggiornate
Android 8.0 (livello API 26) estende le API framework per Android ICU4J, che sono un sottoinsieme delle API ICU4J, che gli sviluppatori di app possono utilizzare nel pacchetto android.icu
. Queste API utilizzano i dati di localizzazione presenti sul dispositivo, quindi puoi ridurre l'utilizzo dell'APK non compilando le librerie ICU4J nell'APK.
Tabella 1. Versioni ICU, CLDR e Unicode utilizzate in Android.
Livello API Android | Versione per T.I. | Versione CLDR | Versione Unicode |
---|---|---|---|
Android 7.0 (livello API 24), Android 7.1 (livello API 25) | 56 | 28 | con Android 8.0 |
Android 8.0 (livello API 26) | 58,2 | 30,0,3 | 9.0 |
Per ulteriori informazioni sull'internazionalizzazione su Android, incluso il supporto di ICU4J, consulta Internazionalizzazione su Android.
Android Enterprise
Per i dispositivi con Android 8.0 (livello API 26) sono state introdotte nuove funzionalità e API aziendali. Le caratteristiche principali includono:
- I profili di lavoro sui dispositivi completamente gestiti consentono alle aziende di separare il lavoro dai dati personali, gestendo al contempo entrambi i casi.
- La delega API consente ai proprietari dei dispositivi e dei profili di assegnare la gestione delle app ad altre applicazioni.
- I miglioramenti dell'esperienza utente nel flusso di provisioning (incluse nuove opzioni di personalizzazione) riducono i tempi di configurazione.
- I nuovi controlli su Bluetooth, Wi-Fi, backup e sicurezza consentono alle aziende di gestire una parte maggiore del dispositivo. Il logging delle attività di rete consente alle aziende di individuare i problemi.
Per saperne di più su queste e altre nuove API e funzionalità di Android Enterprise, consulta Android nella versione Enterprise.