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

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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

монтировать хранилище → проверить изменения → делать свою вещь с обнаруженными изменениями.

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

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

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

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

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

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