Teste programaticamente se no Android 10+ o acesso ao armazenamento externo herdado está desativado

12

Existe uma chamada de API simples que me diga se um aplicativo em execução no Android 10 ou posterior deve usar o acesso ao armazenamento com escopo definido, ou seja, se o acesso normal a arquivos, conhecido como "Armazenamento externo herdado" estiver desativado? Observe que, mesmo que o aplicativo no AndroidManifest.xml, a seção declare:

  android:requestLegacyExternalStorage="true"

o acesso ao arquivo ainda pode ser negado devido a alterações na política do Google no futuro. Portanto, testar esse valor é inútil. A única maneira que encontrei é testar se o diretório raiz do armazenamento externo é legível, mas para isso, o aplicativo deve primeiro pedir permissão de armazenamento, que é inútil para qualquer outra coisa, se o armazenamento herdado estiver desativado.

public static boolean mustUseScopedStorage() {
    // Impractical must first ask for useless Storage permission...
    File exSD = Environment.getExternalStorageDirectory();
    return !exSD.canRead(); // this test works only if Storage permission was granted.
}

Acho que já vi uma nova API para detectar isso, mas não consigo mais encontrar esse artigo ...

Gregko
fonte
an app running on Android 10 or later must use Scoped Storage access? Você pode explicar o que você quer dizer com isso? Quais funções você tem em mente? Eu sei que, por exemplo volumes de armazenamento e Storage Manager que foram trazidos para N já estão obsoletos para Q.
blackapps
Refiro-me ao acesso regular ao arquivo Java além da sandbox atribuída ao aplicativo pelo sistema, ou por exemplo, no código JNI do C / C ++ fopen ("filename.ext", mode); não funcionará (acesso negado) se o caminho do arquivo estiver além do diretório do aplicativo atribuído pelo sistema. Bem, ele funcionará no Android 10 agora, se você usar android: requestLegacyExternalStorage = "true" no manifesto, mas é uma solução temporária e pode ser desativada completamente no próximo ano. Leia mais eg androidcentral.com/what-scoped-storage-android-q
gregko
Mesmo nesse artigo, não está claro o que seria o armazenamento com escopo definido.
blackapps
@blackapps, talvez este artigo explica melhor: developer.android.com/training/data-storage/files/...
gregko
Está bem. Acesso restrito apenas aos diretórios privados dos aplicativos.
blackapps

Respostas:

8

Você pode usar esses dois métodos em android.os.Environment:

  • isExternalStorageLegacy(File path)

    Retorna se a mídia de armazenamento compartilhada / externa no caminho especificado é uma exibição herdada que inclui arquivos que não pertencem ao aplicativo.

  • isExternalStorageLegacy()

    Retorna se a mídia de armazenamento compartilhada / externa principal é uma exibição herdada que inclui arquivos que não pertencem ao aplicativo.

Esse valor pode ser diferente do valor solicitado requestLegacyExternalStorageno manifesto do aplicativo, pois um aplicativo pode herdar seu estado legado com base em quando foi instalado pela primeira vez.

Aplicativos não legados podem continuar a descobrir e ler mídias pertencentes a outros aplicativos via MediaStore.

Caso descubra que você tem acesso ao armazenamento herdado, pessoalmente acho melhor migrar dados para o armazenamento com escopo definido e usá-lo, pois o armazenamento herdado pode parar de funcionar sem aviso.

Zaffy
fonte
11
Obrigado, @Zaffy, esta é exatamente a resposta que eu estava procurando. Funciona perfeitamente e não é necessário solicitar "Acesso ao armazenamento".
gregko