Android 10 include modifiche al comportamento che potrebbero influire sulla tua app.
Le modifiche elencate in questa pagina si applicano alla tua app quando viene eseguita
su Android 10, indipendentemente dal targetSdkVersion
dell'app. Devi testare
la tua app e modificarla in base alle esigenze per supportare correttamente queste modifiche.
Se la targetSdkVersion della tua app è 29
o superiore, dovrai anche
supportare modifiche aggiuntive. Per maggiori dettagli, assicurati di leggere la sezione Modifiche del comportamento per le app
che hanno come target Android 10.
Nota : oltre alle modifiche elencate in questa pagina, Android 10 introduce un gran numero di modifiche e restrizioni basate sulla privacy, tra cui le seguenti:
- Accesso in background alla posizione del dispositivo
- Avvio dell'attività in background
- Informazioni sull'affinità dei contatti
- Selezione casuale dell'indirizzo MAC
- Metadati della videocamera
- Modello di autorizzazioni
Queste modifiche interessano tutte le app e migliorano la privacy degli utenti. Per scoprire di più su come supportare queste modifiche, consulta la pagina Modifiche alla privacy.
Limitazioni relative alle interfacce non SDK
Per garantire la stabilità e la compatibilità delle app, la piattaforma ha iniziato a limitare le interfacce non SDK che la tua app può utilizzare in Android 9 (livello API 28). Android 10 include elenchi aggiornati di interfacce non SDK con limitazioni in base alla collaborazione con gli sviluppatori Android e ai test interni più recenti. Il nostro obiettivo è assicurarci che siano disponibili alternative pubbliche prima di limitare le interfacce non SDK.
Se non hai intenzione di scegliere come target Android 10 (livello API 29), alcune di queste modifiche potrebbero non interessarti immediatamente. Tuttavia, anche se al momento puoi utilizzare alcune interfacce non SDK (a seconda del livello API target della tua app), l'utilizzo di qualsiasi metodo o campo non SDK comporta sempre un rischio elevato di interruzione dell'app.
Se non sai con certezza se la tua app utilizza interfacce non SDK, puoi testarla per scoprirlo. Se la tua app si basa su interfacce non SDK, devi iniziare a pianificare una migrazione ad alternative SDK. Tuttavia, ci rendiamo conto che alcune app hanno casi d'uso validi per l'utilizzo di interfacce non SDK. Se non riesci a trovare un'alternativa all'utilizzo di un'interfaccia non SDK per una funzionalità della tua app, devi richiedere una nuova API pubblica.
Per saperne di più, consulta Aggiornamenti alle limitazioni relative alle interfacce non SDK in Android 10 e Limitazioni relative alle interfacce non SDK.
Navigazione tramite gesti
A partire da Android 10, gli utenti possono attivare la navigazione tramite gesti su tutto il dispositivo. Se un utente attiva la navigazione tramite gesti, questa influisce su tutte le app sul dispositivo, indipendentemente dal fatto che l'app abbia come target il livello API 29. Ad esempio, se l'utente scorre dal bordo dello schermo, il sistema interpreta questo gesto come navigazione Indietro, a meno che un'app non esegua l'override specifico di questo gesto per alcune parti dello schermo.
Per rendere la tua app compatibile con la navigazione tramite gesti, devi estendere i contenuti dell'app da un bordo all'altro e gestire i gesti in conflitto in modo appropriato. Per informazioni, consulta la documentazione relativa alla navigazione tramite gesti.
NDK
Android 10 include le seguenti modifiche all'NDK.
Gli oggetti condivisi non possono contenere riposizionamenti di testo
Android 6.0 (livello API 23) non consente l'utilizzo di rilocazioni di testo in oggetti condivisi. Il codice deve essere caricato così com'è e non deve essere modificato. Questa modifica migliora i tempi di caricamento e la sicurezza delle app.
SELinux applica questa limitazione alle app che hanno come target Android 10 o versioni successive. Se queste app continuano a utilizzare oggetti condivisi che contengono rilocazioni di testo, sono a rischio elevato di malfunzionamento.
Modifiche alle librerie Bionic e ai percorsi del linker dinamico
A partire da Android 10, diversi percorsi sono link simbolici anziché file regolari. Le app che si basano sul fatto che i percorsi siano file regolari potrebbero non funzionare:
/system/lib/libc.so
->/apex/com.android.runtime/lib/bionic/libc.so
/system/lib/libm.so
->/apex/com.android.runtime/lib/bionic/libm.so
/system/lib/libdl.so
->/apex/com.android.runtime/lib/bionic/libdl.so
/system/bin/linker
->/apex/com.android.runtime/bin/linker
Queste modifiche si applicano anche alle varianti a 64 bit del file, con
lib/
sostituito da lib64/
.
Per garantire la compatibilità, i link simbolici vengono forniti nei percorsi precedenti. Ad esempio,
/system/lib/libc.so
è un link simbolico a
/apex/com.android.runtime/lib/bionic/libc.so
. Quindi
dlopen(“/system/lib/libc.so”)
continua a funzionare, ma le app troveranno
la differenza quando tentano di esaminare le librerie caricate leggendo
/proc/self/maps
o simili, il che non è usuale, ma abbiamo scoperto che
alcune app lo fanno nell'ambito della procedura anti-hacking. In questo caso, i percorsi /apex/…
devono essere aggiunti come percorsi validi per i file Bionic.
Librerie/binari di sistema mappati nella memoria di sola esecuzione
A partire da Android 10, i segmenti eseguibili di librerie e binari di sistema
vengono mappati nella memoria di sola esecuzione (non leggibile) come tecnica
di protezione dagli attacchi di riutilizzo del codice. Se la tua app esegue operazioni di lettura in segmenti di memoria contrassegnati come di sola esecuzione, a causa di bug, vulnerabilità o ispezione intenzionale della memoria, il sistema invia un segnale SIGSEGV
alla tua app.
Per capire se questo comportamento ha causato un arresto anomalo, esamina il file
tombstone correlato in /data/tombstones/
. Un arresto anomalo correlato a execute-only
contiene il seguente messaggio di interruzione:
Cause: execute-only (no-read) memory access error; likely due to data in .text.
Per aggirare questo problema ed eseguire operazioni come l'ispezione della memoria, è
possibile contrassegnare i segmenti di sola esecuzione come lettura+esecuzione chiamando
mprotect()
. Tuttavia, ti consigliamo vivamente di ripristinarla
in modalità di sola esecuzione in seguito, in quanto questa impostazione dell'autorizzazione di accesso offre una migliore
protezione per la tua app e i tuoi utenti.
Sicurezza
Android 10 include le seguenti modifiche alla sicurezza.
TLS 1.3 abilitato per impostazione predefinita
In Android 10 e versioni successive, TLS 1.3 è abilitato per impostazione predefinita per tutte le connessioni TLS. Ecco alcuni dettagli importanti sulla nostra implementazione di TLS 1.3:
- Le suite di crittografia TLS 1.3 non possono essere personalizzate. Le suite di crittografia TLS 1.3
supportate sono sempre abilitate quando TLS 1.3 è abilitato. Qualsiasi tentativo di disattivarli chiamando il numero
setEnabledCipherSuites()
viene ignorato. - Quando viene negoziato TLS 1.3,
gli oggetti
HandshakeCompletedListener
vengono chiamati prima che le sessioni vengano aggiunte alla cache delle sessioni. In TLS 1.2 e altre versioni precedenti, questi oggetti vengono chiamati after quando le sessioni vengono aggiunte alla cache delle sessioni. - In alcune situazioni in cui le istanze
SSLEngine
generano unSSLHandshakeException
su versioni precedenti di Android, queste istanze generano unSSLProtocolException
su Android 10 e versioni successive. - La modalità 0-RTT non è supportata.
Se vuoi, puoi ottenere un SSLContext
con TLS 1.3 disabilitato chiamando il numero
SSLContext.getInstance("TLSv1.2")
.
Puoi anche attivare o disattivare le versioni del protocollo in base alla connessione chiamando
setEnabledProtocols()
su un oggetto appropriato.
I certificati firmati con SHA-1 non sono attendibili in TLS
In Android 10, i certificati che utilizzano l'algoritmo hash SHA-1 non sono attendibili nelle connessioni TLS. Le CA radice non emettono certificati di questo tipo dal 2016 e non sono più considerate attendibili in Chrome o in altri browser principali.
Qualsiasi tentativo di connessione non va a buon fine se la connessione è a un sito che presenta un certificato che utilizza SHA-1.
Modifiche e miglioramenti al comportamento di KeyChain
Alcuni browser, come Google Chrome, consentono agli utenti di scegliere un certificato quando un
server TLS invia un messaggio di richiesta di certificato nell'ambito di un handshake TLS. A partire da
Android 10,
gli oggetti KeyChain
rispettano i parametri di specifica dell'emittente e della chiave quando chiamano KeyChain.choosePrivateKeyAlias()
per
mostrare agli utenti una richiesta di selezione del certificato. In particolare, questo prompt non
contiene scelte che non rispettano le specifiche del server.
Se non sono disponibili certificati selezionabili dall'utente, come nel caso in cui nessun certificato corrisponda alla specifica del server o un dispositivo non abbia certificati installati, il prompt di selezione del certificato non viene visualizzato.
Inoltre, su Android 10 o versioni successive non è necessario avere un blocco schermo del dispositivo per importare chiavi o certificati CA in un oggetto KeyChain
.
Altre modifiche a TLS e alla crittografia
Sono state apportate diverse modifiche minori alle librerie TLS e di crittografia che diventano effettive su Android 10:
- Le cifrature AES/GCM/NoPadding e ChaCha20/Poly1305/NoPadding restituiscono dimensioni del buffer più
accurate da
getOutputSize()
. - Il pacchetto di crittografia
TLS_FALLBACK_SCSV
viene omesso dai tentativi di connessione con un protocollo massimo TLS 1.2 o versioni successive. A causa dei miglioramenti nelle implementazioni del server TLS, sconsigliamo di tentare il fallback esterno TLS. Ti consigliamo invece di fare affidamento sulla negoziazione della versione TLS. - ChaCha20-Poly1305 è un alias di ChaCha20/Poly1305/NoPadding.
- I nomi host con punti finali non sono considerati nomi host SNI validi.
- L'estensione supported_signature_algorithms in
CertificateRequest
viene rispettata quando si sceglie una chiave di firma per le risposte del certificato. - Le chiavi di firma opache, come quelle di Android Keystore, possono essere utilizzate con le firme RSA-PSS in TLS.
Trasmissioni Wi-Fi Direct
Su Android 10, le seguenti trasmissioni relative a Wi-Fi Direct non sono permanenti:
Se la tua app si è basata sulla ricezione di queste trasmissioni durante la registrazione perché
erano permanenti, utilizza il metodo get()
appropriato durante l'inizializzazione per
ottenere le informazioni.
Funzionalità di Wi-Fi Aware
Android 10 aggiunge il supporto per semplificare la creazione di socket TCP/UDP utilizzando i percorsi dati Wi-Fi Aware. Per creare un socket TCP/UDP che si connette a un ServerSocket
, il dispositivo client deve conoscere l'indirizzo IPv6 e la porta del server. In precedenza
era necessario comunicare out-of-band, ad esempio utilizzando la messaggistica di livello 2 BT o Wi-Fi Aware, o rilevare in-band utilizzando altri protocolli, come mDNS. Con
Android 10, le informazioni possono essere comunicate durante la configurazione della rete.
Il server può eseguire una delle seguenti operazioni:
- Inizializza un
ServerSocket
e imposta o ottieni la porta da utilizzare. - Specifica le informazioni sulla porta nell'ambito della richiesta di rete Wi-Fi Aware.
Il seguente esempio di codice mostra come specificare le informazioni sulla porta come parte della richiesta di rete:
Kotlin
val ss = ServerSocket() val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle) .setPskPassphrase("some-password") .setPort(ss.localPort) .build() val myNetworkRequest = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE) .setNetworkSpecifier(ns) .build()
Java
ServerSocket ss = new ServerSocket(); WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier .Builder(discoverySession, peerHandle) .setPskPassphrase(“some-password”) .setPort(ss.getLocalPort()) .build(); NetworkRequest myNetworkRequest = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE) .setNetworkSpecifier(ns) .build();
Il client esegue quindi una richiesta di rete Wi-Fi Aware per ottenere l'IPv6 e la porta forniti dal server:
Kotlin
val callback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { ... } override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) { ... } override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { ... val ti = networkCapabilities.transportInfo if (ti is WifiAwareNetworkInfo) { val peerAddress = ti.peerIpv6Addr val peerPort = ti.port } } override fun onLost(network: Network) { ... } }; connMgr.requestNetwork(networkRequest, callback)
Java
callback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { ... } @Override public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) { ... } @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { ... TransportInfo ti = networkCapabilities.getTransportInfo(); if (ti instanceof WifiAwareNetworkInfo) { WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti; Inet6Address peerAddress = info.getPeerIpv6Addr(); int peerPort = info.getPort(); } } @Override public void onLost(Network network) { ... } }; connMgr.requestNetwork(networkRequest, callback);
SYSTEM_ALERT_WINDOW sui dispositivi Go
Le app in esecuzione su dispositivi Android 10 (Go Edition) non possono ricevere l'autorizzazione
SYSTEM_ALERT_WINDOW
. Questo perché il disegno delle finestre di overlay utilizza una quantità eccessiva di memoria,
il che è particolarmente dannoso per le prestazioni dei dispositivi Android
con poca memoria.
Se un'app in esecuzione su un dispositivo Go Edition con Android 9 o versioni precedenti riceve l'autorizzazione
SYSTEM_ALERT_WINDOW
, l'app la mantiene anche se il
dispositivo viene aggiornato ad Android 10. Tuttavia, le app che non dispongono già di questa
autorizzazione non possono ottenerla dopo l'upgrade del dispositivo.
Se un'app su un dispositivo Go invia un intent con l'azione
ACTION_MANAGE_OVERLAY_PERMISSION
,
il sistema nega automaticamente la richiesta e indirizza l'utente a una
schermata Impostazioni che indica che l'autorizzazione non è consentita perché
rallenta il dispositivo. Se un'app su un dispositivo Go chiama
Settings.canDrawOverlays()
,
il metodo restituisce sempre false. Anche in questo caso, queste limitazioni non si applicano alle app
che hanno ricevuto l'autorizzazione SYSTEM_ALERT_WINDOW
prima dell'aggiornamento
del dispositivo ad Android 10.
Avvisi per le app che hanno come target versioni precedenti di Android
I dispositivi con Android 10 o versioni successive avvisano gli utenti la prima volta che eseguono un'app che ha come target Android 5.1 (livello API 22) o versioni precedenti. Se l'app richiede all'utente di concedere le autorizzazioni, l'utente ha anche la possibilità di modificare le autorizzazioni dell'app prima che questa possa essere eseguita per la prima volta.
A causa dei requisiti relativi all'API target di Google Play, un utente visualizza questi avvisi solo quando esegue un'app che non è stata aggiornata di recente. Per le app distribuite tramite altri store, durante il 2019 entreranno in vigore requisiti simili per il livello API target. Per saperne di più su questi requisiti, consulta la pagina Ampliamento dei requisiti relativi al livello API target nel 2019.
Suite di crittografia SHA-2 CBC rimosse
Le seguenti suite di cifratura SHA-2 CBC sono state rimosse dalla piattaforma:
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Queste suite di crittografia sono meno sicure delle suite di crittografia simili che utilizzano GCM e la maggior parte dei server supporta le varianti GCM e CBC di queste suite di crittografia o non ne supporta nessuna.
Utilizzo di app
Android 10 introduce le seguenti modifiche al comportamento relative all'utilizzo delle app:
Miglioramenti dell'utilizzo dell'app UsageStats - <0x0 Inoltre, Android 10 monitora correttamente l'utilizzo delle app istantanee.
Scala di grigi per app - <
Stato di distrazione per app - <0x0A
Sospensione e riproduzione - <0x0A
Modifiche alla connessione HTTPS
Se un'app che esegue Android 10 passa null
in
setSSLSocketFactory()
,
si verifica un IllegalArgumentException
. Nelle versioni precedenti, il passaggio di null
a setSSLSocketFactory()
aveva lo stesso effetto del passaggio dell'attuale impostazione predefinita
di fabbrica.
La libreria android.preference è obsoleta
La libreria android.preference
è deprecata a partire da Android 10.
Gli sviluppatori devono invece utilizzare la libreria delle preferenze AndroidX, che fa parte di Android
Jetpack. Per ulteriori risorse che ti aiutino nella migrazione e nello sviluppo, consulta la Guida alle impostazioni aggiornata, la nostra app di esempio pubblica e la documentazione di riferimento.
Modifiche alla libreria di utilità per i file ZIP
Android 10 introduce le seguenti modifiche alle classi nel pacchetto java.util.zip
, che gestisce i file ZIP. Queste modifiche rendono il comportamento della libreria più
coerente tra Android e altre piattaforme che utilizzano java.util.zip
.
Gonfiatore
Nelle versioni precedenti, alcuni metodi della classe Inflater
generavano un'eccezione
IllegalStateException
se
venivano richiamati dopo una chiamata a end()
.
In Android 10, questi metodi generano un'eccezione
NullPointerException
.
ZipFile
In Android 10 e versioni successive, il costruttore per
ZipFile
che accetta argomenti di tipo File
, int
e Charset
non genera un'eccezione
ZipException
se il file ZIP fornito
non contiene file.
ZipOutputStream
In Android 10 e versioni successive, il metodo
finish()
in
ZipOutputStream
non genera un'eccezione
ZipException
se tenta di scrivere un
flusso di output per un file ZIP che non contiene file.
Modifiche alla videocamera
Molte app che utilizzano la videocamera presuppongono che se il dispositivo è in configurazione verticale, anche il dispositivo fisico sia in orientamento verticale, come descritto in Orientamento della videocamera. In passato questa era un'ipotesi sicura, ma la situazione è cambiata con l'espansione dei fattori di forma disponibili, come i pieghevoli. Questa ipotesi su questi dispositivi può portare a una visualizzazione ruotata o scalata (o entrambe) in modo errato del mirino della videocamera.
Le applicazioni che hanno come target il livello API 24 o versioni successive devono impostare esplicitamente
android:resizeableActivity
e fornire la funzionalità necessaria per gestire
l'operazione multi-finestra.
Monitoraggio dell'utilizzo della batteria
A partire da Android 10,
SystemHealthManager
ripristina
le statistiche sull'utilizzo della batteria ogni volta che il dispositivo viene scollegato dopo un evento di ricarica
importante. In generale, un evento di ricarica importante si verifica quando: il dispositivo
è stato caricato completamente oppure è passato da quasi scarico a quasi
carico.
Prima di Android 10, le statistiche sull'utilizzo della batteria venivano ripristinate ogni volta che il dispositivo veniva scollegato, indipendentemente da quanto poco fosse cambiato il livello della batteria.
Ritiro di Android Beam
In Android 10 stiamo ritirando ufficialmente Android Beam, una funzionalità precedente per avviare la condivisione di dati tra dispositivi tramite NFC (Near Field Communication). Stiamo ritirando anche diverse API NFC correlate. Android Beam rimane disponibile facoltativamente per i partner produttori di dispositivi che vogliono utilizzarlo, ma non è più in fase di sviluppo attivo. Android continuerà a supportare altre funzionalità e API NFC, tuttavia, e casi d'uso come la lettura da tag e i pagamenti continueranno a funzionare come previsto.
Modifica del comportamento di java.math.BigDecimal.stripTrailingZeros()
BigDecimal.stripTrailingZeros()
non conserva più gli zeri finali come caso speciale se il valore di input è zero.
Modifiche al comportamento di java.util.regex.Matcher e Pattern
Il risultato di split()
è stato modificato in modo che non inizi più con un String
vuoto
("") quando c'è una corrispondenza di larghezza zero all'inizio dell'input. Ciò influisce anche su String.split()
. Ad esempio, "x".split("")
ora restituisce {"x"}
mentre in precedenza restituiva {"", "x"}
nelle versioni precedenti di Android.
"aardvark".split("(?=a)"
ora restituisce {"a", "ardv", "ark"}
anziché
{"", "a", "ardv", "ark"}
.
È stato migliorato anche il comportamento delle eccezioni per gli argomenti non validi:
appendReplacement(StringBuffer, String)
ora genera un'IllegalArgumentException
anziché unIndexOutOfBoundsException
se la sostituzioneString
termina con una barra rovesciata solitaria, il che è illegale. Ora viene generata la stessa eccezione se la sostituzioneString
termina con un$
. In precedenza, in questo scenario non veniva generata alcuna eccezione.replaceFirst(null)
non chiama piùreset()
suMatcher
se genera unNullPointerException
.NullPointerException
viene ora generato anche quando non viene trovata alcuna corrispondenza. In precedenza, veniva generato solo in caso di corrispondenza.start(int group)
,end(int group)
egroup(int group)
ora generano un erroreIndexOutOfBoundsException
più generale se l'indice del gruppo non rientra nei limiti. In precedenza, questi metodi generavanoArrayIndexOutOfBoundsException
.
L'angolo predefinito per GradientDrawable ora è TOP_BOTTOM
In Android 10, se definisci un
GradientDrawable
in XML e non fornisci una misurazione dell'angolo, l'orientamento del gradiente
viene impostato
su TOP_BOTTOM
.
Si tratta di una modifica rispetto alle versioni precedenti di Android, in cui l'impostazione predefinita era
LEFT_RIGHT
.
Come soluzione alternativa, se esegui l'aggiornamento all'ultima versione di AAPT2, lo strumento imposta una misurazione dell'angolo pari a 0 per le app legacy se non viene specificata alcuna misurazione dell'angolo.
Logging per oggetti serializzati utilizzando SUID predefinito
A partire da Android 7.0 (livello API 24), la piattaforma ha apportato una correzione
al serialVersionUID
predefinito per gli oggetti
serializzabili. Questa correzione
non ha interessato le app che avevano come target il livello API 23 o inferiore.
A partire da Android 10, se un'app ha come target il livello API 23 o precedente
e si basa sul vecchio serialVersionUID
predefinito errato, il sistema registra
un avviso e suggerisce una correzione del codice.
In particolare, il sistema registra un avviso se tutte le seguenti condizioni sono vere:
- L'app ha come target il livello API 23 o versioni precedenti.
- Un corso viene serializzato.
- La classe serializzata utilizza il valore predefinito
serialVersionUID
, anziché impostare esplicitamente unserialVersionUID
. - Il
serialVersionUID
predefinito è diverso dalserialVersionUID
che si otterrebbe se l'app avesse come target il livello API 24 o versioni successive.
Questo avviso viene registrato una volta per ogni classe interessata.
Il messaggio di avviso include una correzione suggerita, ovvero impostare esplicitamente
serialVersionUID
sul valore predefinito che verrebbe calcolato se
l'app avesse come target il livello API 24 o superiore. Utilizzando questa correzione, puoi assicurarti che
se un oggetto di questa classe viene serializzato su un'app che ha come target il livello API
23 o precedente, l'oggetto venga letto correttamente dalle app che hanno come target il livello 24 o successivo
e viceversa.
Modifiche a java.io.FileChannel.map()
A partire da Android 10, FileChannel.map()
non è supportato per
file non standard, come /dev/zero
, le cui dimensioni non possono essere modificate utilizzando
truncate()
. Le versioni precedenti di Android hanno eliminato l'errno restituito da
truncate()
, ma Android 10 genera un'eccezione IOException. Se hai bisogno del comportamento precedente,
devi utilizzare il codice nativo.