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

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

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

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

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

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

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

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

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

  1. Использование папок на внешнем хранилище в качестве раскрывающегося окна
  2. Передача запросов CRUD и содержимого удаленного ящика черезMessenger / Service
  3. Используйте ContentProvider для хранения статуса запросов
  4. Стороннее приложение получает обновления статуса через ContentObserver

Резюме

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

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

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

Ответы [ 3 ]

16 голосов
/ 08 сентября 2011

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

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

Обновление

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

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

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

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

Конец объявления

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

3 голосов
/ 10 сентября 2011

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

2 голосов
/ 04 сентября 2011

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

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

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

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

...