Совместное использование контента Android провайдера документов через канал поиска или другой механизм - PullRequest
0 голосов
/ 15 января 2020

Есть ли способ создать трубу для поиска на Android Linux? Существуют различные странности android, например, ашмем, которые подходят близко, но их нельзя использовать для очень больших файлов.

Проблема: для чтения содержимого провайдера документов вызывается DocumentProvider.OpenDocument. Поставщик должен вернуть ParcelFileDescriptor. Ключевой частью ParcelFileDesriptor является дескриптор файла Linux, который передается по IP C процессу принимающего приложения. Базовый дескриптор файла может быть файлом (см. ParcelFileDescriptor.Open(File file,...)), каналом (см. ParcelFileDescriptor[] ParcelFileDescriptor.createPipe()) или сокетом. Файловые дескрипторы доступны для поиска; дескрипторы канала и сокета не являются.

Фактически, дескриптор ParcellableFile также допускает канал управления в обратном направлении, но канал управления в настоящее время используется только для отправки сообщения об ошибке при закрытии. На самом деле совместные приложения могли бы использовать обратную трубу для получения сообщений о поиске, но, к сожалению, это выходит за рамки. Мне нужно решение, которое будет вмещать системные проигрыватели Android без дополнительного клиентского кода. И чертовски важно, что это решение работает, когда пользовательский интерфейс android провайдера документов пытается создать миниатюру !!

Что нужно: какой-то дескриптор Linux для поиска канала (с целочисленным идентификатором, например файл, сокет или сокет), который будет использоваться для построения ParcelFileDescritor с использованием ParcelFileDescriptor ParcelFileDescriptor.fromFd(int fd).. Я готов сделать что-нибудь на стороне сервера; но полученный дескриптор файла для клиента должен быть доступен для поиска с использованием стандартных API.

Вариант использования:

Поставщик документов для общих файловых ресурсов SMB. В ответ на вызов openDocument поставщик документов возвращает t ParcellableFileDescriptor, который содержит целочисленный дескриптор файла, который может быть либо для физического файла, либо для именованного канала или сокета. Файловые дескрипторы доступны для поиска; труб и розеток нет.

Поставщик документов SMB отправляет канал в ParcellableFileDescriptor, который заполнен на стороне сервера данными из удаленного файла SMB.

На стороне клиента клиент запрашивает и получает ParcellableFileDescriptor для видеофайла. Если основной дескриптор файла предназначен для физического файла, он может эффективно выполнять поиск по файлу и, следовательно, может эффективно воспроизводить видеофайлы, даже если содержимое является файлом удаленной сети. Если основной дескриптор файла предназначен для сокета, то поведение поиска можно эмулировать, пропустив контент при поиске вперед или закрыв и снова открыв поток, а затем пропустив в новое местоположение. Медиаплееры, включая собственные android медиаплееры, делают это.

Все работает нормально, если это небольшой файл или если информация заголовка находится рядом с началом файла, что на самом деле верно для примерно половины всех видеофайлов. Некоторые форматы мультимедиа (в частности, MP4) получают метаданные в конце файла, что означает, что медиаплеер должен прочитать все 3 ГБ файла, чтобы в конце получить метаданные. На типичных скоростях сети это может занять до минуты, если FD представляет собой канал, а не файл. И это не может быть отменено. Некоторые видео файлы будут воспроизводиться. Большие JPG-файлы настолько малы, что чтение всех 10 МБ JPG-файлов несколько раз не является проблемой. Однако открытие файла 3GP MP4 с заголовками, расположенными в конце файла, может занять несколько минут. Точно так же попытка поиска видео в контенте ближе к концу видео может привести к задержкам в минуту или более, когда пропускается 3 ГБ данных.

...