Как передавать файлы между приложениями Android, работающими на одном устройстве?
я пишу приложение для Android, которое взаимодействует с RESTful-сервис. Этот веб-сервис по существу фронтов файловой системы, и предоставляет метаданные, а также CRUD доступ к файлам. Мое приложение извлекает метаданные и предоставляет их сторонним приложениям через ContentProvider
.
мне нужно добавить возможность для сторонних приложений, работающих на том же устройстве, что и мое приложение, CRUD фактические файлы, делая запросы в/из моего приложения (не напрямую с сервером). Это означает, что они должны либо отправлять, либо получать содержимое файлов (которые обычно являются XML или изображениями) через мое приложение.
я подумал о двух подходах для реализации этого:
Вариант 1-Использование ContentProvider.функция openfile
это кажется очевидным выбором для предоставления сторонним приложениям возможности читать файлы из my ContentProvider
. Я думаю, что это начинает усложняться, когда этим приложениям нужно создавать или обновлять файлы через мой "ContentProvider". Мне понадобится обратный вызов, когда они закончат, чтобы узнать, когда отправить новый / измененный файл обратно на сервер. Я считаю, что я мог бы использовать FileObserver для этой цели, хотя.
Вариант 2-использование мессенджера через сервис
при таком подходе я могу отправлять файлы между моим приложением и клиентскими приложениями через Messenger
. Файлы должны быть переданы через Bundle
, поэтому я не уверен, что лучшее формат предназначен для их передачи (File
, FileDescriptor
, массив байтов, что-то еще??). У меня нет хорошей ручки о том, вызовет ли это проблемы, если файлы станут большими.
Вариант 3-гибридный подход
- используйте папки на внешнем хранилище в качестве выпадающего окна
- общайтесь с запросами CRUD и отбрасывайте содержимое коробки через
Messenger
/Service
- использовать
ContentProvider
для сохранения статуса запросов - 3-й приложение party получает обновления статуса через
ContentObserver
резюме
я думаю, что с помощью ContentProvider
было бы идеальным решением, но кажется, что API не полностью поддерживает мой вариант использования. Я обеспокоен тем, что попытка пойти по этому пути может привести к реализации kludgy. Если я пойду с Messenger
и Service
подход, я не уверен в наиболее надежном способе передачи файлов через Bundle
.
гибридный подход кажется довольно надежный, но самый сложный в реализации. Файлы на самом деле не передаются, поэтому производительность должна быть хорошей. Однако я боюсь, что это переоценивает решение.
каков наилучший подход для передачи файлов между приложениями, работающими на одном устройстве Android? конечно, я открыт для других вариантов, которые я не изложил в своем вопросе.
3 ответов
контент-провайдер, безусловно,путь. Если учесть, что google использует этот подход практически для всего, то становится понятно, что это предполагаемый метод проектирования.
Я не превозношу их добродетели, но в стране слепых, одноглазый контент-провайдер-король.
обновление
в книге CommonsWare приведен пример того, как это сделать, см. ссылку.
источник Контент-Провайдер / Файлы
используйте synch framework для поставщиков контента. Просто сохраните список запросов, а затем запланируйте синхронизацию для загрузки этих файлов. Вы также можете сделать это в сети tickles и т. д. можно использовать широковещательные намерения или contentobserver для уведомления клиентов о загрузке файла.
по сути, это, вероятно, похоже на ваш 3-й вариант, но важно, что он использует Android поставляемые инструменты, а не прокатки собственный.
Ad Endum
лучшее место для начала-образец Android SDK в: android-sdk\samples\android-8\SampleSyncAdapter, но будьте осторожны, что есть нагрузка контактов, связанных с вещами, которые маскируют сочные биты. Мне потребовалось некоторое время, чтобы понять, что я могу удалить почти все, кроме syncadapter
http://developer.android.com/reference/android/os/ParcelFileDescriptor.html смогите быть послано между процессами. Я считаю, что есть тонко, где они явно занесены в черный список из-за того, что им разрешено вводить намерения. Однако их можно отправить через AIDL. Кроме того, не используйте sdcard для этого. Это просто напрашивается на неприятности. Одна sdcard читается в мире, поэтому любой может ее увидеть. Кроме того, у вас не всегда есть доступ для записи на sdcard (он удаляется или вставляется UMS).
использование SD-карты, безусловно,рекомендовано способ перейти к обмену файлами на Android.
однако я бы пошел с модифицированным гибридным решением, которое использует startActivityForResult()
и onActivityResult()
(docs здесь) на стороне клиента для передачи запросов CRUD (и получения Uri в файл(ы) на SD-карте, если это необходимо), если вы не возражаете против создания фиктивной активности в качестве интерфейса к вашей службе. Клиенты, закончив с файлом(файлами), могут вызвать startActivityForResult()
снова, чтобы предупредить ваше приложение об изменениях.
конечно, это можно сделать с помощью startService()
/bindService()
однако это не обеспечивает простой способ для клиентов получить результат состояния, особенно если вам нужен IPC.
хотя контент-провайдеры / решатели чувствуют себя правильным способом, я чувствую, что это больше для запросов одного направления, специфичных для предоставления / потребления контента.