Багато хороших запитань, давайте розберемося. :)
Як ти ним користуєшся?
Ось чудовий підручник для взаємодії з рамкою доступу до зберігання в KitKat:
https://developer.android.com/guide/topics/providers/document-provider.html#client
Взаємодія з новими API в Lollipop дуже схожа. Щоб спонукати користувача вибрати дерево каталогів, ви можете запустити такий намір:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
Потім у своєму onActivityResult () ви можете передати вибраний користувачем Uri до нового допоміжного класу DocumentFile. Ось короткий приклад, який перераховує файли у вибраній директорії, а потім створює новий файл:
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (resultCode == RESULT_OK) {
Uri treeUri = resultData.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
// List all existing files inside picked directory
for (DocumentFile file : pickedDir.listFiles()) {
Log.d(TAG, "Found file " + file.getName() + " with size " + file.length());
}
// Create a new file and write into it
DocumentFile newFile = pickedDir.createFile("text/plain", "My Novel");
OutputStream out = getContentResolver().openOutputStream(newFile.getUri());
out.write("A long time ago...".getBytes());
out.close();
}
}
Повернений Uri DocumentFile.getUri()
досить гнучкий для використання з різними API платформ. Наприклад, ви можете поділитися ним за Intent.setData()
допомогою Intent.FLAG_GRANT_READ_URI_PERMISSION
.
Якщо ви хочете отримати доступ до цього Uri з рідного коду, ви можете зателефонувати, ContentResolver.openFileDescriptor()
а потім використати ParcelFileDescriptor.getFd()
або detachFd()
отримати традиційне ціле число дескриптора файлу POSIX.
Як перевірити, чи можете ви отримати доступ до файлів / папок?
За замовчуванням Uris, що повернувся через рамки доступу до зберігання, не зберігається через перезавантаження. Платформа "пропонує" можливість зберігати дозвіл, але вам потрібно "взяти" дозвіл, якщо ви цього хочете. У нашому прикладі вище, ви зателефонуєте:
getContentResolver().takePersistableUriPermission(treeUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Ви завжди можете розібратися, що надає доступ до вашої програми через ContentResolver.getPersistedUriPermissions()
API. Якщо вам більше не потрібен доступ до збереженого Урі, ви можете звільнити його ContentResolver.releasePersistableUriPermission()
.
Це доступно на KitKat?
Ні, ми не можемо заднім числом додати нову функціональність до старих версій платформи.
Чи можу я побачити, які програми мають доступ до файлів / папок?
Наразі немає інтерфейсу, який би це показував, але ви можете знайти деталі у розділі "Випущені дозволи на Uri" adb shell dumpsys activity providers
.
Що станеться, якщо додаток встановлено для декількох користувачів на одному пристрої?
Дотації на дозвіл Uri виділяються на основі кожного користувача, як і всі інші функції багатокористувацької платформи. Тобто, той самий додаток, який працює під двома різними користувачами, не має накладених дозволів на дозвільне використання Uri.
Чи можна скасувати дозволи?
Резервний DocumentProvider може відкликати дозвіл у будь-який час, наприклад, коли видаляється хмарний документ. Найпоширеніший спосіб виявити ці відкликані дозволи - це зникнення ContentResolver.getPersistedUriPermissions()
згаданих вище.
Дозволи також скасовуються, коли дані програми додаються для будь-якого додатка, що бере участь у гранті.
Попросили б дозвіл працювати рекурсивно у вибраній папці?
Так, цей ACTION_OPEN_DOCUMENT_TREE
намір надає вам рекурсивний доступ до існуючих та новостворених файлів та каталогів.
Це дозволяє багаторазовий вибір?
Так, з KitKat підтримується багаторазовий вибір, і ви можете дозволити це, встановивши, EXTRA_ALLOW_MULTIPLE
починаючи свій ACTION_OPEN_DOCUMENT
намір. Ви можете використовувати Intent.setType()
або EXTRA_MIME_TYPES
звужувати типи файлів, які можна вибрати:
http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT
Чи є можливість на емуляторі спробувати новий API?
Так, основний пристрій спільного зберігання повинен з’являтися в засобі вибору, навіть на емуляторі. Якщо ваш додаток використовує тільки Framework Access Storage для доступу до спільної пам'яті, вам більше не потрібні READ/WRITE_EXTERNAL_STORAGE
дозволи на всі і може видалити їх або використовувати android:maxSdkVersion
функцію тільки запросити їх на більш старих версіях платформи.
Що відбувається, коли користувач замінить SD-карту на іншу?
Якщо задіяні фізичні носії, UUID (наприклад, серійний номер FAT) базових носіїв інформації завжди спалюється у повернутий Uri. Система використовує це для підключення вас до медіа, який користувач спочатку обрав, навіть якщо користувач обмінюється носієм між кількома слотами.
Якщо користувач обміняється другою карткою, вам потрібно буде запропонувати отримати доступ до нової картки. Оскільки система запам'ятовує дотації на основі UUID, вам надалі надаватиметься доступ до оригінальної картки, якщо користувач повторно вставить її пізніше.
http://en.wikipedia.org/wiki/Volume_serial_number