Фон
Google (к сожалению) планирует испортить разрешение на хранение, чтобы приложения не могли получить доступ к файловой системе, используя стандартный File API (и пути к файлам). Многие против этого, поскольку это меняет способ, которым приложения могут получить доступ к хранилищу, и во многих отношениях это ограниченный и ограниченный API.
В результате нам потребуется полностью использовать SAF (инфраструктура доступа к хранилищу) в какой-то будущей версии Android (в Android Q мы можем, по крайней мере временно, использовать флаг, чтобы использовать обычное разрешение хранилища), если мы хотим иметь дело с различными объемы хранения и добраться до всех файлов там.
Так, например, предположим, что вы хотите создать файловый менеджер и показать все тома хранилища устройства и показать для каждого из них, сколько есть общих и свободных байтов. Такая вещь кажется очень законной, но, поскольку я не могу найти способ сделать такую вещь.
Эта проблема
Начиная с API 24 ( здесь), мы наконец-то получили возможность перечислять все тома хранения как таковые:
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumes = storageManager.storageVolumes
Дело в том, что для каждого элемента в этом списке нет функции, чтобы получить его размер и свободное пространство.
Однако приложение Google "Файлы от Google" каким-то образом получает эту информацию без какого-либо разрешения:
И это было проверено на Galaxy Note 8 с Android 8. Даже не последняя версия Android.
Таким образом, это означает, что должен быть способ получить эту информацию без какого-либо разрешения, даже на Android 8.
Что я нашел
Есть что-то похожее на получение свободного пространства, но я не уверен, действительно ли это так. Похоже, как таковой, хотя. Вот код для этого:
val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
val storageVolumes = storageManager.storageVolumes
AsyncTask.execute {
for (storageVolume in storageVolumes) {
val uuid: UUID = storageVolume.uuid?.let { UUID.fromString(it) } ?: StorageManager.UUID_DEFAULT
val allocatableBytes = storageManager.getAllocatableBytes(uuid)
Log.d("AppLog", "allocatableBytes:${android.text.format.Formatter.formatShortFileSize(this,allocatableBytes)}")
}
}
Однако я не могу найти что-то похожее для получения общего пространства каждого из экземпляров StorageVolume. Предполагая, что я прав в этом, я просил это здесь.
Вы можете найти больше того, что я нашел в ответе, который я написал на этот вопрос, но в настоящее время все это смесь обходных путей и вещей, которые не являются обходными, но работают в некоторых случаях.
Вопросы
- Действительно ли
getAllocatableBytes
это способ получить свободное место? - Как я могу получить свободное и реальное общее пространство (в некоторых случаях я получил более низкие значения по какой-то причине) каждого StorageVolume, не запрашивая никакого разрешения, как в приложении Google?