Просматривая съемную USB OTG на Android N, действительно ли Storage Access Framework - единственный способ?

У нас есть пользовательское устройство Android, работающее под управлением Nougat и обернутое в специфичную для поставщика программу запуска. Я пытаюсь реализовать диспетчер файлов для указанного устройства с использованием API 23. Это потому, что я прочитал, что единственный способ сделать это, начиная с Android M, - это SAF.

Устройство, на котором я разрабатываю, имеет 3 порта USB, к которым при подключении USB-накопителя приложение будет обнаруживать и передавать пользовательские файлы с USB-накопителя во внутреннюю память устройства (на устройстве нет SD-карты). Поскольку прямой доступ к монтируемому хранилищу на Android не используется, N I думал об этом с помощью SAF.

Я реализовал широковещательные приемники для USB отсоединения и подключения через USB-менеджер и USB-хост и могу успешно определять, подключен ли USB или нет, в тщетной попытке связаться с устройством и попытаться извлечь файлы. Но я также читал, что Android USB Framework предназначен только для отправки небольших байтов для связи с USB-подключенным устройством, таким как плата Arduino, а что нет.

Я сейчас пытаюсь реализовать провайдера документов USB для просмотра USB. Так как я не могу напрямую получить доступ к файлам согласно этому посту.

Я следую этому исходному коду для реализации моего USB-провайдера документов.

В настоящее время я реализую часть класса queryRoots и queryChildDocuments. Большинство полей для курсора я понимаю, что поставить, но часть для COLUMN_DOCUMENT_ID ставит меня в тупик (для обоих методов).

Поскольку устройство является съемным USB, я не знаю, что указать в качестве значения для столбца

Вот моя реализация метода queryRoots:

@Override
public Cursor queryRoots(String[] projection) throws FileNotFoundException {
    final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
    final MatrixCursor.RowBuilder row = result.newRow();
    row.add(Root.COLUMN_ROOT_ID, BuildConfig.DOCUMENTS_AUTHORITY);
    row.add(Root.COLUMN_ICON, R.drawable.ic_menu_manage);
    row.add(Root.COLUMN_TITLE, "Root Title");
    row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_RECENTS);
    row.add(Root.COLUMN_SUMMARY, "USB Reader");
    row.add(Root.COLUMN_DOCUMENT_ID, "/");
    row.add(Root.COLUMN_MIME_TYPES, "*/*");

    Uri rootsUri = DocumentsContract.buildRootsUri(BuildConfig.DOCUMENTS_AUTHORITY);
    getContext().getContentResolver().notifyChange(rootsUri, null);
    return result;
}

Пожалуйста, исправьте меня, если я ошибаюсь, но так как файлы, которые я хочу экспортировать, не являются вашими типичными файлами mime-типов, я установил для COLUMN_MIME_TYPES значение

*/*

И мой метод queryChildDocuments:

   @Override
    public Cursor queryChildDocuments(String parentDocumentId, String[] projection,
                                      String sortOrder) throws FileNotFoundException {
        final MatrixCursor result = new
                MatrixCursor(resolveDocumentProjection(projection));
        String parentDocumenPath = getContext().getFilesDir().getPath() + "/" + parentDocumentId;
        File dir = new File(parentDocumenPath);
                    for (File file : dir.listFiles()) {
            String documentId = parentDocumentId + "/" + file.getName();
            includeFile(result, documentId);
        }

        return result;
    }

Кроме этого, в моей реализации нет ничего особенного.

Затем я решил открыть провайдер документов через меню навигации с этим кодом:

if (id == R.id.nav_file_explorer) {
            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
            startActivityForResult(intent, 1);
}

Пользовательский поставщик документов отображается в списке, но USB-накопитель отсутствует в списке. Кроме того, когда я нажимаю на провайдера документов, чтобы открыть его из указанного мной корня, он ничего не возвращает. Что я делаю неправильно?

1 ответ

Решение

Доступ к данным съемного хранилища можно сделать без SAF в Android M и выше. Вам просто нужно сделать низкоуровневое кодирование. Как показано в этом проекте. Мы в нашем проекте могли бы предпочесть реализацию чего-то похожего на этот связанный проект, поскольку SAF оказывается ненадежным на данный момент.

Проект также включает реализацию SAF, но с низкоуровневой библиотекой чтения USB в качестве основы.

Другие вопросы по тегам