Я думаю, многие в детстве рисовали самодельные открытки для мам, сестер, бабушек. В школе так уж точно. Однако, после определенного возраста увлечение подобными вещами остается уделом очень маленького числа людей. Вряд ли вы хоть раз дарили что-то подобное своей девушке/жене. А ведь им наверняка понравится, психология и всё такое. Естественно, мы, программисты, народ плечистый, нас не заманишь бумагой шелковистой, поэтому открытку делать я решил в виде мобильного приложения, а не клеить на коленке из картона и цветной бумаги. Благо, смартфоны сейчас даже у бездомных есть. Я ни коим образом не претендую на качество программного кода, представленного в посте, на оригинальность идеи либо ее реализации.
Я не несу ответственности за ваши воспаленные от ужасного кода глаза и оскорбление чувств программистов.
Я понимаю, что большинство принятых мной решений при разработке были неидальными, и надеюсь, что данный пост убережет других разработчиков от аналогичных промахов Итак, для успешного, яркого и запоминающегося поздравления нужен, что? Правильно, Вау-эффект! Для этого следует сделать все незаметно для объекта поздравления, и добавить немного программистской магии. На мое счастье, в Android её хватает, как белой так и черной. Представьте, вы написали и установили приложение в телефон к жертве виновнику всей затеи, а потом что? "Запусти, пожалуйста, вон то приложение" или "Дай телефон на секунду… Смотри!". Вау-эффекта не будет, даже не надейтесь.
Поэтому самое лучшее, что пришло мне в голову — предустановить приложение (хотел замаскировать, но не успел, да и не пришлось, в общем-то), а в момент Х запустить его удаленно, с помощью магии, удивив ничего не подозревающего маггла. Начинку открытки составляют памятные фотографии и короткие поздравления в стиле "желаю оставаться красивой, умной, доброй, счастья, здоровья". Набор индивидуальный, мало ли что вашему поздравляемому нравится. Уже на стадии проектирования я совершил свою первую и самую критическую ошибку. Я решил, что успею за короткий срок сделать красивую открытку с кучей анимаций, не имея никакого опыта работы с этой самой анимацией и её оптимизацией. Не скажу, что визуально получилось плохо, но и без той анимации, что я добавил, всё было бы превосходно, и проблем стало б меньше. Для работы нам понадобятся: Для создания анимаций я воспользовался библиотекой 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 (нажать на шестеренку) "Content-Type: application/json"  Теперь остается только в нужный момент отправить запрос! Девушке понравилось, вау-эффект был достигнут :) Android Middle Developer