Cambiamenti del comportamento: tutte le app

Android 10 include modifiche del comportamento che potrebbero interessare la tua app. Le modifiche elencate in questa pagina si applicano alla tua app quando è in esecuzione su Android 10, indipendentemente dal targetSdkVersion dell'app. Dovresti testare l'app e modificarle in base alle necessità per supportare correttamente queste modifiche.

Se il valore targetSdkVersion dell'app è 29 o superiore, dovrai anche supportare ulteriori modifiche. Assicurati di leggere le modifiche del comportamento delle app targeting 29 per informazioni.

Nota : oltre alle modifiche elencate in questa pagina, Android 10 introduce un numero elevato di modifiche e restrizioni basate sulla privacy, tra cui: le seguenti:

  • Accesso in background alla posizione del dispositivo
  • Avvio delle attività in background
  • 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 dell'utente. Per scoprire di più su come supportare queste modifiche, consulta la pagina Modifiche alla privacy.

Limitazioni relative all'interfaccia non SDK

Per contribuire a garantire stabilità e compatibilità delle app, la piattaforma ha iniziato a applicare limitazioni quali 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 sviluppatori Android e test interni più recenti. Il nostro obiettivo è far sì che sono disponibili alternative prima di limitare le interfacce non SDK.

Se non scegli come target Android 10 (livello API 29), alcune di queste modifiche potrebbero non riguardarti immediatamente. Tuttavia, sebbene al momento tu possa utilizzare interfacce non SDK (a seconda del livello API target dell'app), l'utilizzo di qualsiasi metodo o campo non SDK comporta sempre un rischio elevato di danneggiare dell'app.

Se non hai la certezza che la tua app utilizzi interfacce non SDK, puoi testare la tua app per scoprirlo. Se la tua app si basa su interfacce non SDK, dovresti iniziare a pianificare una migrazione alle alternative dell'SDK. Tuttavia, siamo consapevoli che alcune app hanno casi d'uso validi per l'utilizzo di interfacce non SDK. Se non riesci a trovare un'alternativa a utilizzare 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 dispositivo. Se un utente attiva la navigazione tramite gesti, l'operazione interessa tutte le app nella 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 quel gesto come un Indietro durante la navigazione, a meno che un'app non sovrascriva in modo specifico quel gesto per parti di sullo schermo.

Per rendere l'app compatibile con la navigazione tramite gesti, devi estendere l'impostazione i contenuti dell'app da un bordo all'altro e gestisci i gesti in conflitto in modo appropriato. Per informazioni, consulta la sezione Navigazione tramite gesti documentazione.

ND

Android 10 include le seguenti modifiche relative all'NDK.

Gli oggetti condivisi non possono contenere riposizionazioni di testo

Android 6.0 (livello API 23) non consente l'utilizzo delle rilocazioni di testo negli oggetti condivisi. Il codice deve essere caricato così com'è e non deve possono essere modificate. Questa modifica migliora i tempi di caricamento delle app e la sicurezza.

SELinux applica questa limitazione alle app destinate ad Android 10 o superiore. Se queste app continuano a usare oggetti condivisi contenenti testo dei trasferimenti, sono ad alto rischio di guasti.

Modifiche alle librerie Bionic e ai percorsi dei linker dinamici

A partire da Android 10, diversi percorsi sono link simbolici anziché file regolari. App che utilizzavano i percorsi come file normali 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 con lib64/.

Per garantire la compatibilità, i collegamenti simbolici sono forniti nei percorsi precedenti. Ad esempio: /system/lib/libc.so è un collegamento simbolico a /apex/com.android.runtime/lib/bionic/libc.so. Quindi... dlopen(“/system/lib/libc.so”) continua a funzionare, ma le app trovano la differenza quando provano effettivamente a esaminare le librerie caricate /proc/self/maps o simili, che non è una cosa normale, ma abbiamo riscontrato che alcune app lo fanno nell'ambito della procedura anti-compromissione. In tal caso, È necessario aggiungere /apex/… percorsi come percorsi validi per i file Bionic.

Librerie/binari di sistema mappati alla memoria di sola esecuzione

A partire da Android 10, vengono eseguiti segmenti eseguibili di file binari di sistema. e le librerie sono mappate in memoria di sola esecuzione (non leggibile) come contro gli attacchi da riutilizzo del codice. Se la tua app esegue operazioni di lettura segmenti di memoria contrassegnati come di sola esecuzione, che si tratti di bug, vulnerabilità o un'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 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, è possibile contrassegnare i segmenti di sola esecuzione come lettura+esecuzione richiamando mprotect(). Tuttavia, ti consigliamo vivamente di tornare a eseguire solo successivamente, in quanto questa impostazione di autorizzazione di accesso per la tua app e i tuoi utenti.

Sicurezza

Android 10 include le seguenti modifiche relative alla sicurezza.

TLS 1.3 abilitato per impostazione predefinita

In Android 10 e versioni successive, TLS 1.3 è attivo per impostazione predefinita per tutti Connessioni TLS. Ecco alcuni dettagli importanti sul nostro TLS 1.3 implementazione:

  • Le suite di crittografia TLS 1.3 non possono essere personalizzate. La crittografia TLS 1.3 supportata sono sempre attivate quando TLS 1.3 è abilitato. Qualsiasi tentativo di disattivazione chiamandoli setEnabledCipherSuites() viene ignorato.
  • Quando viene negoziato TLS 1.3, HandshakeCompletedListener vengono richiamati prima che le sessioni vengano aggiunte alla cache delle sessioni. (in TLS 1.2 e altre versioni precedenti, questi oggetti vengono chiamati dopo l'aggiunta di sessioni nella cache della sessione).
  • In alcuni casi in cui le istanze SSLEngine generano un messaggio SSLHandshakeException su versioni precedenti di Android, su Android 10 e versioni successive generano un messaggio SSLProtocolException.
  • La modalità 0-RTT non è supportata.

Se vuoi, puoi ottenere un SSLContext con TLS 1.3 disabilitato chiamando 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 considerate attendibili nelle connessioni TLS. Le CA radice non hanno emesso questo certificato dal 2016 e non sono più attendibili in Chrome o nei principali browser.

Qualsiasi tentativo di connessione non va a buon fine se la connessione è con 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 Il server TLS invia un messaggio di richiesta di certificato come parte di un handshake TLS. Dati aggiornati Android 10 Gli oggetti KeyChain rispettano gli emittenti e dei parametri chiave delle specifiche quando si chiama KeyChain.choosePrivateKeyAlias() a mostra 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 corrispondano alle specifiche del server o il dispositivo non dispone di certificati installati, la richiesta di selezione dei certificati non viene visualizzata.

Inoltre, su Android 10 o versioni successive non è necessario avere una 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 entrano in vigore su Android 10:

  • Le crittografie AES/GCM/NoPadding e ChaCha20/Poly1305/NoPadding restituiscono più dimensioni del buffer precise da getOutputSize().
  • La suite di crittografia TLS_FALLBACK_SCSV è stata omessa dai tentativi di connessione con un protocollo massimo di TLS 1.2 o superiore. Grazie ai miglioramenti nel server TLS sconsigliamo di tentare di utilizzare il fallback TLS esterno. Invece, consigliamo 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.
  • È possibile utilizzare chiavi di firma opache, come quelle dell'archivio chiavi Android, con Firme RSA-PSS in TLS.

Trasmissioni Wi-Fi Direct

Su Android 10, i seguenti annunci correlati al Wi-Fi Le campagne dirette non sono fisse:

Se la tua app si è affidata alla ricezione di questi annunci al momento della registrazione perché erano fissi, usa il metodo get() appropriato durante l'inizializzazione ottenere le informazioni.

Funzionalità Wi-Fi Aware

Android 10 aggiunge il supporto per semplificare la creazione di socket TCP/UDP utilizzando il Wi-Fi Aware per i datapath. Per creare un socket TCP/UDP che si connette a un ServerSocket, il client Il dispositivo deve conoscere l'indirizzo IPv6 e la porta del server. In precedenza, era necessario comunicare fuori banda, ad esempio usando il livello BT o Wi-Fi Aware 2 o scoperti 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 ottieni 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 di 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 il protocollo 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_WINDOW sui dispositivi Go

Le app eseguite su dispositivi Android 10 Go non possono ricevere il SYSTEM_ALERT_WINDOW autorizzazione. Ciò è dovuto al fatto che le finestre di overlay disegnate utilizzano troppa memoria, particolarmente dannoso per le prestazioni dei dispositivi Android con memoria ridotta. dispositivi mobili.

Se un'app in esecuzione su un dispositivo Go con Android 9 o versioni precedenti riceve il messaggio di errore SYSTEM_ALERT_WINDOW, l'app conserva l'autorizzazione anche se viene eseguito l'upgrade del dispositivo ad Android 10. Tuttavia, le app che non dispongono già non può essere concessa 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 un Schermata Impostazioni in cui viene indicato che l'autorizzazione non è consentita perché rallenta 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 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 delle autorizzazioni, all'utente viene data anche la possibilità per regolare le autorizzazioni dell'app prima che possa essere eseguita per la prima nel tempo.

A causa dell'API target di Google Play requisiti, un utente vede questi avvisi solo quando esegue un'app che non è stata aggiornata di recente. Per le app distribuite tramite altri store, API target simile entreranno in vigore nel corso del 2019. Per ulteriori informazioni su questi requisiti, consulta l'articolo Espansione dei requisiti relativi al livello API target 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 rispetto a quelle simili che utilizzano GCM e la maggior parte dei server supporta entrambe le varianti GCM e CBC di questa crittografia suite o non supporta nessuna di queste.

Utilizzo di app

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

  • Miglioramenti all'utilizzo delle appUsageStats - Android 10 monitora accuratamente l'utilizzo delle app con UsageStats quando le app vengono in modalità schermo diviso o Picture in picture. Inoltre, Android 10 monitora correttamente l'utilizzo delle app istantanee.

  • Scala di grigi per app - Android 10 può impostare una modalità di visualizzazione in scala di grigi per ogni app.

  • Stato distrazione per app - Android 10 consente di impostare selettivamente le app sullo "stato di distrazione" dove le relative notifiche vengono soppresse e non vengono visualizzate come app suggerite.

  • Sospensione e riproduzione: Su Android 10, le app sospese non possono riprodurre contenuti audio.

Modifiche alla connessione HTTPS

Se un'app con Android 10 passa null a setSSLSocketFactory(), avviene un IllegalArgumentException. Nelle versioni precedenti, la trasmissione di null in setSSLSocketFactory() ha avuto lo stesso effetto di passare il valore predefinito fabbrica.

La libreria android.preference è deprecata

La libreria android.preference è deprecata a partire da Android 10. Gli sviluppatori dovrebbero invece utilizzare la raccolta di preferenze AndroidX, parte di Android Jetpack. Per risorse aggiuntive utili per la migrazione e di sviluppo, consulta la sezione Impostazioni guida insieme al nostro esempio pubblico l'app e la documentazione di riferimento.

Modifiche alle librerie di utilità dei file ZIP

Android 10 introduce le seguenti modifiche ai corsi dell'java.util.zip che gestisce i file ZIP. Queste modifiche migliorano il comportamento della raccolta coerente tra Android e altre piattaforme che utilizzano java.util.zip.

Inferiore

Nelle versioni precedenti, alcuni metodi della classe Inflater hanno generato un IllegalStateException se sono stati richiamati dopo una chiamata a end(). In Android 10, questi metodi generano un'eccezione NullPointerException.

File ZIP

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

ZipOutputStream

In Android 10 e versioni successive, Metodo finish() in ZipOutputStream non genera un ZipException se prova a scrivere un per un file ZIP che non contiene file.

Modifiche fotocamera

Molte app che utilizzano la fotocamera presuppongono che, se il dispositivo è in una configurazione verticale, il dispositivo fisico è anche in orientamento verticale, come descritto in Orientamento fotocamera. In passato questo era un presupposto sicuro, ma è diventato è cambiato con l'espansione dei fattori di forma disponibili, come i pieghevoli. Questo ipotesi su questi dispositivi può portare a una rotazione o una scalabilità errata (oppure entrambi) del mirino della fotocamera.

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 con la modalità multi-finestra.

Monitoraggio dell'utilizzo della batteria

A partire da Android 10, Reimpostazione di SystemHealthManager le statistiche sull'utilizzo della batteria ogni volta che il dispositivo viene scollegato dopo un ricarica completa. In linea di massima, un evento di ricarica importante si verifica quando il dispositivo è completamente carico o quando passa da quasi scarico a quasi carico.

Prima di Android 10, le statistiche sull'utilizzo della batteria venivano reimpostate ogni volta che il dispositivo veniva scollegato dalla corrente, a prescindere dalle variazioni minime del livello della batteria.

Ritiro di Android Beam

In Android 10 ritireremo ufficialmente Android Beam, una vecchia funzionalità avviare la condivisione di dati tra dispositivi tramite Near Field Communication (NFC). Stiamo inoltre ritirando molte delle API NFC correlate. Android Beam rimane disponibile come opzione per i partner produttori di dispositivi che desiderano utilizzarla, ma più a lungo nello sviluppo attivo. Android continuerà a supportare altre tecnologie NFC funzionalità e API, tuttavia, e casi d'uso come la lettura dai tag 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 inserito è zero.

Modifiche al comportamento java.util.regex.Matcher e pattern

Il risultato di split() è stato modificato in modo che non inizi più con un String vuoto ("") quando è presente una corrispondenza di larghezza zero all'inizio dell'input. Anche questo interessa String.split(). Ad esempio, "x".split("") ora restituisce {"x"} mentre restituiva {"", "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 lancia IllegalArgumentException anziché IndexOutOfBoundsException se la sostituzione String termina con una barra rovesciata solitaria, che non è valida. Ora viene lanciata la stessa eccezione se il valore sostitutivo String termina con $. In precedenza, non era prevista alcuna eccezione in questo scenario.
  • replaceFirst(null) non chiama più reset() su Matcher se genera un NullPointerException. Ora viene lanciata anche NullPointerException quando non corrisponde. In precedenza, veniva lanciato solo quando c'era una partita.
  • start(int group), end(int group) e group(int group) ora lanciano un'altra generale IndexOutOfBoundsException se l'indice del gruppo è fuori intervallo. In precedenza, questi metodi lanciavano ArrayIndexOutOfBoundsException.

L'angolo predefinito per GradientDrawable ora è TOP_BOTTOM

In Android 10, se definisci una GradientDrawable in XML e non forniscono una misurazione dell'angolo, l'orientamento del gradiente il valore predefinito è 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 alla versione più recente di AAPT2, Lo strumento imposta una misurazione dell'angolo pari a 0 per le app legacy se non c'è alcuna angolazione. viene specificata la misurazione.

Log per gli oggetti serializzati che utilizzano SUID predefinito

A partire da Android 7.0 (livello API 24), la piattaforma ha apportato una correzione nel valore predefinito serialVersionUID per i dati serializzabili oggetti. Questa correzione Non ha influito sulle app che avevano come target il livello API 23 o precedente.

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

Nello specifico, il sistema registra un avviso se tutte le seguenti condizioni sono vere:

  • L'app ha come target il livello API 23 o precedente.
  • Una classe è serializzata.
  • La classe serializzata utilizza il valore predefinito serialVersionUID, anziché di impostare esplicitamente un serialVersionUID.
  • Il valore predefinito di serialVersionUID è diverso da serialVersionUID nel caso in cui l'app abbia come target il livello API 24 o un livello superiore.

Questo avviso viene registrato una volta per ogni classe interessata. Il messaggio di avviso include una correzione suggerita, ovvero l'impostazione esplicita serialVersionUID sul valore predefinito che verrebbe calcolato se l'app ha come target il livello API 24 o 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 una versione 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, FileChannel.map() non è supportato per i file non standard, come /dev/zero, le cui dimensioni non possono essere modificate utilizzando truncate(). Indietro versioni di Android hanno inghiottito l'errore restituito truncate(), ma Android 10 genera una IOException. Se hai bisogno del comportamento precedente, devi utilizzare codice nativo.