Подтвердить что ты не робот

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

Я пишу приложение для Android, которое взаимодействует с сервисом RESTful. Этот веб-сервис, по существу, выходит из файловой системы и предоставляет метаданные, а также доступ к файлам с помощью CRUD. Мое приложение извлекает метаданные и предоставляет их сторонним приложениям через ContentProvider.

Мне нужно добавить способность сторонних приложений, работающих на том же устройстве, что и мое приложение, к CRUD с фактическими файлами, делая запросы в/из моего приложения (а не напрямую с сервера). Это означает, что они должны либо отправлять, либо получать содержимое файлов (которые обычно являются XML или изображениями) через мое приложение.

Я подумал о двух подходах для реализации этого:

Вариант 1 - Использование ContentProvider.openFile

Это кажется очевидным выбором для предоставления сторонним приложениям возможности читать файлы с моего ContentProvider. Я думаю, что это начинает усложняться, когда эти приложения должны создавать или обновлять файлы через мой ContentProvider. Мне понадобится обратный вызов, когда они будут завершены, чтобы узнать, когда отправить новый/измененный файл обратно на сервер. Я полагаю, что для этой цели я мог бы использовать FileObserver.

Вариант 2 - Использование Messenger через службу

При таком подходе я могу отправить файлы между моим приложением и клиентскими приложениями через Messenger. Файлы должны быть переданы через Bundle, поэтому я не уверен, какой лучший формат для их передачи (File, FileDescriptor, массив байтов, что-то еще?). У меня нет хорошей справки о том, вызовет ли это проблемы, если файлы станут большими.

Вариант 3 - гибридный подход

  • Использовать папку (-ы) на внешней памяти в качестве раскрывающегося списка
  • Обмениваться запросами CRUD и отображать содержимое окна с помощью Messenger/Service
  • Используйте ContentProvider для хранения статуса запросов
  • Стороннее приложение получает обновления статуса через ContentObserver

Резюме

Я думаю, что использование ContentProvider было бы идеальным решением, но похоже, что API не полностью поддерживает мой прецедент. Я обеспокоен тем, что попытка спуститься по этому пути может привести к запутанной реализации. Если я использую подход Messenger и Service, я не уверен в наиболее надежном способе переноса файлов через Bundle.

Гибридный подход кажется довольно надежным, но наиболее сложным для реализации. Файлы фактически не передаются, поэтому производительность должна быть хорошей. Однако я боюсь, что это чрезмерное архитектурное решение.

Каков наилучший способ передачи файлов между приложениями, запущенными на одном устройстве Android? Конечно, я открыт для других вариантов, которые я не указал в моем вопросе.

4b9b3361

Ответ 1

Поставщик контента - это, безусловно, путь. Если вы считаете, что Google использует этот подход почти для всех, то он становится appaentr, что это предполагаемый метод проектирования.

Я не превозношу достоинства их, но на земле слепых провайдер контента с одним взглядом является королем.

Обновление

Ниже приведен пример того, как это сделать в книге CommonsWare, см. предоставленную ссылку.

Источник поставщика контента/файлы

Используйте инфраструктуру синхронизации для поставщиков контента. Просто поддерживайте список запросов, а затем планируйте синхронизацию для загрузки этих файлов. Вы также можете сделать это на сетевых щеках и т.д. Вы можете использовать трансляции или контент-сервер, чтобы уведомить клиентов о том, что файл загружен.

По сути, это, вероятно, похоже на ваш третий вариант, но важно, чтобы он использовал инструменты, поставляемые Android, а не сворачивал ваши собственные.

Ad Endum

Лучшим местом для начала является образец SDK для Android в: android-sdk\samples\android-8\SampleSyncAdapter, но следует предупредить о том, что нагрузка связанных с контактами материалов, которая маскирует сочные биты. Мне потребовалось некоторое время, чтобы понять, что я могу удалить почти все, кроме syncadapter

Ответ 2

http://developer.android.com/reference/android/os/ParcelFileDescriptor.html может быть отправлено между процессами. Я считаю, что есть тонко, где они явно занесены в черный список из-за того, что их можно ввести в заблуждение. Они могут быть отправлены через AIDL. Кроме того, НЕ используйте SDK для этого. Это просто просит неприятностей. Одна SD-карта является читаемой в мире, поэтому любой может ее увидеть. Кроме того, у вас не всегда есть доступ к записи на SD-карту (она удаляется или помещается в UMS).

Ответ 3

Использование SD-карты, безусловно, рекомендуется для обмена файлами на Android.

Однако я бы пошел с модифицированным гибридным решением, которое использует startActivityForResult() и onActivityResult() (docs здесь) на клиенте чтобы сообщать запросы CRUD (и получать Uri в файл на SD-карте, если это необходимо), если вы не возражаете против создания фиктивной активности в качестве передней части вашей службы. Клиенты, закончив с файлом (-ами), могут снова вызвать startActivityForResult(), чтобы предупредить ваше приложение об изменениях.

Конечно, это можно сделать с помощью startService()/bindService(), однако он не обеспечивает простой способ для клиентов получить результат статуса, особенно если вам нужен IPC.

Хотя контент-провайдеры/преобразователи чувствуют себя как правильный способ заниматься вещами, я чувствую, что это больше для запросов с одним направлением, специфичных для предоставления/потребления контента.