Modifiche del comportamento: tutte le app

Android 10 include modifiche del 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 da targetSdkVersion. Ti consigliamo di testare l'app e modificarla secondo necessità per supportare correttamente queste modifiche.

Se il valore targetSdkVersion dell'app è 29 o superiore, devi supportare anche ulteriori modifiche. Assicurati di leggere modifiche del comportamento per le app che hanno come target 29 per maggiori dettagli.

Nota : oltre alle modifiche elencate in questa pagina, Android 10 introduce un gran numero di modifiche e limitazioni basate sulla privacy, tra cui:

  • Accesso in background alla posizione del dispositivo
  • L'attività in background viene avviata
  • Informazioni sull'affinità dei contatti
  • Randomizzazione degli indirizzi 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 relative alla privacy.

Limitazioni dell'interfaccia non SDK

Per garantire la stabilità e la compatibilità dell'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 limitate in base alla collaborazione con gli sviluppatori Android e agli ultimi test interni. Il nostro obiettivo è assicurarci che siano disponibili alternative pubbliche prima di limitare le interfacce non SDK.

Se non sceglierai 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 metodi o campi non SDK comporta sempre un rischio elevato di danneggiare la tua app.

Se non hai la certezza che la tua app utilizzi interfacce non SDK, puoi testare l'app per scoprirlo. Se la tua app si basa su interfacce non SDK, devi iniziare a pianificare una migrazione alle alternative all'SDK. Ciononostante, siamo consapevoli 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à nella tua app, devi richiedere una nuova API pubblica.

Per scoprire di più, consulta Aggiornamenti alle limitazioni delle interfacce non SDK in Android 10 e Limitazioni sulle 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 operazione 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 verso l'interno dal bordo dello schermo, il sistema interpreta quel gesto come una navigazione Indietro, a meno che un'app sostituisca in modo specifico quel gesto per parti dello schermo.

Per rendere la tua app compatibile con la navigazione tramite gesti, dovrai estendere i contenuti dell'app da un bordo all'altro e gestire i gesti in conflitto in modo appropriato. Per ulteriori informazioni, consulta la documentazione relativa alla navigazione tramite gesti.

NDK

Android 10 include le seguenti modifiche NDK.

Gli oggetti condivisi non possono contenere riposizionazioni del testo

Android 6.0 (livello API 23) non è consentito l'uso non consentito delle riassegnazioni del testo negli 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 destinate ad Android 10 o versioni successive. Se queste app continuano a utilizzare oggetti condivisi che contengono trasferimenti del testo, sono ad alto rischio di interruzione.

Modifiche alle librerie Bionic e ai percorsi di linker dinamici

A partire da Android 10, diversi percorsi sono link simbolici anziché file normali. Le app che si basano su percorsi come 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 vengono applicate anche alle varianti a 64 bit del file, dove lib/ viene sostituito con lib64/.

Per motivi di compatibilità, i link simbolici sono forniti nei percorsi precedenti. Ad esempio, /system/lib/libc.so è un collegamento simbolico a /apex/com.android.runtime/lib/bionic/libc.so. Pertanto, dlopen(“/system/lib/libc.so”) continua a funzionare, ma le app troveranno la differenza quando provano effettivamente a esaminare le librerie caricate leggendo /proc/self/maps o simili, cosa non normale, ma abbiamo scoperto che alcune app lo fanno nell'ambito del loro processo anti-hack. In tal caso, i percorsi /apex/… dovrebbero essere aggiunti come percorsi validi per i file Bionic.

File binari di sistema/librerie mappati alla memoria di sola esecuzione

A partire da Android 10, i segmenti eseguibili dei file binari di sistema e delle librerie sono mappati alla sola memoria di esecuzione (non leggibili) come tecnica di protezione contro gli 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.

Puoi identificare se questo comportamento ha causato un arresto anomalo esaminando il file di tombstone correlato in /data/tombstones/. Un arresto anomalo correlato solo all'esecuzione 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, puoi contrassegnare i segmenti solo di esecuzione come letti ed eseguire richiamando mprotect(). Tuttavia, ti consigliamo vivamente di tornare alla modalità solo in seguito, poiché questa impostazione di autorizzazione di accesso offre una maggiore 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 disabilitarle chiamando setEnabledCipherSuites() viene ignorato.
  • Quando viene negoziato TLS 1.3, gli oggetti HandshakeCompletedListener vengono chiamati prima che le sessioni vengano aggiunte alla cache della sessione. In TLS 1.2 e in altre versioni precedenti, questi oggetti vengono chiamati dopo che le sessioni sono state aggiunte alla cache delle sessioni.
  • In alcune situazioni in cui le istanze SSLEngine generano un elemento SSLHandshakeException sulle versioni precedenti di Android, vengono generate SSLProtocolException invece su Android 10 e versioni successive.
  • La modalità 0-RTT non è supportata.

Se vuoi, puoi ottenere un SSLContext con TLS 1.3 disattivato chiamando SSLContext.getInstance("TLSv1.2"). Puoi anche abilitare o disabilitare 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 di hash SHA-1 non sono attendibili nelle connessioni TLS. Le CA radice non rilasciano questo certificato dal 2016 e non sono più attendibili in Chrome o altri browser principali.

Qualsiasi tentativo di connessione non riesce se la connessione avviene a un sito che presenta un certificato utilizzando SHA-1.

Modifiche e miglioramenti del 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 gli emittenti e i parametri di specifica della chiave quando chiamano KeyChain.choosePrivateKeyAlias() per mostrare agli utenti una richiesta di selezione dei certificati. 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 se su un dispositivo non sono installati certificati, la richiesta di selezione dei certificati non viene visualizzata.

Inoltre, su Android 10 o versioni successive non è necessario un blocco schermo del dispositivo per importare chiavi o certificati CA in un oggetto KeyChain.

Altre modifiche a TLS e crittografia

Sono state apportate diverse modifiche di minore entità alle librerie TLS e di crittografia che entreranno in vigore su Android 10:

  • Le crittografie AES/GCM/NoPadding e ChaCha20/Poly1305/NoPadding restituiscono dimensioni del buffer più accurate a partire da getOutputSize().
  • La suite di crittografia TLS_FALLBACK_SCSV viene omessa dai tentativi di connessione con un protocollo massimo di TLS 1.2 o versioni successive. A causa dei miglioramenti nelle implementazioni dei server TLS, sconsigliamo di provare TLS di riserva esterno. Ti consigliamo invece di affidarti alla 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 supportata_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 dell'archivio chiavi di Android, 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 fisse:

Se la tua app ha fatto affidamento sulla ricezione di questi broadcast al momento della registrazione perché erano persistenti, usa il metodo get() appropriato al momento dell'inizializzazione per ottenere le informazioni.

Funzionalità Wi-Fi Aware

Android 10 aggiunge il supporto per semplificare la creazione di socket TCP/UDP mediante percorsi dati consapevoli del Wi-Fi. 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, doveva essere comunicato fuori banda, ad esempio mediante la messaggistica BT o Wi-Fi Aware di livello 2, oppure rilevato in banda 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 recupera la porta da utilizzare.
  • Specifica le informazioni sulla porta come parte 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 fornita 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_WINDOWS su dispositivi Go

Le app eseguite su dispositivi Android 10 (Go Edition) non possono ricevere l'autorizzazione SYSTEM_ALERT_WINDOW. Questo perché le finestre di disegno in overlay utilizzano una memoria eccessiva, che è particolarmente dannosa per le prestazioni dei dispositivi Android con memoria insufficiente.

Se un'app in esecuzione su un dispositivo Go con Android 9 o versioni precedenti riceve l'autorizzazione SYSTEM_ALERT_WINDOW, l'app mantiene l'autorizzazione anche se viene eseguito l'upgrade del dispositivo ad Android 10. Tuttavia, le app che non dispongono già di questa autorizzazione non possono essere concesse 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 alla schermata Impostazioni in cui viene indicato che l'autorizzazione non è consentita perché inattiva il dispositivo. Se un'app su un dispositivo Go chiama Settings.canDrawOverlays(), il metodo restituisce sempre false. Ancora una volta, queste limitazioni non si applicano alle app che hanno ricevuto l'autorizzazione SYSTEM_ALERT_WINDOW prima dell'upgrade del dispositivo ad Android 10.

Avvisi per le app che hanno come target le 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 autorizzazioni, all'utente viene anche data la possibilità di modificare le autorizzazioni dell'app prima che l'app possa essere eseguita per la prima volta.

A causa dei requisiti dell'API target di Google Play, un utente vede questi avvisi solo quando esegue un'app che non è stata aggiornata di recente. Per le app distribuite tramite altri datastore, requisiti dell'API target simili entreranno in vigore nel 2019. Per ulteriori informazioni su questi requisiti, consulta la pagina relativa ai requisiti relativi ai livelli API target dell'espansione nel 2019.

Suite di crittografia CBC SHA-2 rimosse

Le seguenti suite di crittografia CBC SHA-2 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 entrambe le varianti GCM e CBC di queste suite di crittografia o nessuna di queste supporta.

Utilizzo di app

Android 10 introduce le seguenti modifiche del comportamento relative all'utilizzo delle app:

  • Miglioramenti all'utilizzo delle app UsageStats - le app utilizzate per la modalità Inoltre, Android 10 monitora correttamente l'utilizzo delle app istantanee.

  • Scala di grigi per app - su base di grigi per app.

  • lo stato di distrazione per app:

  • In Sospensione e riproduzione - le app Android possono essere sospese

Modifiche alla connessione HTTPS

Se un'app con Android 10 passa null in setSSLSocketFactory(), si verifica una IllegalArgumentException. Nelle versioni precedenti, il passaggio di null in setSSLSocketFactory() aveva lo stesso effetto del passaggio alla fabbrica predefinita corrente.

La libreria android.preference è deprecata

La libreria android.preference è deprecata a partire da Android 10. Gli sviluppatori dovrebbero usare invece la libreria delle preferenze AndroidX, che fa parte di Android Jetpack. Per ulteriori risorse di supporto nella migrazione e nello sviluppo, consulta la Guida alle impostazioni aggiornata insieme alla nostra app pubblica di esempio e alla nostra documentazione di riferimento.

Modifiche alla libreria di utility 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 raccolta più coerente tra Android e altre piattaforme che usano java.util.zip.

Interessato

Nelle versioni precedenti, alcuni metodi nella classe Inflater generavano un IllegalStateException se venivano richiamati dopo una chiamata a end(). In Android 10, questi metodi restituiscono invece NullPointerException.

File ZIP

In Android 10 e versioni successive, il costruttore di ZipFile che accetta argomenti di tipo File, int e Charset non genera un ZipException se il file ZIP fornito non contiene file.

ZipOutputStream

In Android 10 e versioni successive, il metodo finish() in ZipOutputStream non genera ZipException se tenta di scrivere uno stream di output per un file ZIP che non contiene alcun file.

Modifiche fotocamera

Molte app che usano la fotocamera presuppongono che, se il dispositivo è in configurazione verticale, anche il dispositivo fisico è in orientamento verticale, come descritto in Orientamento della fotocamera. In passato questa era un'ipotesi sicura, ma ora è cambiata con l'espansione dei fattori di forma disponibili, come i pieghevoli. Su questi dispositivi, il mirino della fotocamera potrebbe essere ruotato o ridimensionato (o entrambi) in modo errato.

Le applicazioni che hanno come target il livello API 24 o versioni successive devono impostare esplicitamente android:resizeableActivity e fornire le funzionalità necessarie per gestire le operazioni multi-finestra.

Monitoraggio dell'utilizzo della batteria

A partire da Android 10, SystemHealthManager reimposta 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 può essere: il dispositivo è completamente carico oppure il dispositivo è passato da quasi esaurito a quasi completamente carico.

Prima di Android 10, le statistiche sull'utilizzo della batteria si resettavano ogni volta che il dispositivo veniva scollegato, indipendentemente dalle piccole modifiche apportate al livello della batteria.

Ritiro di Android Beam

In Android 10 ritireremo ufficialmente Android Beam, una funzionalità meno recente che consente di avviare la condivisione di dati tra dispositivi tramite NFC (Near Field Communication). Stiamo anche ritirando diverse API NFC correlate. Android Beam rimane disponibile facoltativamente per i partner dei produttori che desiderano utilizzarlo, ma non è più nello sviluppo attivo. Android continuerà a supportare altre funzionalità e API NFC e casi d'uso come la lettura dai 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 dei pattern

Il risultato di split() è stato modificato in modo da non iniziare più con un valore String vuoto ("") quando esiste una corrispondenza di larghezza zero all'inizio dell'input. Riguarda anche String.split(). Ad esempio, "x".split("") ora restituisce {"x"} mentre prima restituisce {"", "x"} su 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 IllegalArgumentException invece di IndexOutOfBoundsException se la sostituzione String termina con una barra rovesciata solitaria, che non è consentita. La stessa eccezione viene ora generata se il valore String sostitutivo termina con un valore $. In precedenza, non sono state fatte eccezioni in questo scenario.
  • replaceFirst(null) non chiama più reset() sul Matcher se genera un NullPointerException. Ora viene generata NullPointerException anche in assenza di corrispondenze. In precedenza, veniva lanciato solo quando c'era una partita.
  • start(int group), end(int group) e group(int group) ora restituiscono un valore IndexOutOfBoundsException più generale se l'indice del gruppo è fuori dai limiti. In precedenza, questi metodi lanciavano ArrayIndexOutOfBoundsException.

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 per impostazione predefinita sarà TOP_BOTTOM. Si tratta di una modifica rispetto alle versioni precedenti di Android, dove l'impostazione predefinita era LEFT_RIGHT.

Come soluzione alternativa, se esegui l'aggiornamento alla versione più recente dell'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 valore serialVersionUID predefinito per gli oggetti serializzabili. Questa correzione non ha interessato le app che avevano come target il livello API 23 o un livello precedente.

A partire da Android 10, se un'app ha come target il livello API 23 o un livello precedente e si basa sul valore serialVersionUID predefinito precedente e non corretto, il sistema registra un avviso e suggerisce una correzione del codice.

In particolare, il sistema registra un avviso se si verificano tutte le seguenti condizioni:

  • L'app ha come target il livello API 23 o un livello precedente.
  • Un corso è serializzato.
  • La classe serializzata utilizza il valore predefinito serialVersionUID, invece di impostare esplicitamente un serialVersionUID.
  • Il valore predefinito serialVersionUID è diverso da serialVersionUID se l'app ha come target il livello API 24 o un livello superiore.

Questo avviso viene registrato una volta per ogni corso interessato. Il messaggio di avviso include una correzione suggerita, ovvero impostare esplicitamente serialVersionUID sul valore predefinito che verrà calcolato se l'app ha scelto come target il livello API 24 o un livello superiore. Utilizzando questa correzione, puoi assicurarti che se un oggetto di quella classe è serializzato su un'app che ha come target il livello API 23 o precedente, l'oggetto verrà letto correttamente dalle app che hanno come target 24 o versioni successive e viceversa.

Modifiche a java.io.FileChannel.map()

A partire da Android 10, l'elemento FileChannel.map() non è supportato per i file non standard, come /dev/zero, le cui dimensioni non possono essere modificate utilizzando truncate(). Nelle versioni precedenti di Android era presente l'errore restituito da truncate(), ma Android 10 genera un'eccezione IOException. Se hai bisogno del comportamento precedente, devi usare codice nativo.