Иногда экосистеме Android немного не хватает поддержки инструментов; например, мне нужно было извлечь набор отправленных элементов из почтового ящика POP3 — стандартный почтовый клиент позволяет выполнять только 3 действия: удалить, пометить как непрочитанное или избранное.
Вооружившись Android SDK, некоторыми SQL-запросами и скриптом Groovy, мы увидим, как можно восстановить электронную почту в файлы RFC822 .eml.
Хранение электронной почты
Стандартный клиент com.android.email хранит заголовки сообщений и их тела в двух базах данных sqlite, а AttachmentProvider хранит вложения на диске.
Исходный код доступен по адресу https://android.googlesource.com/platform/packages/apps/Email — в данном случае это был телефон Samsung с версией 4.1.2, поэтому я проверил ветку jb-mr0-release для проверки код, когда требуется.
Резервное копирование с помощью ADB
ADB — это Android Debug Bridge , инструмент отладки, который является частью инструментов платформы Android SDK . Выполнение ‘ adb usb ‘ (пере) запускает демон adbd, прослушивающий USB-соединения.
Следующим шагом является выбор параметров разработчика в разделе «Система» списка настроек (рисунок 1), а затем включение отладки по USB на устройстве (рисунок 2).
Затем подключитесь к устройству с помощью USB-кабеля и выполните команду « adb backup -f mybackup.ab -all » (вы также можете более избирательно подходить к нужному пакету, например, « adb backup -f mybackup.ab com.android.email » ). АБР предложит вам разблокировать телефон и разрешить выполнение резервного копирования.
Накачка бэкапа
Резервная копия Android — это tar-файл с дефлированным Zlib — спасибо http://nelenkov.blogspot.jp/2012/06/unpacking-android-backups.html за подсказку, что его можно перекачать с помощью следующей команды:dd if=mybackup.ab bs=24 skip=1|openssl zlib -d > mybackup.tar
Обратите внимание, что установка openssl, которая была у меня на OSX, не была скомпилирована с поддержкой zlib , поэтому я запустил ее через виртуальную машину Ubuntu Vagrant, чтобы накачать файл tar.
ИЗУЧЕНИЕ РЕЗЕРВНОГО КОПИРОВАНИЯ
Распаковка файла tar даст вам структуру папок, как показано на рисунке 3; в этом случае базы данных sqlite находятся в БД, а вложения фотографий, снятые с телефона, находятся в f .
Изучение баз данных
Sqlitebrowser — хороший инструмент для просмотра базы данных sqlite и функций на следующих скриншотах.
Текущий скрипт ограничивает количество обрабатываемых сообщений одним почтовым ящиком для одной учетной записи. Для определения mailboxKey необходимо найти целевую учетную запись из таблицы « Учетная запись» (рисунок 4), а затем изолировать нужный почтовый ящик для этой учетной записи в таблице « Почтовый ящик» (рисунок 5).
Вы можете просмотреть данные или выполнить следующий запрос, чтобы получить список почтовых ящиков и их соответствующих учетных записей:
SELECT a.displayName as accountName, m._id as mailboxKey, m.displayName as mailboxName
FROM Account a, Mailbox m
WHERE m.accountKey = a._id
Если вы не хотите ограничивать извлечение одним почтовым ящиком или учетной записью, вы можете удалить предложение WHERE из первого запроса SELECT .
Извлечение электронной почты
Удовлетворяя спецификации RFC822 и JavaMail (я создал расширение IMAP для Alfresco в 2006 году), я решил, что будет проще реконструировать MimeMessage с использованием SQL & Groovy, чем пытаться адаптировать исходный код Android для запуска с устройства или создать Пользовательское приложение для запуска в эмуляторе.
НЕДОСТАТКИ
В качестве первого среза, который был достаточно хорош для моих целей, есть несколько недостатков:
1. Он установлен по умолчанию для поля Отправитель вместо преобразования значения Message.fromList и использования метода addFrom
2. Адреса используют только адрес, а не чем метка
3. При обработке тела используется только простой текст, а не альтернативные мультипликаторы.
4. Body.textReply отделен от Body.textContent разделительной линией из 25 штрихов; он не пытается восстановить информацию заголовка предыдущего сообщения в потоке
5. Скрипт не обрабатывает вложения — это было сознательное решение, так как фотографии с камеры были на com.android.email/fдругие вложения «RAW» не были в com.android.email/1.db_att/ согласно javadoc класса AttachmentProvider
В качестве начальной подсказки, чтобы восстановить вложения, которые вам понадобятся, используйте MimeMultipart , создайте объекты MimeBodyPart, начиная с запроса, такого как:
"""SELECT fileName, mimeType, size, contentId, contentUri, encoding FROM Attachment WHERE messageKey = ${msgKey}"""
АДРЕСА
Сценарий предоставляет один служебный метод для преобразования списка с указанием строки, в котором записи разделены SOH
символом (ASCII 1), а адреса электронной почты и соответствующие им отображаемые имена разделены STX
символом (ASCII 2).
Обработка состоит из итерации строк набора результатов таблицы сообщений, для каждой строки тело сообщения извлекается из отдельной базы данных sqlite, а затем создается JavaMail MimeMessage и выводится в файл.
ПОИСК ПРОБЛЕМЫ
Сценарий не может вызвать потерю данных на вашем устройстве, так как он работает с резервной копией. Если вы хотите сначала поэкспериментировать, вы можете установить ограничение (например LIMIT 10
) для первого запроса SELECT, чтобы уменьшить количество получаемых им сообщений.
Кроме того, простой способ просмотра выходных данных, например, в Groovy Console, заключается в использовании msg.writeTo(System.out)
вместо создания файла .eml.
ПОЛУЧИТЬ СЦЕНАРИЙ
Обычные заявления об отказе от ответственности распространяются на то, что скрипт не имеет гарантии, поддержки и т. Д. — получите его на GitHub: https://gist.github.com/rbramley/65261127dfb857b03bb6