Pruebe mediante programación si en Android 10+ el acceso de almacenamiento externo heredado está deshabilitado

12

¿Hay una simple llamada a la API que me diga si una aplicación que se ejecuta en Android 10 o posterior debe usar el acceso de Scoped Storage, es decir, si el acceso normal a los archivos, también conocido como "Legacy External Storage" está desactivado? Tenga en cuenta que incluso si la aplicación en AndroidManifest.xml, la sección declara:

  android:requestLegacyExternalStorage="true"

el acceso al archivo aún puede denegarse debido a cambios en la política de Google en el futuro, por lo que probar este valor es inútil. La única forma que encontré es probar si el directorio raíz de almacenamiento externo es legible, pero para eso, la aplicación primero debe solicitar permiso de almacenamiento, que es inútil para cualquier otra cosa, si el almacenamiento heredado está deshabilitado.

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.
}

Creo que una vez vi una nueva API para detectar esto, pero ya no puedo encontrar ese artículo ...

Gregko
fuente
an app running on Android 10 or later must use Scoped Storage access? ¿Puedes explicar a qué te refieres con eso? ¿Qué funciones tienes en mente? Sé que, por ejemplo, Storage Volumes y Storage Manager que se trajeron para N ya están en desuso para Q.
blackapps
Me refiero al acceso regular a Java File más allá del sandbox asignado a la aplicación por el sistema, o por ejemplo, en código C / C ++ JNI fopen ("filename.ext", modo); no funcionará (acceso denegado) si la ruta del archivo está más allá del directorio de aplicaciones asignado por el sistema. Bueno, ahora funcionará en Android 10, si usa android: requestLegacyExternalStorage = "true" en el manifiesto, pero es una solución temporal y puede deshabilitarse por completo el próximo año. Leer más, por ejemplo, androidcentral.com/what-scoped-storage-android-q
gregko
Incluso en ese artículo no está claro cuál sería el almacenamiento con alcance.
blackapps
@blackapps, tal vez este artículo lo explique mejor: developer.android.com/training/data-storage/files/…
gregko
Okay. Acceso restringido a directorios privados de aplicaciones solamente.
blackapps

Respuestas:

8

Puede usar estos dos métodos desde android.os.Environment:

  • isExternalStorageLegacy(File path)

    Devuelve si el medio de almacenamiento compartido / externo en la ruta dada es una vista heredada que incluye archivos que no son propiedad de la aplicación.

  • isExternalStorageLegacy()

    Devuelve si el medio de almacenamiento primario compartido / externo es una vista heredada que incluye archivos que no son propiedad de la aplicación.

Este valor puede ser diferente del valor solicitado por requestLegacyExternalStorageel manifiesto de la aplicación, ya que una aplicación puede heredar su estado heredado en función de cuándo se instaló por primera vez.

Las aplicaciones no heredadas pueden continuar descubriendo y leyendo medios que pertenecen a otras aplicaciones a través de MediaStore.

En caso de que descubra que tiene acceso al almacenamiento heredado, personalmente creo que es mejor simplemente migrar los datos al almacenamiento con alcance y usarlos, ya que el almacenamiento heredado puede dejar de funcionar sin previo aviso.

Zaffy
fuente
1
Gracias, @Zaffy, esta es exactamente la respuesta que estaba buscando. Funciona perfectamente y no hay necesidad de pedir "Acceso al almacenamiento".
gregko