Следите за изменениями во внешнем USB-накопителе для Honeycomb или более поздних версий Android

У меня есть зеркальная камера и Samsung Galaxy Tab с Android Honeycomb. Цифровая зеркальная камера подключена к планшету с помощью USB-кабеля (через комплект USB, обеспечивающий функциональность хоста на планшете). Я хотел бы получать уведомления, когда пользователь делает фотографию с помощью этой внешней камеры, чтобы загрузить это изображение на планшет или сделать что-то еще с ним, например, показать уведомление о тосте, содержащее мета-информацию, взятую из изображения.

Насколько я понимаю, все существующие инструменты (например, FileObserver используя базовый inotify механизм, MediaContentProvider и т.д.) позволяя отслеживать изменения, требовать отслеживания определенного файла или пути к файловой системе. Это было достаточно, пока у нас не было поддержки протокола блочного уровня в 2.x и более ранних версиях Android - когда вы подключили устройство, оно было смонтировано где-то в файловой системе устройства, и вы смогли использовать эту точку монтирования в качестве точки наблюдения для этих инструментов,

С тех пор как Honeycomb Google изменил способ доступа к внешним USB-устройствам Media Transfer Protocol с PTP как подмножество этого. Теперь, когда я подключаю внешнее USB-устройство к устройству Android, я не вижу точек подключения для него (я использую adb shell и последующее mount команда для их получения). Более того, MTP В реализации используются идентификаторы хранилища, которые, по-видимому, действуют как более высокий уровень абстракции и представляют собой просто целочисленные значения. Я надеялся, что есть способ как-то перевести эти идентификаторы хранилища в реальные пути / точки монтирования / что угодно, но, видимо, их там нет.

Думая об Android MediaScanner который уже запущен на моем устройстве, я догадался, что может решить эту проблему с помощью специального Intent транслировался, когда есть изменения в медиа-файлах, доступных с устройства, поэтому я начал искать уже существующие и подходящие Intents за уведомление, но не повезло - я нашел только ACTION_MEDIA_MOUNTED а также ACTION_MEDIA_REMOVED которые транслируются только тогда, когда устройство подключено и отключено соответственно. Это означает MediaScanner не может заметить никаких изменений на устройстве, пока вы не перемонтируете его (я дважды проверил его с помощью приложения "Галерея" - оно не видит вновь созданные изображения на камере, пока вы не отключите его, а затем снова не подключите его к устройству Android),

Пытаясь получить этот путь монтирования для внешней SDCard, я использовал Environment.getExternalStorageDirectory() Вызов API, но он дает эмулированный путь SDCard Galaxy, который /mnt/sdcardа не камера. Так что это не работает для меня тоже.

Мне удалось решить эту проблему только запустив периодический Timer событие с AsyncTask действуя как TimerTask, Эта задача инициализирует USB-соединение, открывает устройство, сканирует всю память устройства, получает только последнюю сделанную фотографию, а затем закрывает дескриптор устройства и USB-соединение.

Это не самый лучший и эффективный способ сделать это, учитывая, что он должен выполнять все эти действия каждый раз, что может быть довольно часто, скажем, каждые 5 или 10 секунд. Он определенно быстро разряжает батарею и производит ненужные системные операции ввода-вывода, позволяющие делать только последний снятый снимок и сравнивать его с предыдущим последним снимком (на 99% это было бы то же изображение), но я не нашел лучшего рабочего решения для этого. Было бы лучше иметь механизм наблюдателя с уведомлениями на основе событий.

Итак, мой вопрос, есть ли более эффективный способ уведомления об изменениях внешнего USB-накопителя для Honeycomb или более поздних версий Android, чем описанный выше?

1 ответ

Если вы хотите более эффективный способ, камера должна послать какой-то сигнал через USB, что она сделала фотографию. Я думаю, что это не так.

Поэтому вам придется проверить вручную, выполнив то, как вы пишете:

смонтировать хранилище -> проверить наличие изменений -> сделать свое дело с обнаруженными изменениями.

Я не знаю, что вы использовали, чтобы прочитать "путь MTP", но вот пример приложения:

https://github.com/ynakanishi/Honeycomb-MTP-sample

Чтобы не сканировать все хранилище каждый раз, вы можете сохранять результат считанных имен файлов, например, каждый раз, когда вы проверяете и сравниваете его, чтобы найти новые. Обычно именование файла также начинается с того же номера на камере. Таким образом, если вы начинаете сеанс с пустой SD-картой, вы уже знаете имя файла, которое будет иметь фотография. скажем, img0001.jpg. Так что вам просто нужно написать функцию для захвата этого файла, пока он не будет успешным. если вам нужен следующий img0002.jpg, вы можете написать задачу / сервис / функцию, которая будет захватывать этот файл до тех пор, пока не будет успешно, и так далее.

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

Вместо асинхронной задачи или timerTask вы можете попробовать ScheduledExecutorService и посмотреть, использует ли он меньше энергии.

Надеюсь, что это дало вам новые мысли

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