Шрифт
(Не)оригинальное поздравление на 8 марта
Play

(Не)оригинальное поздравление на 8 марта

Я думаю, многие в детстве рисовали самодельные открытки для мам, сестер, бабушек. В школе так уж точно. Однако, после определенного возраста увлечение подобными вещами остается уделом очень маленького числа людей. Вряд ли вы хоть раз дарили что-то подобное своей девушке/жене. А ведь им наверняка понравится, психология и всё такое .

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

Дисклеймер

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

Идея и анализ задачи

Итак, для успешного, яркого и запоминающегося поздравления нужен, что? Правильно, Вау-эффект! Для этого следует сделать все незаметно для объекта поздравления, и добавить немного программистской магии. На мое счастье, в Android её хватает, как белой так и черной.

Представьте, вы написали и установили приложение в телефон к жертве виновнику всей затеи, а потом что? "Запусти, пожалуйста, вон то приложение" или "Дай телефон на секунду… Смотри!". Вау-эффекта не будет, даже не надейтесь. Поэтому самое лучшее, что пришло мне в голову — предустановить приложение (хотел замаскировать, но не успел, да и не пришлось, в общем-то), а в момент Х запустить его удаленно, с помощью магии, удивив ничего не подозревающего маггла.

Начинку открытки составляют памятные фотографии и короткие поздравления в стиле "желаю оставаться красивой, умной, доброй, счастья, здоровья". Набор индивидуальный, мало ли что вашему поздравляемому нравится.

Уже на стадии проектирования я совершил свою первую и самую критическую ошибку. Я решил, что успею за короткий срок сделать красивую открытку с кучей анимаций, не имея никакого опыта работы с этой самой анимацией и её оптимизацией. Не скажу, что визуально получилось плохо, но и без той анимации, что я добавил, всё было бы превосходно, и проблем стало б меньше.

Инструментарий

Для работы нам понадобятся:

  • Любая IDE для андроид-разработки
  • Фото жертвы и стоковые изображения для открытки
  • Google Firebase либо Google Cloud Firestore
  • Утилита curl либо любое другое средство отправки POST-запросов
Реализация

Для создания анимаций я воспользовался библиотекой WowoViewPager. Не советую ее использовать для подобных проектов.

Библиотека позволяет создавать анимированные слайды, работающие через ViewPager. Перелистывание по умолчанию осуществляется свайпами. Можно полностью настроить движение любых view-элементов, скорость и тип анимации. Поддерживаются gif и svg анимации.

Основным минусом, на мой взгляд, является требование все элементы хранить в одном xml-файле. Библиотека, судя по всему, не рассчитана на большое количество слайдов (в оригинальном примере их всего максимум 4). В моем случае 21 слайд и 16 jpeg-фото вызвало "отжирание" более 200 Мб памяти.

Расписывать процесс создания анимации я не стану, поскольку у каждого программиста свои костыли и велосипеды. Хочу лишь упомянуть, что для сокрытия тулбара и панели уведомлений можно воспользоваться флагами

В процессе работы с библиотекой анимирования меня поджидал несколько неожиданный трабл. Классическая формула центрирования по абсолютным координатам

не работала; опытным путем я выяснил, что нужный эффект дает абсолютно аналогичная формула:

Однако, в одном исключительном случае, фотография центрировалась только по формуле

При том, что разница в размерах составляла всего 3 пикселя по оси Y (!sic)

Именно так я себя чувствовал в тот момент. Мне неизвестно, с чем это связано — с особенностями координат в андроид, багами библиотеки, или моими корявыми руками. Может быть, в комментариях кто-то сталкивался с аналогичными проблемами.

После реализации самой открытки, настал черед магии. Прежде всего, создадим новый проект в Firebase Console. При создании проекта укажите название и страну. Следующим шагом, нужно подключить Firebase к написанной открытке. На выбор есть два варианта: Realtime Database и Cloud Firestore. В этом конкретном случае разницы нет, со своей задачей оба сервиса справляются прекрасно. В чем глобальная разница — я не знаю. Я использовал Cloud Firestore. По ссылке есть официальный туториал.

1) Укажите зависимости Gradle на уровне проекта

2) Укажите зависимости Gradle на уровне модуля app. Сразу учтем зависимость для получения push-уведомлений

3) Создайте и добавьте в манифест сервис для получения токена Firebase и дальнейшей записи в Cloud Firestore. Токен будет нам нужен для удаленного запуска приложения. Замечу, что у меня нет функции удаления старого токена из базы, не успел реализовать. Если вам потребуется, пример есть выше по ссылке.

4) Создаем и добавляем в манифест сервис для получения push-уведомлений от Firebase. Ранее мы уже добавили зависимость в Gradle.

Я не буду объяснять принципы создания и работы push-уведомлений в android. Для этого есть профильные сайты. Приведенный пример должен сработать в большинстве смартфонов с андроид 4.2.2 и выше.

Дописывал открытку я уже ранним утром 8 марта. Катастрофически не успевал, до будильника оставались считанные минуты, а я еще не проверял, как работает приложение в смартфоне девушки (у нас разные разрешения экрана). У меня был доступ по отпечатку пальца. При настройке отладки по USB потребовалась перезагрузка. После перезагрузки оказалось, что я не помню графический пароль. В ту секунду я почувствовал себя полным дебилом. В шаге от финиша я не мог проверить работу приложения (facepalm). Пришлось будить девушку и заставить ее разблокировать, благо, спросонья она ничего не соображала и ввела пароль на автомате.

Финальная стадия разработки. Осталось только подготовить запрос для отправки в Firebase для инициализации push-уведомления.

Важный момент: Firebase позволяет отправлять уведомление двумя способами: простым и кастомизируемым. Простой вариант подразумевает отправку только двух полей — заголовка и текста уведомления. Такой тип сообщения можно отправить прямо из консоли Firebase, однако уведомление будет получено только в том случае, если есть работающий процесс приложения. Он нам не подходит, поскольку приложение никак не должно проявлять себя до момента X.

Кастомизируемый вариант позволяет отправлять сообщения в json-формате объемом до 4Кб с любым содержанием. Такое сообщение придет, даже если сообщение очищено из стека ранее запущенных приложений. (Однако, если приложение и его сервисы были убиты каким-нибудь чистильщиком памяти, уведомление не придет до момента перезапуска приложения). Минус кастомизируемого способа в том, что его можно отправить только POST-запросом к серверам Firebase.

Для отправки запроса я воспользовался утилитой curl. Поскольку код писался из-под Linux Mint, мне достаточно было запустить терминал. Вы можете использовать любой другой инструмент, например Postman.

"Authorization: key=<ваш ключ>" Ключ можно посмотреть в настройках проекта Firebase (нажать на шестеренку)

📎📎📎📎📎📎📎📎📎📎