Modifiche del comportamento: tutte le app

Android 9 (livello API 28) introduce una serie di modifiche al sistema Android, Le seguenti modifiche del comportamento si applicano a tutte le app quando vengono eseguite sulla piattaforma Android 9, indipendentemente dal livello API target. Tutti gli sviluppatori sono tenuti a esaminare le modifiche e modificare le proprie app per supportare correttamente le modifiche, ove applicabile.

Per le modifiche che interessano solo le app che hanno come target il livello API 28 o versioni successive, consulta Modifiche del comportamento: app che hanno come target i livelli API 28 o versioni successive.

Gestione alimentazione

Android 9 introduce nuove funzionalità per migliorare la gestione dell'alimentazione dei dispositivi. Queste modifiche, insieme alle funzionalità già presenti prima di Android 9, aiutano a garantire che le risorse di sistema siano rese disponibili per le app che ne hanno più bisogno.

Per maggiori dettagli, consulta Gestione dell'alimentazione.

Modifiche relative alla privacy

Per migliorare la privacy degli utenti, Android 9 introduce diversi cambiamenti del comportamento, ad esempio la limitazione dell'accesso delle app in background ai sensori dei dispositivi e la limitazione delle informazioni recuperate dalle ricerche di reti Wi-Fi, nonché nuove regole e nuovi gruppi di autorizzazioni relativi a telefonate, stato del telefono e ricerche di reti Wi-Fi.

Queste modifiche interessano tutte le app eseguite su Android 9, indipendentemente dalla versione target dell'SDK.

Accesso limitato ai sensori in background

Android 9 limita la possibilità delle app in background di accedere ai dati dei sensori e degli input utente. Se la tua app è in esecuzione in background su un dispositivo con Android 9, il sistema applica le seguenti limitazioni alla tua app:

  • La tua app non può accedere al microfono o alla fotocamera.
  • I sensori che utilizzano la modalità di segnalazione continua, ad esempio accelerometri e giroscopi, non ricevono eventi.
  • I sensori che utilizzano le modalità di reporting al cambiamento o one-shot non ricevono eventi.

Se la tua app deve rilevare gli eventi dei sensori sui dispositivi con Android 9, utilizza un servizio in primo piano.

Accesso limitato ai registri chiamate

Android 9 introduce il gruppo di autorizzazioni CALL_LOG e sposta le autorizzazioni READ_CALL_LOG, WRITE_CALL_LOG e PROCESS_OUTGOING_CALLS in questo gruppo. Nelle versioni precedenti di Android, queste autorizzazioni si trovavano nel gruppo di autorizzazioni PHONE.

Questo gruppo di autorizzazioni CALL_LOG offre agli utenti un controllo e una visibilità migliori delle app che devono accedere a informazioni sensibili sulle chiamate, ad esempio la lettura dei registri delle telefonate e l'identificazione dei numeri di telefono.

Se la tua app richiede l'accesso ai registri chiamate o deve elaborare le chiamate in uscita, devi richiedere esplicitamente queste autorizzazioni al gruppo di autorizzazioni CALL_LOG. In caso contrario, si verifica un SecurityException.

Nota : poiché queste autorizzazioni hanno cambiato gruppi e vengono concesse in fase di runtime, è possibile che l'utente neghi alla tua app l'accesso alle informazioni dei registri chiamate del telefono. In questo caso, la tua app dovrebbe essere in grado di gestire agevolmente la mancanza di accesso alle informazioni.

Se la tua app segue già le best practice relative alle autorizzazioni di runtime, può gestire la modifica nel gruppo di autorizzazioni.

Accesso limitato ai numeri di telefono

Le app eseguite su Android 9 non possono leggere i numeri di telefono o lo stato dei telefoni senza prima aver acquisito l'autorizzazione READ_CALL_LOG, oltre alle altre autorizzazioni richieste dai casi d'uso della tua app.

I numeri di telefono associati alle chiamate in entrata e in uscita sono visibili nella trasmissione dello stato del telefono, ad esempio per le chiamate in entrata e in uscita, e sono accessibili dalla classe PhoneStateListener. Tuttavia, senza l'autorizzazione READ_CALL_LOG, il campo del numero di telefono fornito negli annunci PHONE_STATE_CHANGED e tramite PhoneStateListener è vuoto.

Per leggere i numeri di telefono dallo stato del telefono, aggiorna l'app in modo che richieda le autorizzazioni necessarie in base al caso d'uso:

Accesso limitato alle informazioni sulla posizione e sulla connessione Wi-Fi

In Android 9, i requisiti di autorizzazione per l'esecuzione di scansioni di reti Wi-Fi da parte di un'app sono più rigidi rispetto alle versioni precedenti. Per maggiori dettagli, consulta le limitazioni relative alla ricerca di reti Wi-Fi.

Restrizioni simili si applicano anche al metodo getConnectionInfo(), che restituisce un oggetto WifiInfo che descrive la connessione Wi-Fi attuale. Puoi utilizzare i metodi di questo oggetto per recuperare i valori SSID e BSSID soltanto se l'app chiamante dispone delle seguenti autorizzazioni:

  • ACCESS_FINE_LOCATION o ACCESS_COARSE_LOCATION
  • STATO_DI_ACCESSO WIFI

Il recupero di SSID o BSSID richiede anche l'attivazione dei servizi di geolocalizzazione sul dispositivo (in Impostazioni > Posizione).

Informazioni rimosse dai metodi del servizio Wi-Fi

In Android 9, i seguenti eventi e trasmissioni non ricevono informazioni sulla posizione dell'utente o sui dati che consentono l'identificazione personale:

La trasmissione del sistema NETWORK_STATE_CHANGED_ACTION dalla rete Wi-Fi non contiene più informazioni su SSID (precedentemente EXTRA_SSID), BSSID (in precedenza EXTRA_BSSID) o informazioni sulla connessione (in precedenza EXTRA_NETWORK_INFO). Se la tua app ha bisogno di queste informazioni, chiama invece getConnectionInfo().

Le informazioni di telefonia ora si basano sull'impostazione di geolocalizzazione del dispositivo

Se l'utente ha disattivato la posizione del dispositivo su un dispositivo con Android 9, i seguenti metodi non forniscono risultati:

Limitazioni relative all'utilizzo di interfacce non SDK

Per garantire la stabilità e la compatibilità delle app, la piattaforma limita l'uso di alcuni metodi e campi non SDK. Queste limitazioni si applicano a prescindere dal fatto che tu provi ad accedere a questi metodi e campi direttamente, tramite riflessione o utilizzando JNI. In Android 9, la tua app può continuare ad accedere a queste interfacce limitate; la piattaforma utilizza toast e voci di log per portarle alla tua attenzione. Se la tua app mostra questo toast, è importante adottare una strategia di implementazione diversa dall'interfaccia con limitazioni. Se ritieni che non sia possibile applicare alcuna strategia alternativa, puoi segnalare un bug per richiedere la riconsiderazione della limitazione.

Restrizioni sulle interfacce non SDK contiene ulteriori informazioni importanti. Dovresti esaminarlo per assicurarti che l'app continui a funzionare correttamente.

Modifiche al comportamento di sicurezza

Modifiche alla sicurezza del dispositivo

Android 9 aggiunge diverse funzionalità che migliorano la sicurezza della tua app, indipendentemente dalla versione scelta come target.

Modifiche all'implementazione TLS

L'implementazione TLS del sistema ha subito diversi cambiamenti in Android 9:

Per scoprire di più su come effettuare richieste web sicure in un'app per Android, vedi Un esempio di HTTPS.

Filtro SECCOMP più rigido

Android 9 limita ulteriormente le chiamate di sistema disponibili per le app. Questo comportamento è un'estensione del filtro SECCOMP incluso in Android 8.0 (livello API 26).

Modifiche crittografiche

Android 9 introduce diverse modifiche all'implementazione e alla gestione degli algoritmi crittografici.

Cripta le implementazioni di parametri e algoritmi

Android 9 fornisce implementazioni aggiuntive dei parametri dell'algoritmo in Conscrypt. Questi parametri includono: AES, DESEDE, OAEP ed EC. Le versioni Bouncy Castle di questi parametri e molti algoritmi sono state ritirate a partire da Android 9.

Se la tua app ha come target Android 8.1 (livello API 27) o versioni precedenti, riceverai un avviso quando richiedi l'implementazione di Bouncy Castle di uno di questi algoritmi deprecati. Se scegli come target Android 9, tuttavia, queste richieste generano ciascuna un NoSuchAlgorithmException.

Altre modifiche

Android 9 introduce diverse altre modifiche relative alla crittografia:

  • Quando utilizzi le chiavi PBE, se Bouncy Castle prevede un vettore di inizializzazione (IV) e la tua app non ne fornisce uno, ricevi un avviso.
  • L'implementazione di Conscrypt della crittografia ARC4 consente di specificare ARC4/ECB/NoPadding o ARC4/NONE/NoPadding.
  • Il provider JCA (Crypto Java Cryptography Architecture) è stato rimosso. Di conseguenza, se la tua app chiama SecureRandom.getInstance("SHA1PRNG", "Crypto"), si verifica un NoSuchProviderException.
  • Se la tua app analizza le chiavi RSA da buffer più grandi della struttura della chiave, non si verifica più un'eccezione.

Per scoprire di più sull'utilizzo delle funzionalità crittografiche di Android, consulta Crittografia.

I file criptati protetti per Android non sono più supportati

Android 9 rimuove completamente il supporto per i file ASEC (Secure Encrypted) di Android.

In Android 2.2 (livello API 8), Android ha introdotto le ASEC per supportare la funzionalità delle app su scheda SD. Su Android 6.0 (livello API 23), la piattaforma ha introdotto una tecnologia per dispositivi di archiviazione utilizzabili che gli sviluppatori possono utilizzare al posto delle ASEC.

Aggiornamenti alle librerie ICU

Android 9 utilizza la versione 60 della libreria di ICU. Android 8.0 (livello API 26) e Android 8.1 (livello API 27) utilizzano ICU 58.

L'ICU viene utilizzata per fornire API pubbliche al di sotto di android.icu package e viene utilizzata internamente nella piattaforma Android per supportare l'internazionalizzazione. Ad esempio, viene utilizzato per implementare le classi Android in java.util, java.text e android.text.format.

L'aggiornamento a ICU 60 contiene molte modifiche piccole ma utili, tra cui il supporto dei dati di Emoji 5.0 e i formati di data e ora migliorati, come documentato nelle note di rilascio di ICU 59 e ICU 60.

Modifiche importanti in questo aggiornamento:

  • Il modo in cui la piattaforma gestisce i fusi orari è cambiato.
    • La piattaforma gestisce meglio GMT e UTC; UTC non è più un sinonimo di GMT.

      ICU ora fornisce nomi di zona tradotti per GMT e UTC. Questa modifica influisce sul comportamento di formattazione e analisi di android.icu per zone come "GMT", "Etc/GMT", "UTC", "Etc/UTC" e "Zulu".

    • java.text.SimpleDateFormat ora utilizza ICU per fornire nomi visualizzati per UTC /GMT, il che significa:
      • La formattazione di zzzz genera una lunga stringa localizzata per molte impostazioni internazionali. In precedenza, produceva "UTC" per UTC e stringhe come "GMT+00:00" per GMT.
      • L'analisi di zzzz riconosce stringhe come "Universal Coordinated Time" (Tempo coordinato universale) e "Greenwich Mean Time" (Ora del meridiano di Greenwich).
      • Le app potrebbero riscontrare problemi di compatibilità se presuppongono che l'output "UTC" o "GMT+00:00" venga restituito per zzzz in tutte le lingue.
    • Il comportamento di java.text.DateFormatSymbols.getZoneStrings() è cambiato:
      • Come per SimpleDateFormat, UTC e GMT ora hanno nomi lunghi. Le varianti DST dei nomi dei fusi orari per la zona UTC, ad esempio "UTC", "Etc/UTC" e "Zulu", diventano GMT+00:00, che rappresentano il fuso orario di riserva standard quando non sono disponibili nomi al posto della stringa hardcoded UTC.
      • Alcuni ID zona vengono riconosciuti correttamente come sinonimi di altre zone, pertanto Android trova le stringhe per gli ID zona arcaici, come Eire, che in precedenza non potevano essere risolti.
    • L'Asia/Hanoi non è più una zona riconosciuta. Per questo motivo, java.util.TimeZones.getAvailableIds() non restituisce questo valore e java.util.TimeZone.getTimeZone() non lo riconosce. Questo comportamento è coerente con il comportamento esistente di android.icu.
  • Il metodo android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String) potrebbe generare un ParseException anche durante l'analisi del testo in valuta legittimo. Per evitare questo problema, utilizza NumberFormat.parseCurrency, disponibile a partire da Android 7.0 (livello API 24), per il testo della valuta in stile PLURALCURRENCYSTYLE.

Modifiche ad Android Test

Android 9 introduce diverse modifiche alla libreria e alla struttura delle classi del framework Android Test. Queste modifiche aiutano gli sviluppatori a utilizzare API pubbliche supportate da framework, ma consentono anche una maggiore flessibilità nella creazione e nell'esecuzione di test utilizzando librerie di terze parti o logica personalizzata.

Librerie rimosse dal framework

Android 9 riorganizza le classi basate su JUnit in tre librerie: android.test.base, android.test.runner e android.test.mock. Questa modifica consente di eseguire test su una versione di JUnit che funziona meglio con le dipendenze del progetto. Questa versione di JUnit potrebbe essere diversa da quella fornita da android.jar.

Per scoprire di più su come le classi basate su JUnit sono organizzate in queste librerie e su come preparare il progetto dell'app per la scrittura e l'esecuzione di test, consulta Configurare un progetto per Android Test.

Modifiche alla build della suite di test

Il metodo addRequirements() nella classe TestSuiteBuilder è stato rimosso e la classe TestSuiteBuilder stessa è stata deprecata. Il metodo addRequirements() richiedeva agli sviluppatori di fornire argomenti i cui tipi erano API nascoste, perciò l'API non era valida.

Decodificatore UTF Java

UTF-8 è il set di caratteri predefinito in Android. Una sequenza di byte UTF-8 può essere decodificata da un costruttore String, come String(byte[] bytes).

Il decoder UTF-8 di Android 9 segue gli standard Unicode in modo più rigoroso rispetto alle versioni precedenti. Le modifiche includono:

  • La forma non più breve di UTF-8, ad esempio <C0, AF>, viene considerata di formato errato.
  • La forma surrogata della UTF-8, ad esempio U+D800..U+DFFF, viene trattata come malformata.
  • La sottoparte massima è sostituita da un singolo U+FFFD. Ad esempio, nella sequenza di byte "41 C0 AF 41 F4 80 80 41", le sottoparti massime sono "C0", "AF" e "F4 80 80". "F4 80 80" può essere la sottosequenza iniziale di "F4 80 80 80", ma "C0" non può essere la sottosequenza iniziale di qualsiasi sequenza di unità di codice ben strutturata. Di conseguenza, l'output dovrebbe essere "A\ufffd\ufffdA\ufffdA".
  • Per decodificare una sequenza UTF-8 / CESU-8 modificata in Android 9 o versioni successive, utilizza il metodo DataInputStream.readUTF() o il metodo JNI NewStringUTF().

Verifica del nome host mediante un certificato

RFC 2818 descrive due metodi per associare un nome di dominio a un certificato: utilizzare i nomi disponibili all'interno dell'estensione subjectAltName (SAN) o, in assenza di un'estensione SAN, fare riferimento a commonName (CN).

Tuttavia, il metodo di riserva a CN è stato ritirato in RFC 2818. Per questo motivo, Android non ricorre più all'utilizzo di CN. Per verificare un nome host, il server deve presentare un certificato con un valore SAN corrispondente. I certificati che non contengono un valore SAN corrispondente al nome host non sono più attendibili.

Le ricerche di indirizzi di rete possono causare violazioni della rete

Le ricerche di indirizzi di rete che richiedono la risoluzione dei nomi possono includere l'I/O di rete e sono quindi considerate operazioni di blocco. Il blocco delle operazioni sul thread principale può causare pause o jank.

La classe StrictMode è uno strumento di sviluppo che aiuta gli sviluppatori a rilevare i problemi nel codice.

In Android 9 e versioni successive, StrictMode rileva le violazioni di rete causate da ricerche di indirizzi di rete che richiedono la risoluzione dei nomi.

Non spedire le app con StrictMode abilitato. In questo caso, le tue app potrebbero riscontrare eccezioni, ad esempio NetworkOnMainThreadException quando utilizzi i metodi detectNetwork() o detectAll() per ottenere un criterio che rilevi le violazioni di rete.

La risoluzione di un indirizzo IP numerico non è considerata un'operazione di blocco. La risoluzione degli indirizzi IP numerici funziona come nelle versioni precedenti ad Android 9.

Tagging socket

Nelle versioni della piattaforma precedenti ad Android 9, se un socket viene taggato utilizzando il metodo setThreadStatsTag(), il socket non viene taggato quando viene inviato a un altro processo utilizzando l'IPC di Binder con un container ParcelFileDescriptor.

In Android 9 e versioni successive, il tag socket viene conservato quando viene inviato a un altro processo utilizzando l'IPC di binder. Questa modifica può influire sulle statistiche del traffico di rete, ad esempio quando utilizzi il metodo queryDetailsForUidTag().

Se vuoi mantenere il comportamento delle versioni precedenti, annullando il tagging di un socket inviato a un altro processo, puoi chiamare untagSocket() prima di inviare il socket.

Quantità segnalata di byte disponibili nel socket

Il metodo available() restituisce 0 quando viene richiamato dopo aver richiamato il metodo shutdownInput().

Report più dettagliati sulle funzionalità di rete per le VPN

In Android 8.1 (livello API 27) e versioni precedenti, la classe NetworkCapabilities segnalava solo un insieme limitato di informazioni per le VPN, come TRANSPORT_VPN, ma ometteva NET_CAPABILITY_NOT_VPN. Queste informazioni limitate erano difficile determinare se l'utilizzo di una VPN avrebbe comportato addebiti per l'utente dell'app. Ad esempio, controllare NET_CAPABILITY_NOT_METERED non determina se le reti sottostanti sono a consumo o meno.

In Android 9 e versioni successive, quando una VPN chiama il metodo setUnderlyingNetworks(), il sistema Android unisce i trasporti e le funzionalità di qualsiasi rete sottostante e restituisce il risultato come funzionalità di rete effettive della rete VPN.

In Android 9 e versioni successive, le app che verificano già NET_CAPABILITY_NOT_METERED ricevono le funzionalità di rete della VPN e delle reti sottostanti.

I file nella cartella xt_qtaguid non sono più disponibili per le app

A partire da Android 9, le app non possono avere accesso diretto in lettura ai file che si trovano nella cartella /proc/net/xt_qtaguid. Il motivo è garantire l'uniformità con alcuni dispositivi che non hanno questi file.

Le API pubbliche che si basano su questi file, TrafficStats e NetworkStatsManager, continuano a funzionare come previsto. Tuttavia, le funzioni cutils non supportate, ad esempio qtaguid_tagSocket(), potrebbero non funzionare come previsto o non funzionare affatto su dispositivi diversi.

Il requisito FLAG_ACTIVITY_NEW_TASK è ora applicato

Con Android 9, non puoi avviare un'attività da un contesto non attivo, a meno che non passi il flag di intent FLAG_ACTIVITY_NEW_TASK. Se tenti di avviare un'attività senza passare questo flag, l'attività non viene avviata e il sistema invia un messaggio al log.

Modifiche alla rotazione dello schermo

A partire da Android 9, sono state apportate modifiche significative alla modalità di rotazione verticale. In Android 8.0 (livello API 26), gli utenti potevano passare dalla modalità di rotazione automatica a quella verticale e viceversa utilizzando un riquadro Impostazioni rapide o le impostazioni di visualizzazione. La modalità verticale è stata rinominata blocco rotazione ed è attiva quando la rotazione automatica è disattivata. Non sono state apportate modifiche alla modalità di rotazione automatica.

Quando il dispositivo è in modalità di blocco a rotazione, gli utenti possono bloccare lo schermo a qualsiasi rotazione supportata dall'Attività visibile in alto. Un'attività non deve presupporre che venga sempre visualizzata in verticale. Se è possibile visualizzare l'attività principale in più rotazioni in modalità di rotazione automatica, le stesse opzioni dovrebbero essere disponibili in modalità di blocco della rotazione, con alcune eccezioni basate sull'impostazione screenOrientation dell'attività (vedi la tabella di seguito).

Le attività che richiedono un orientamento specifico (ad esempio screenOrientation=landscape) ignorano la preferenza di blocco utente e si comportano come in Android 8.0.

La preferenza dell'orientamento dello schermo può essere impostata a livello di attività nel file manifest Android o in modo programmatico con setRequestedOrientation().

La modalità di blocco della rotazione funziona impostando la preferenza di rotazione dell'utente che WindowManager utilizza quando gestisce la rotazione dell'attività. La preferenza di rotazione dell'utente potrebbe essere modificata nei seguenti casi. Tieni presente che esiste un bias per tornare alla rotazione naturale del dispositivo, che solitamente è verticale per i dispositivi con fattore di forma degli smartphone:

  • Quando l'utente accetta un suggerimento di rotazione, la preferenza di rotazione cambia in base al suggerimento.
  • Quando l'utente passa a un'app verticale forzata (inclusa la schermata di blocco o Avvio app), la preferenza di rotazione diventa verticale.

La seguente tabella riassume il comportamento di rotazione per gli orientamenti più comuni dello schermo:

Orientamento schermo Comportamento
non specificato, utente Con il blocco della rotazione automatica e della rotazione, l'attività può essere visualizzata in verticale oppure orizzontale (e viceversa). Saranno supportate sia i layout verticale sia quello orizzontale.
orizzontale Con la rotazione automatica e il blocco della rotazione, l'attività può essere visualizzata in orizzontale o in orizzontale invertita. Sono supportate solo i layout orizzontali.
Verticale Con il blocco della rotazione automatica e della rotazione, l'attività può essere visualizzata in verticale o in verticale al contrario. Sono supportate solo i layout verticali.
Utente completo Con il blocco della rotazione automatica e della rotazione, l'attività può essere visualizzata in verticale oppure orizzontale (e viceversa). Saranno supportate sia il layout verticale che quello orizzontale.

Gli utenti con il blocco rotazione avranno la possibilità di bloccare l'orientamento verticale, spesso a 180o.
sensore, fullSensor, sensoreRitratto, sensoreOrizzontale La preferenza della modalità di blocco della rotazione viene ignorata e viene trattata come se la rotazione automatica fosse attiva. Utilizza questa opzione solo in circostanze eccezionali e con un'attenta considerazione dell'UX.

Il ritiro del client HTTP Apache interessa le app con ClassLoader non standard

Con Android 6.0, abbiamo rimosso il supporto per il client HTTP Apache. Questa modifica non influisce sulla maggior parte delle app che non hanno come target Android 9 o versioni successive. Tuttavia, la modifica può interessare alcune app che utilizzano una struttura ClassLoader non standard, anche se non hanno come target Android 9 o versioni successive.

Un'app può essere interessata se utilizza un oggetto ClassLoader non standard che delega esplicitamente al sistema ClassLoader. Queste app devono invece delegare all'app ClassLoader quando cercano corsi in org.apache.http.*. Se vengono delegate al sistema ClassLoader, le app non riusciranno su Android 9 o versioni successive con un'NoClassDefFoundError, perché queste classi non sono più note al sistema ClassLoader. Per prevenire problemi simili in futuro, le app devono utilizzare le classi di carico generali tramite l'app ClassLoader anziché accedere direttamente al sistema ClassLoader.

Enumerazione delle videocamere

Le app installate su dispositivi Android 9 possono rilevare tutte le videocamere disponibili chiamando il numero getCameraIdList(). Un'app non deve presupporre che il dispositivo abbia una sola fotocamera posteriore o una sola fotocamera anteriore.

Ad esempio, se l'app dispone di un pulsante per passare dalla fotocamera anteriore a quella posteriore e viceversa, potrebbe esserci più di una fotocamera anteriore o posteriore tra cui scegliere. Dovresti camminare sull'elenco delle fotocamere, esaminarne le caratteristiche e decidere quali videocamere esporre all'utente.