Укажите путь по умолчанию для ACTION_OPEN_DOCUMENT - PullRequest
0 голосов
/ 11 марта 2019

В моем приложении я хочу дать пользователям возможность выбрать файл из каталога данных приложения. Это мой код:

// use ACTION_OPEN_DOCUMENT because ACTION_GET_CONTENT will give us
// gallery and other stuff we don’t need
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
Uri uri = Uri.parse(getExternalFilesDir(null).getAbsolutePath());
Log.d(TAG, "Browsing " + uri.toString());
intent.setDataAndType(uri, "*/*");
// show the entire internal storage tree
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
startActivityForResult(intent, 42);

Logcat показывает мне, что я устанавливаю URI file:///sdcard/Android/data/my.app/files, но пользовательский интерфейс средства выбора файлов по умолчанию имеет корень общего хранилища (/sdcard).

Следующий код работает (требуется API 26+ в соответствии с документацией, намерение доступно из API как DocumentsContract.EXTRA_INITIAL_URI):

// works only with this intent, at the expense of gallery etc. appearing
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);

// apparently we need a valid content URI
Uri uri = Uri.parse("content://com.android.externalstorage.documents/document/primary%3AAndroid%2Fdata%2Fmy.app%2Ffiles");

intent.putExtra("android.provider.extra.INITIAL_URI", uri);

Log.d(TAG, "Browsing " + uri.toString());
intent.setType("*/*");
// show the entire internal storage tree
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
startActivityForResult(intent, 42);
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri);

Однако, ACTION_GET_CONTENT вызывает появление всевозможных провайдеров, таких как «Галерея» и «Музыка», когда все, что мне нужно, это локальная файловая система (а на самом деле только частное поддерево приложения). Если я изменю намерение на ACTION_OPEN_DOCUMENT, предоставленный мною URI игнорируется.

Как заставить пользовательский интерфейс средства выбора файлов запускаться в каталоге по моему выбору, с минимальным выбором поставщиков контента?

Редактировать: Тестирование этого на Anbox, которое я только что понял, только на API 25 - на самом деле мне нужен способ, который работает на API, начиная с 24.

1 Ответ

0 голосов
/ 12 марта 2019

Может не быть универсально жизнеспособного решения, но для некоторых сборок (хотя и не для других) работает следующее:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);

Uri uri = Uri.parse("content://com.android.externalstorage.documents/document/primary%3AAndroid%2Fdata%2Fmy.app%2Ffiles");

intent.setData(uri);
intent.setType("*/*");
intent.putExtra("android.provider.extra.INITIAL_URI", uri);
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);

startActivityForResult(intent, 42);

uri должен быть content URI для com.android.externalstorage.documents провайдер.Путь URI - /document/primary%3A, за которым следует путь файловой системы к папке для запуска. Путь должен быть относительно корня общего хранилища (т. Е. Удалить на устройстве начальный /sdcard/ или эквивалентный и убедиться, что результат не соответствуетначать с косой черты) и экранировать.

Вызов Intent#setData() не помогает в настройке местоположения по умолчанию (в отличие от некоторых сторонних файловых менеджеров), но предотвращает нежелательных поставщиков хранилищ (таких как Галерея и Музыка)

Дополнительный android.provider.extra.INITIAL_URI устанавливает начальный URI, но это может не сработать до API 26 (хотя он работает на некоторых версиях Android).

android.content.extra.SHOW_ADVANCED дополнительные действия приводят к тому, что хранилище устройства становится доступным в качестве поставщика (в противном случае, в зависимости от разновидности Android, пользователю может потребоваться выбрать его или вообще не быть доступным).

Опять же, все еще не идеальное решениено ближе всего мне удалось добраться.

...