Рабочих способов оплатить iCloud и другой контент или услуги для пользователей iPhone становится все меньше. Один из таких — подарочные карты, с помощью которых можно приобретать приложения в App Store, донатить в играх и оплачивать подписки. В этой статье мы в редакции GGSel.net расскажем как их приобрести и активировать на вашем устройстве.
Покупка и активация подарочных карт
Для RU-региона существуют карты номиналом 500–10000 рублей.
На главной торговой площадки GGSel находим раздел Apple, далее выбираем iTunes и попадаем на страницу с подарочными картами, которые можно отсортировать по региону аккаунта. Ищем интересующий нас товар, помимо цены рекомендуем обращать внимание на продажи, отзывы и рейтинг продавца.
Внимательно читаем описание и оплачиваем товар.
После завершения транзакции, мы получим 16-значный код на указанную при оплате почту.
На своем устройстве заходим в App Store, нажимаем на иконку в правом верхнем углу.
Жмем «Погасить подарочную карту или код». Если надпись не отображается, входим в учетную запись с помощью идентификатора Apple ID.
Для каждого региона свои карты. Коды, предназначенные для Турции, не получится активировать с российского аккаунта.
Переходите на GGSel.net — торговую площадку, где вы найдете игры для ПК и консолей, DLC, сможете пополнить баланс популярных игровых и неигровых сервисов, купить и продать игровой аккаунт. И все это — по выгодным ценам!
Друзья! Много ли платформ вы знаете, где для написания пользовательских приложений используется стек… веб-технологий, причём это единственный нативный способ писать программы? Услышав о HTML5 + CSS + JS, на ум приходит разве что webOS — которая используется в современных телевизорах от LG (а ранее использовалась ещё и в Palm Pre — уникальный смартфон, единственный в своём роде), а олды вспомнят ещё и про FireFox OS, в которой вся оболочка (включая многозадачность, шторку уведомлений и все приложения) также была реализована на JS. Но ни webOS, ни FFOS в своё время не суждено было стать массовыми ОС на смартфонах: сказывались аппаратные ограничения устройств, да и проблемы с портированием уже существующих приложений с других платформ (например, игр). Однако несколько лет назад, проект FireFox OS был форкнут и на свет появилась новая система, предназначенная для… умных кнопочных телефонов с LTE! И имя ей — KaiOS. Вероятно, многие мои читатели слышали о ней и о новых умных кнопочниках от Nokia. Но что из себя представляет система под капотом и чем она может быть интересна гику? Читайте в новом материале!
❯ Предыстория
В наше время, стек веб-технологий стал чуть ли не вторым по важности для разработки клиентских приложений. С появлением PWA и модных MVC-фреймворков, а также таких проектов, как Electron, визуальная составляющая многих приложений радикально поменялась: стало возможным реализовывать кастомный, гибкий и адаптивный интерфейс с поддержкой тем и анимаций буквально в несколько строчек кода. Такой подход значительно упрощает и удешевляет разработку клиентских приложений для популярных сервисов: например, «набросать» своё приложение для MP3-плеера может даже зелёный джун, который только начал писать код.
Первой попыткой сделать PWA-приложения «нативными» был, как ни странно, первый iPhone. iOS 1.0, которая в те годы ещё называлась iPhone OS, не имела AppStore и поддержки нативных ipa-приложений и предлагала просто выносить значки нужных сайтов на рабочий стол. При этом возможность отображения полноценных десктопных сайтов была одна из самых сильных сторон iPhone в те годы! Как показала практика, Стив Джобс немного поспешил с интеграцией PWA на смартфонах и в iOS 2.0 уже был добавлен AppStore, куда разработчики могли публиковать нативные и быстрые приложения!
Alcatel OneTouch Fire E — один из двух смартфонов на FireFox OS в моей коллекции!
Но всё это итак знакомо многим моим читателям: подписчики часто жалуются на то, что современные приложения жиреют и лагают, а ещё тащат за собой целый CEF и миллион npm-пакетов из-за чего даже какие-то простые приложения начинают требовать слишком большие ресурсы. Но кто бы мог подумать, что веб-стек найдет своё место на… кнопочных мобильниках! Казалось бы, дешевые кнопочники не имеют ресурсов для запуска полноценного браузера, их главная задача — именно звонить. Но ведь на складах всё ещё лежат, полагаю, целые стеллажи бюджетных смартфонных процессоров 10-летней давности, которые вполне способы запустить Android… смекаете, к чему я? :)
KaiOS появилась как форк и концептуальное продолжение провалившейся FireFox OS: система от Mozilla предлагала множество интересных концепций и шустро работала даже на очень-очень бюджетных смартфонах, несмотря на веб-направленность. Минимальные требования системы были скромными: ОС шустро работала на бюджетном ZTE Open с 256Мб ОЗУ и чипсетом MSM7225A из 2012 года. FireFox OS работала на ядре Linux, основой был браузерный движок Gecko, а поскольку Mozilla, полагаю, не смогла заручиться поддержкой вендоров чипсетов и хотела, чтобы систему мог портировать на своё устройство любой желающий, для взаимодействия с железом устройства система использовала драйвера для… Android! Поскольку Gecko собирался с использованием стандартного libc, а драйверы использовали bionic, FireFox OS активно использовала библиотеку libHybris, что позволяло портировать систему на уже существующие смартфоны с любыми чипсетами.
LG fx0 — редчайший смартфон на FireFox OS. Правда на фото он на Android :)
Идея системы простая: формально, это один большой браузер (оболочка Gaia), который при запуске приложений создаёт ещё маленькие «браузеры» (элемент webview, это не iframe). Плюсы такого подхода очевидны: отказоустойчивость (потенциально, весь рестарт Gaia — это WebView.Refresh. В случае Android — это закрытие всех приложений и перезапуск app_process), безопасность (нельзя вызвать Private API), лёгкость отладки и малый вес конечных приложений (причём вес — основной критерий для публикации приложения в официальном магазине KaiOS, пакет до 20Мб). Стоит ли говорить о том, что приложение на такое устройство сможет написать даже ребенок, а игру в стиле «Змейки» можно реализовать за пару часов? Порог вхождения значительно ниже даже чем на Android!
В основном, KaiOS разрабатывалась как система, которая должна вывести кнопочные телефоны из разряда «просто-звонилок» и позволить использовать на привычных устройствах современные мессенджеры и различные сервисы (например, тот-же YouTube). Пожалуй, это отнюдь не «прокачанные бабушкофоны», как некоторые могут подумать, а перспективные девайсы с современным железом (поддержка дисплеев высокого разрешения, 3D GPU, LTE) и заделом на будущее, пусть пока и без крутых девайсов в стиле Nokia N-серии. Концепция умных кнопочников не ограничена KaiOS: выходят различные девайсы и на Android, об одном из таких смартфонов я даже писал две отдельные статьи с обзором и моддингом.
Сейчас на барахолках можно найти дешевые девайсы на KaiOS до 2х тысяч рублей, правда свежие Nokia ценятся обычно выше. Мне же достался в подарок Nobby 240 LTE от моего читателя jameskod007, за что ему большое спасибо! Чем такие девайсы могут быть интересны гику? Давайте посмотрим!
❯ Что «под капотом»?
Под капотом у устройств на KaiOS трудятся старые и такие знакомые многим читателям бюджетные чипсеты, как MediaTek MT6572 (использовался в смартфонах до 3-4х тысяч рублей в 2014-2015), SpreadTrum SC7731E (наследник SC7731 2014 года с другим GPU) и Qualcomm 205 (судя по всему, наследник Snapdragon 200 — популярного чипсета 2014-2015 года, который использовался, например, в Lumia 520). Само собой, это позитивно сказывается на цене устройства: зачем в девайс с дисплеем 240x320 ставить 800'ый Snapdragon? :)
Значительным плюсом подобных устройств является простота обслуживания. По правде сказать, здесь и ломаться то особо нечему: дисплей относительно надежно защищен от внешнего влияния с помощью воздушной прослойки и защитного стекла, а элементная база смартфона весьма маленькая и «не ломучая». Разбирается смартфон просто: достаточно лишь открутить несколько винтов с обратной стороны корпуса и расщелкнуть телефон пластиковой картой. Что забавно — такие формы корпусов будто «унифицированы» среди производителей дешевых телефонов, никто, почему-то, не экспериментирует с корпусами в стиле а-ля Nokia N-серий.
Перед нашим взором открывается плата. К сожалению, я пока не видел на кнопочных смартфонах UART в открытом виде, иначе давно бы реализовал что-то типа такого. На плате мы можем заметить, что LTE-версия Nobby 240 работает на достаточно свежем Spreadtrum SC9820E с двумя 64-битными ARMv8 ядрами Cortex-A53 на частоте 1.3ГГц и GPU Mali T820 MP1, а также с LTE модемом. Чип выполнен по техпроцессу 28Нм, максимальное разрешение дисплея — 480x854 (т. е. DSI матрицы всё таки поддерживаются, параллельно с DBI). Весьма шустрый чипсет для девайса такого класса, его едва ли можно назвать «бабушкофонским», подобные характеристики были флагманскими для смартфонов ~2012 года. Для сравнения — простые кнопочники все еще работают на ARMv5 ядрах на частоте около 200-300МГц.
Дисплей припаян и приклеен к плате, подключен к процессору при помощи 16-битного протокола 8080, а не MIPI DSI, как в современных смартфонах. Его разрешение — классические 240x320. Поиск его замены скорее всего не составит труда, хотя точная модель контроллера мне пока неизвестна (предполагаю, либо ILI9341/ILI9325, либо ST7731, либо так любимый китайцами GC9306).
А вот клавиатура — болячка таких девайсов. По каким-то причинам, пластиковые толкатели кнопок очень быстро изнашиваются и кнопки начинают дребезжать (нажиматься несколько раз одновременно), либо не прожиматься. Это очень обидно и неприятно, но быстрофикс есть — напечатать крохотные проставки на 3D-принтере.
В остальном, конструктивно девайс вполне хорош и надежен. Корпус почти не поддается трещинам и царапкам, при аппаратных болячек его относительно легко диагностировать. Ну не замечательно ли? Давайте глянем, чем интересен девайс с точки зрения веб-разработчика!
❯ Веб-разработка
Для разработки нам потребуется совсем немного: любой текстовый редактор (хоть блокнот), FireFox 59 и platform-tools с adb для Android. В первую очередь, на смартфоне необходимо включить режим отладки, который активируется набором кода *#*#33284#*#* (DEBUG) в номеронабирателе. После этого, в шторке уведомлений появится значок «жука». На некоторых устройствах, режим отладки активируется прямо в настройках. После этого, смартфон будет виден через adb и мы сможем дебажить на нем свои приложения!
Теперь нам необходимо накатить «древний» FireFox 59, это последняя версия с поддержкой WebIDE и возможностью деплоя под FireFox OS от 2018 года. WebIDE — это дебаггер и менеджер приложений для экосистемы Mozilla, активируется с помощью хоткея Shift + F8. Не забудьте отключить авто-обновление в настройках браузера!
После этого, нам необходимо связать WebIDE с нашим смартфоном с помощью «Remote Runtime». Однако перед этим, нам необходимо форварднуть adb-сокет с помощью команды:
После этого, мы жмем «Remote Runtime» и «Runtime Info», дабы получить информацию о нашем девайсе и убедится что всё нормально:
Создаём новое приложение и вперед творить! По правде сказать, я практически не знаю, каких приложений особо не хватает на KaiOS. ВК частично есть, YouTube почти полноценный, WhatsApp тоже реализован… не хватает разве что Telegram? Но я лично не смог бы полноценно чатится с телефона такого типа (и дело не в форм-факторе), поэтому я решил запилить ради прикола приложение-виджет для просмотра погоды в моём городе :)
У каждого приложения есть манифест, который объявляет используемые разрешения, значки и различные данные, необходимые для публикации приложения в магазине приложений. Существует три типа приложений: «web» (Hosted web apps — или, фактически, PWA), «privileged», и «certified» (приложения с доступом к критичным функциям смартфона типа СМС. В привилегерованном режиме, приложения могут обращаться к службам KaiOS, таким, как например Bluetooth и настройках сети.
Сначала я сверстал простенький интерфейс для приложения. Логика простая: поскольку это приложение-виджет, при его запуске отображается прелоадер (анимация загрузки), а как только данные загружены — программа показывает блок content и скрывает анимацию загрузки. Никаких фреймворков типа React я тащить не стал, но для более сложных приложений придётся продумывать более сложную логику для реализации диалогов.
Не ругайте за <center>! Я не веб-разработчик, адаптивные верстки делать не умею :))
Фетчить данные мы будем с OpenWeatherMap, хотя можно попросить доступ к API и у Gismeteo. Формат запросов у API очень простой — фетчим данные о погоде в локации относительно координат широты/долготы, при этом встроенный API для геокодинга поможет найти координаты того или иного района в городе. Делаем вот такой GET-запрос:
queryWeather(onReady) { var req = new XMLHttpRequest(); req.onreadystatechange = () => { if(req.readyState == XMLHttpRequest.DONE) { var json = JSON.parse(req.responseText);
Вся логика программы уложилась в 85 строк кода. Преимущества веб-подхода и «жабоскрипта» при грамотном использовании очевидны, согласитесь? Опять-же повторюсь, я не веб-разработчик, мои познания в JS ограничиваются «олдовым» стилем уровня начала-середины 2010х годов, я, вон, даже jquery тащить не стал.
❯ Рут
Изначально материал должен был состоять из двух частей: обзор «клиентской» части девайса с приложениями на веб-стеке и выкидывание B2G, дабы реализовать нечто подобное одной из моих более ранних статей. Но вендор смартфона подложил «свинью»: у устройства залочен загрузчик и разблокировать его штатными средствами невозможно. Вообще, инфраструктура FireFox OS имеет много общего с Android изнутри, так что я попробовал с помощью патчера magisk'а пропатчить бут и залить в него su… но увы, девайс валился на верификации signed-образа и отказывался прошивать раздел! За это жирнющий минус вендору.
Если хотите взять подобный девайс для моддинга и экспериментов, присмотритесь к девайсам на Android, или KaiOS на базе MT6572/SC7731 — те обычно разблокированы с завода. Например, год назад я сделал первую кастомную прошивку для Android-кнопочника и написал для него кастомный лаунчер.
Я лично буду очень рад, если ЕС обяжет вендоров смартфонов давать возможность заводской разлочки загрузчиков, иначе это ущемление в правах тех людей, которые покупают смартфон с изначально открытой системой!
❯ Заключение
Вот такой материал про KaiOS у нас с вами получился. Теперь вы и сами знаете, что девайс может быть интересен не только как «бабушкофон» или продвинутая звонилка, но и как платформа для реализации каких-то собственных прикольных фишек :)
Какие применения могут быть у такого девайса? Да самые разные! Например:
Маленький фронтэнд для данных с микроконтроллера: тут уже и дисплейчик небольшой есть, и кнопки, а также GPU, если нужно показывать какие-то данные в 3D. Почему-бы и нет?
BT-плеер в машину: пилим фронтэнд к ВК Музыке/Спотику или еще какому-либо сервису, коннектим по BT и получаем миниатюрный автомобильный самодостаточный плеер, который еще и аккумулятор относительно долго держит :)
Часы с погодой: частичную реализацию этого проекта я уже представил в статье. Собственно, а почему-бы и нет? Многие смартфоны от Motorola и Sony с док-станциями сейчас так и используют. Почему бы не заюзать для этого и девайс на KaiOS?
Надеюсь вам было интересно! Пишите своё мнение, есть ли перспективы у смартфонов на KaiOS? Также у меня есть свой Telegram-канал, куда я выкладываю бэкстейдж со статей, различные заметки о ремонте, моддинге и программировании под девайсы прошлых лет и вовремя публикую линки на новые статьи. Подписывайтесь!
Насчёт машины
Друзья! Те читатели, которые подписаны на меня наверняка знают о том, что я коплю на покупку ТАЗика, дабы реализовать интересный проект с разработкой самопального ГУ "из того что было" по самому дешману. Сейчас у меня есть чуть более 100.000 рублей, из которых 8.000 рублей - донаты читателей! В Ейске, на юге, за такие деньги купить относительно живой по мотору и, что немаловажно, с +- целым дном тазик сложновато. Я даже Волгу и Москвич рассматривал как вариант, но Волга ушла, а у Москвича мотор не родной. Если вам нравятся мои статьи и вы хотите помочь материально будущему проекту - с помощью формы ниже можно помочь проспонсировать проект!
Если вы вдруг живете в Ейске или в 50км от Ейска и вы или ваши знакомые продают относительно живой ТАЗик (кроме классики, критерии - на ходу, чистые документы и не совсем панорамное дно. Машинка может быть помята, с плохим ЛКП и конечно другими косяками, машина ведь не новая!) - пишите в ТГ @monobogdan!
Статья подготовлена при активной финансовой поддержке TimeWeb Cloud. Не стесняйтесь пользоваться их услугами, если вам нужен VDS, выделенный сервер или иные облачные услуги. Подписывайтесь на меня и @Timeweb.Cloud, дабы не пропускать интересные технические статьи каждую неделю!
С момента выхода первой части статьи из рубрики «сам себе экосистема» прошёл уже практически год! За это время, мы успели с вами реализовать клиенты VK и YouTube, которые работают на Android 2.2+, а также на Windows Phone 8, написать небольшую 2D-игру с нуля весом менее 1Мб, которая работает практически везде и довести существующее приложение до ума, дабы оно работало даже на смартфоне с дисплеем 240x320! Но на дворе 2024 год, люди стремительно переходят из соц. сетей в продвинутые мессенджеры и уже сложно себе представить современного человека, который не пользовался бы «телегой» или даже «вайбером» в качестве основного средства общения. Поэтому я решил реализовать клиент Telegram на смартфоне 14-летней давности на базе официальной реализации MTProto от команды Telegram — TDLib. Сегодня мы с вами: узнаем новые причины мотивации вернуть в строй смартфоны прошлых лет, напишем на C# реле-сервер, который обрабатывает пакеты MTProto и кодирует их в простой текстовый формат датасетов, который можно моментально обработать даже при нестабильном GPRS-соединении на 21-летнем Siemens C60, а также узнаем о разработке миниатюрных Android-приложений на базе «голого» API-системы, которые не тянут за собой никаких зависимостей, в том числе и AppCompat/androidx. Интересно? Тогда жду вас под катом!
На дворе уже стукнул 2024 год, современные смартфоны предлагают какие-то немыслимые мощности относительно тех, которые когда-то были в первых Android-девайсах. Сейчас за сотню баксов можно купить смартфон с хорошей 1080p IPS-матрицей, 4Гб ОЗУ и 8-ядерным шустрым чипсетом, который вполне способен плавно тянуть даже стремительно «жиреющие» на ресурсы клиенты социальных сетей, банков и прочие необходимые в повседневной жизни приложения. И казалось бы: всё хорошо, покупай себе редмик раз в год или айфон раз в несколько лет и наслаждайся всеми прелестями работы современных приложений…
Для многих людей смартфон — это лишь инструмент, повседневный компаньон, который помогает облегчить выполнение каких-то задач. Им совершенно не важно, как он выглядит, как ощущается в руках, какой у него дисплей и железо «под капотом», лишь бы работал да и нормально. Но есть и другая категория людей, для которых телефоны, смартфоны и любые портативные гаджеты — это не просто утилитарный девайс, а настоящее инженерное произведение искусства, с которого буквально сдувают пылинки и стараются до последнего пользоваться ими как повседневными устройствами. Хотите пример? Смотрите ниже:
Фактически, среди современных смартфонов по сути и нет представителей такого нынче вымершего форм-фактора, как сайдслайдеры с физической QWERTY-клавиатурой, боковые раскладушки с двумя дисплеями и даже из QWERTY-моноблоков есть только смартфоны от Unihertz. Даже среди моноблоков с тачскринами нет никакого разнообразия, лишь без-рамочные одинаковые девайсы за исключением устройств от Sony.
Galaxy S Plus
Раньше меня часто спрашивали, мол, да как ты вообще можешь пользоваться смартфоном 10-летней давности, на котором давно нет официальных клиентов популярных сервисов и только недавно, с развитием блога, мне перестали задавать этот вопрос, поняв, что это бесполезно — ведь это дело принципа и порыва энтузиазма! Смотрите сами: у нас уже есть простенькие, но вполне рабочие клиенты ВК, YouTube, сейчас я допиливаю клиент «Сбера» на СМСках, реализую карты OpenStreetMap (правда пока без адекватной навигации), а в будущем планирую написать приложение для мониторинга погоды и трекинга посылок. Кроме того, в рамках этой статьи мы реализуем с вами клиент Telegram: так чем же это не функционал современного смартфона?
Но хорошо, с функционалом разобрались, однако для многих читателей слова «старый смартфон» это прямые синонимы «тормозной смартфон», мол «фуу, да как можно пользоваться этим тормозным кирпичом, он же лагает в последней версии моей ВКшечки!». Но давайте поставим вопрос ребром: может, это не столько девайсы немощные, сколько сами приложения, с кодовой базой, которая тянется более 10 лет, откровенно жиреют, обрастают костылями и хаками после далеко не одного поколения программистов, которые над ними работали? :) Один, вот, предпочитал пользоваться чистым AppCompat'ом, другой решил притащить зависимость, которая, например, оптимизирует виртуализацию ListView, третий решил заменить всю сериализацию Json со встроенных классов в Android на что-то стороннее и реализовал это костылями и вот так, по чуть-чуть изначально оптимальный и шустрый код превращается в неповоротливое УГ, которое не рефакторили кучу лет.
На видео Galaxy Pocket Neo — очень дешёвый Android-смартфон из 2011 года с 1-ядерным чипсетом на ~800МГц и 256Мб ОЗУ. При этом всём, Android софтварно рисует все анимации на процессоре, без участия GPU.
А значит у стареньких девайсов всё равно есть шанс быть полезными и стать полноценными повседневными смартфонами даже спустя более чем десять лет после выхода! И в сегодняшнем материале, я вам расскажу об особенностях разработки самопального клиента Telegram с собственным прокси-сервером, которое концептуально допускает реализацию даже на кнопочном Siemens C60 2003 года. Как? Читаем ниже!
❯ Принцип работы
В отличии от ВК (который разрабатывали те же самые люди, что и Telegram), API которого построено на базе REST-запросов и концепции Longpolling'а для моментального получения событий с сервера, Telegram построен на базе собственного протокола под названием MTProto, который может работать поверх любого «транспорта» (протокола нижнего уровня) — TCP, HTTP, WebSocket и т.п. Сам по себе MTProto в современном виде, разработка прожженного математика Николая Дурова и его команды — протокол относительно сложный для реализации «на коленке» и в первую очередь требует довольно серьезного понимания принципов работы современной криптографии, да и документирован он всё ещё не особо хорошо. Кроме того, у MTProto весьма интересный бинарный формат пакетов, эдакий велосипед Protobuf. В долгосрочной перспективе поддерживать свой велосипед MTProto может быть весьма проблематично, учитывая не самую лучшую документацию.
Но городить велосипед и не нужно, поскольку у команды Telegram есть официальная реализация MTProto — библиотека TDLib, которая инкапсулирует в себе не только детали реализации протокола, но и сетевой ввод/вывод и выбор транспорта, хранение базы данных сообщений и авторизации, автоматическую загрузку фото и видео, конвертация объектов из бинарного формата MTProto в JSON и полная многопоточность и частичная потоко-безопасность. С одной стороны это плюс — уже готовое решение для реализации клиента на новой поддерживаемой платформе, где есть OpenSSL (можно статически слинковать), zlib (линкуется статически), сокеты и файловый ввод/вывод, а также довольно неплохой механизм JSON-based API, которое позволяет использовать библиотеку в любом языке, который поддерживает вызов C-функций, а с другой и минус — библиотека довольно много весит, в одиночку прибавляя ~20Мб веса приложения для каждой архитектуры, у неё течёт память и у нее странный механизм получения данных с сервера (например, нельзя ответить на сообщение, зная его ID, если сообщение предварительно не загружено, при том что на сервере весь ответ — это просто ID, на какое сообщение прилетел ответ).
Понятное дело, что на стареньком смартфоне использовать оригинальный TDLib будет проблематичным — даже если собрать либы современным NDK и запилить JNI-интерфейс, библиотека «жрёт» много ОЗУ (20-100Мб «вхолостую», в зависимости от числа диалогов и частоты прилетающих событий, плюс со временем течет до 1-2Гб, если не использовать базу данных сообщений. Скорее всего, это косяк в реализации пулов, объекты из которых выгружаются при сбросе в базу, но не выгружаются при высоком потреблении ОЗУ) и уж тем-более TDLib не запустить на любимых кнопочных Java-сонериках! Поэтому я решил написать прокси-сервер, который отправляет команды, слушает ивенты TDLib и предоставляет REST-like API для клиентских программ, которые просто вызывают какой-либо метод, а в ответ получают простой и короткий строковой датасет только с необходимыми полями, весом до 10Кб (что позволяет его быстро загрузить даже с GPRS-интернетом), который можно быстро распарсить даже на преусловутом Siemens C60!
К сожалению, поскольку TDLib прожорлив, я не смогу захостить на своём сервере инстансы для читателей, которые хотят поюзать приложение, поэтому вам придется ставить и запускать сервер на своём VDS/компьютере с белым IP/роутере, если под него есть .NET Core :)
Клиентом же будет выступать Android-смартфон, где приложение будет фронтэндом данных с сервера. Ничего сложного на первое время нет: первое окно — это список диалогов, второе окно — список сообщений в диалоге + поле для написания сообщения, третье окно — информация о пользователе. Всё это я реализовал за три дня не-напряжной работы «на коленке».
Давайте же перейдем к реализации сервера!
❯ Прокси-сервер
Сервер я решил писать на C#, поскольку у .NET Core сейчас всё очень хорошо с кроссплатформенностью и производительностью. Его можно даже на Raspberry Pi запустить :)
Итак, какая-же архитектура такого сервера может быть? Программа инициализирует TDLib, начинает слушать её события в отдельном потоке, пока в основном потоке крутится HTTP-сервер, который обрабатывает каждый отдельный запрос с клиентского приложения. Почему синхронно? Потому что TDLib фактически не возвращает никаких идентификаторов для возвращаемых датасетов, дабы их можно было отличить друг от друга. Приведу пример: у нас есть метод getChatHistory, который возвращает n-сообщений. При этом TDLib сам определяет, сколько хочет сообщений вернуть (и в первый вызов возвращает одно сообщение вне зависимости от настрое и отправляем пакет message n-раз. При этом в пакете message нет какого-либо ID, который позволял бы ассоциировать текущий объект с какой-либо операцией. Увы!
Начинаем с коммуникации с TDLib. Для работы с библиотекой, мы будем использовать json-интерфейс. Для .NET есть биндинги через C++/CLI, но в таком случае, сервер не будет работать на Linux. Для работы с библиотекой хватит лишь три функции: CreateClientID, которая аллокейтит новый инстанс клиента, Send, которая асинхронно отправляет JSON-объект с командой, которую затем обработает TDLib и Receive, которая ждёт N-секунд и возвращает в виде ASCII-строки (!) JSON-объект с описанием события или данными после одного из запросов. За это у нас отвечает класс TDLibInterface, который объявляет PInvoke-методы для вызова нативных методов из библиотеки. .NET Core сам подгрузит библиотеку tdjson (причём на Linux он добавит ей префикс а-ля libtdjson.so, а на Windows загрузит tdjson.dll) и сам разберется с маршаллингом аргументов функций: например, string автоматически преобразует в const char*. Тем не менее, с const char* возвратами нужно быть аккуратнее — у меня был SIGSEGV, пока я ручками не конвертировал их в обычную строку.
З.Ы: На Пикабу нет отдельного тега для кода, а вставить листинги картинками я не могу из-за ограничения на 25 медиаэлементов. Так что листинги будут совсем без табов, но алгоритм их работы понять можно :)
Позволю себе чуточку критики в сторону TDLib. Во первых, почему нет s-версии функции с возможностью указать длину входной строки, а tdjson полагается исключительно на \0 в конце строки? Во вторых, почему const char*, а не wchar_t*? Сейчас юникод во входной строке приходится escape'ами превращать в \u-последовательности. После этого, нам нужно написать обёртку над TDLib, которая будет вызывать для зарегистрированных событий специальные функции, называемые коллбэками. При этом закомментированный WriteLine снизу — это «дебаг» для того, чтобы узнать названия неизвестных мне ивентов :)
В каждом объекте, полученном с помощью receive, есть поле "@type", которое содержит в себе имя класса возвращаемого объекта. Первый же вопрос от читателей — почему я использую JObject с ручным дерганьем нужных полей и вручную пишу JSON в виде строковых литералов вместо нормальной сериализации/десериализации? Ответ прост: во-первых, для актуализации Data-классов придется писать кодогенератор из TL-схемы, а во-вторых иногда TDLib может возвращать немного разные объекты в JSON, из-за чего приходится мудрить с атрибутами на этих самых Data-классах, иначе десериализатор выбросит исключение. Это решается нормальными юнит-тестами на всех вариантах данных, но зачем себе в колени стрелять, если нужен конкретный фиксированный функционал и лишь малое число от всех полей, возвращаемых TDLib?
string recv = NativeInterface.Receive(10.0d);
if (recv != null) { JObject json = JObject.Parse(recv);
if (!handlers.ContainsKey(type)) { //Console.WriteLine("Unknown event type: {0}", type); continue; }
handlers[type](recv, json); }
Теперь переходим к самому интересному — обработке событий и реализации синхронного клиента, который позволяет без async/await просто запросить список сообщений и сразу же его получить (такой подход может быть полезен и юзерботам, которые не хотят размазывать стейты по всей программе). Почему без асинков? Честно сказать, мне они просто не нравятся: как привык к концепции wait/notify и коллбэков из Java, так их и юзаю всю жизнь :)
Сначала TDLib запрашивает параметры инициализации (стейт authorizationStateWaitTdlibParameters), затем если пользователь не авторизован — запрашивает номер телефона и код подтверждения (плюс дополнительные шаги для авторизации если они есть). В конце, TDLib возвращает стейт Ready, что означает готовность библиотеки к работе:
После этого, можно начать работу с данными. Обратите внимание, мой подход потоко-небезопасен, его нельзя дергать из нескольких потоков одновременно! В коде ниже, я вызываю метод для фетча сообщений, а затем в соответствующем коллбэке от TDLib обрабатываю данные (дабы статья не разрасталась на 20+ минут, я чуть урезал все листинги).
public List<Message> QueryMessagesInChat(long chatId, long lastMessage, int count) { messages.Clear();
public User QueryUser(long userId) { string json = Utils.Format("{\"@type\": \"getUser\", \"user_id\": \"{0}\" }", userId); NativeInterface.Send(InstanceID, json);
waitHandle.WaitOne(); return user; }
Переходим к реализации самого сервера, для наших целей хватит обычного HttpListener. Сначала мы зарегистрируем все поддерживаемые методы и занесем их в ассоциативный список ключ-значение. Сами методы реализованы в виде делегатов, которые принимают лишь один аргумент — список параметров из строки запроса, а возвращают строку — все ответы, за исключением особых (связанных с загрузкой вложений) — текстовые.
Переходим к обработке запроса. Метод ищет, зарегистрирован ли запрошенный метод и если да, то парсит строку запроса, которая начинается с "?", которую затем передаёт в виде коллекции ключ->значения обработчику метода:
А сами методы, в свою очередь, дергают соответствующие функции из клиента и формируют на их основе датасет в примитивном формате:
public staticstring QueryChats(Dictionary<string, string> args) { if(args.ContainsKey("count")) { int count = int.Parse(args["count"]); StringBuilder ret = new StringBuilder();
В результате получаем вот такой простой датасет, который, как я и говорил, легко распарсить и на Siemens C60, и на Atmega328 — да где угодно! В целом, такой сервер можно использовать для реализации бота в телеграме, который будет передавать показания каких-то датчиков, сигнализацию и прочие клевые штуки!
Переходим к реализации клиента, т.е. приложения на Android. Здесь будет не менее интересно!
❯ Пилим для Android
В геймдеве есть своеобразный мем — некоторые инди-разработчики сначала начинают делать меню, вместо основного геймплея, что становится предметом насмешек среди других разработчиков. Но в разработке приложений для смартфонов всё по другому — здесь как-раз таки хорошо заранее продумывать макет будущего приложения!
Поскольку у нас с вами мессенджер, то главный экран должен представлять из себя список чатов (ListView) и верхнюю панельку, где в будущем могут разместиться настройки и свайп-менюшка:
Такой вот простой макет.
Каждый пункт меню — это тоже отдельный layout, в котором мы по шаблону строим внешний вид будущего элемента списка. На немолодых устройствах есть смысл использовать как можно меньше контейнеров в layout'е, поскольку пересчет позиций и размеров элементов — одна из самых «тяжелых» операций в UI-фреймворке вообще. Кроме того, не стоит использовать кучу картинок и drawable — в Android 2.x всё 2D рисуется софтварно, аппаратное ускорение появилось только в 3.0 (частично).
Но дабы в списке диалогов что-то появилось, нужно сначала реализовать фетчинг (получение) этих самых диалогов с сервера! Сам объект, который занимается обработкой запросов называется ClientManager и является синглтоном — он в единственном экземпляре на все время работы программы. Помимо менеджмента «ноды» (т.е. прокси-сервера), токена для авторизации и обработчика ошибок, ClientManager реализует метод для асинхронного запроса информации с сервера и, собственно, формирует строки запросов с помощью соответствующих методов:
Подгрузка чатов и сообщений реализована через Adapter — концепция «виртуальных» списков, которая предполагает что система создаст не 50 элементов интерфейса на каждую кнопку чата, а только 5 и будет их виртуально «мотать по кругу», обновляя только данные в уже существующих элементах. Это позволяет значительно ускорить отрисовку, учитывая то, что Android 2.x Canvas рисуется программно.
Ну вы уже явно замучились видеть простыни кода, давайте посмотрим что у нас вышло!
Шустренько, да? А ведь это ультрабюджетник Alcatel OT-916D, один из последних массовых дешевых QWERTY-смартфонов за 5 000 рублей из 2012 года. Кстати, смартфон подарил мне читатель chuvakoff с Хабра!
Переходим к окну чата. Основной макет почти такой-же, как и у основного окна: только добавилась панелька для ввода сообщения снизу.
Концептуально, всё тоже самое — запрашиваем данные с сервера, парсим их и загружаем в адаптер, благодаря чему мы сможем листать наш диалог. Однако в сообщения я добавил контекстное меню с стандартными фишками типа копирования, ответа и прочих подобных действий. Поскольку у нас нет ни пушей, ни еще каких-либо средств для поулчения данных о новых сообщениях, я раз в определенный интервал просто получаю сообщения — и если новый датасет отличается от старого — обновляю окошко чата.
Переходим к реализации поля для ввода сообщения. Здесь всё просто — на серверсайде за это отвечает метод SendMessage. Однако для того, чтобы с нашего клиента можно было ответить на другие сообщения, я ввёл также «контекст ответа», в котором запоминается сообщение, на которое мы хотим ответить. Telegram также поддерживает Markdown, однако его полная поддержка пока не реализована.
В остальном же, функционал конечно пока совсем базовый, однако клиент работает очень шустро даже бюджетной X10 Mini Pro и позволяет чатится с моими читателями в Telegram. В будущем хотелось бы допилить:
Поддержка картинок: Сейчас уже есть кривоватый механизм кэширования изображений на стороне сервера, который позволяет загружать аватарки чатов. В будущем, я добавлю поддержку «галерей» с картинками!
Поддержка голосовых сообщений: Не все их любят, но они порой удобны и выручают. Реализую как прослушивание, так и запись!
Подробный просмотр профилей и менеджмент чатов: Удаление сообщений, чатов и прочие фишечки из официальных клиентов.
Казалось бы — до официальных клиентов ещё очень далеко. Но сам факт, чтобы всё это работало достаточно шустро на девайсах, которым уже более 10 лет!
❯ Звучит интересно! Как заюзать твой клиент?
Тут всё очень и очень просто! В первую очередь, нам понадобится ПК с белым IP, роутер (если под него есть сборка dotnet), либо VDS. Виртуальные сервера сейчас стоят копейки, у ТаймВеба есть тариф за 188 рублей в месяц, которого с головой хватит для нашего сервера.
Такая вот рекламная интеграция (к слову, прокси для всех приложений уже более года крутятся именно на мощностях TimeWeb Cloud)!
Программа сначала запросит номер телефона, а затем код подтверждения Telegram. После этого будет создана папка tdlib/, где будут хранится данные вашей сессии, а также файл authkey.txt, где хранится случайный ключ для сессии (md5 phone_number + response code + псевдослучайное число). Не оставляйте его в /var/www/!
Если всё нормально, программа начнёт слушать порт 13377 на всех сетевых интерфейсах, в т.ч и в локальной сети. После этого, ставим уже предварительно собранный, либо собираем сами в Android Studio APK и в окне авторизации пишем адрес ноды и ключ авторизации. Если всё настроено верно — программа запомнит сервер и будет работать без проблем! Вот так всё легко :) Как видите — всё очень и очень просто!
Кроме того, буквально за пару дней до публикации статьи я сел вечерком из интереса что-нить под Java-телефоны попилить… и, как и обещал, реализовал Proof of Concept возможности работы Telegram даже на сонериках, которым скоро 20 лет стукнет! А ведь если ещё чуть заморочится, можно запустить приложение даже на преусловутых монохромных сименсах!
❯ Заключение
Вот такой у нас получился проект с реализацией лёгкого, примитивного, но тем не менее рабочего клиента Telegram, который на клиентской части вообще не использует никаких зависимостей. Вес собранного APK в release-версии — всего 54 килобайта! Понятное дело что с ростом функционала, вес программы будет увеличиваться, но я обещаю — больше 1Мб он не вырастет :)
Ну а вам, моим читателям, надеюсь было интересно прочитать такой «двойной материал» не только о разработке сетевой части без использования Apache/nginx/IIS, но и UI-фронтэнда для Android-смартфонов, которым уже более 10 лет! Исходный код проекта можно найти на моём GitHub: как приложения, так и сервера, а также убедиться в отсутствии каких либо закладок и, если совсем не доверяете, собрать бинарники сами! Для сборки понадобится VS2017 или свежее, а также Android Studio 2.3.2 (если собираете для Android 2.1 и ниже).
Друзья! Сейчас на Хабре опросы сломаны, поэтому если у вас есть желание, вы можете проголосовать в комментариях: какой стиль статей вам больше нравится — где больше конкретики и кода с пояснением как конкретно работает та или иная часть программы, или наоборот стиль ближе к научпопу, где фрагментов кода нет, или их значительно меньше? Пишите своё мнение о проекте в комментариях!
Кроме того, у меня есть канал в Telegram, куда я публикую бэкстейдж статей, ссылки на новый материал, свои наработки, а также посты о ремонте девайсов и различные мысли.
Статья подготовлена при поддержке TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!
Взять с собой побольше вкусняшек, запасное колесо и знак аварийной остановки. А что сделать еще — посмотрите в нашем чек-листе. Бонусом — маршруты для отдыха, которые можно проехать даже в плохую погоду.
Где я подробно рассказываю о том, как реализовал клиент современного мессенджера Telegram на Android 1.5+ и выше. Таким образом, Telegram будет работать даже на самом первом Android-смартфоне в мире, T-Mobile G1, причём на стоковой прошивке!
⏺ ПОЛУЧИТЬ | 499₽ 💁🏻♂️ Discord Nitro — это платная подписка на популярный мессенджер для геймеров Discord, подписка предоставляет ряд дополнительных функций и возможностей, которые не доступны обычным пользователям: глобальные смайлики, модернизированная трансляция Go-Live, пользовательский тег «Discord», совместное использование экрана, увеличение лимита загрузки, анимированные аватары и т.д. ↘️ Прямо сейчас Discord совместно с браузером Opera GX запустили раздачу «Discord Nitro» для пользователей, у которых в течение года не было активной подписки. По итогу вы получаете уникальную ссылку для активации Discord Nitro, чтобы активировать подписку потребуется зарубежная карта.
🤷🏻♂️ ЧТО НУЖНО ДЕЛАТЬ: 1. Подключаем » Bright VPN. └ Выбираем страну, кроме РФ 2. Переходим по этой ссылке. └ Загружаем браузер Opera GX 3. Отлично, запускаем Opera GX. └ И снова переходим по ссылке 4. Теперь нажимаем: Claim Now! └ Получаем ссылку для активации 5. Готово, активируем Disord Nitro. └ Потребуется зарубежная карта, к примеру Papara (для активации подписки вам нужно иметь 1$ на карте для проверки)
Update: Нажимать "CLAIM NOW!" - можно бесконечно, тем самым каждый раз вы будете получать новую ссылку, при желании ссылки можно продавать на различных маркетплейсах или вы можете помочь сэкономить время Пикабушникам, просто пришлите ссылку в комментариях.
Ожидание: купила много классной косметики, уложилась в бюджет и при этом даже не выходила из дома. Реальность: собрала все пробки на дороге и перетолкалась с пассажирами в душном транспорте, пока добиралась до магазина. Если хотите, чтобы ожидание стало реальностью, заказывайте косметику в СберМаркете.
СберМаркет — это не только про продукты. Здесь можно быстро обновить косметичку в магазинах «Магнит Косметик», РИВ ГОШ, «Подружка» и других. В супермаркетах тоже есть соответствующие категории. Всё в одном приложении, не нужно никуда дополнительно заходить и что-то скачивать.
По оплате тоже удобно — до 30 ноября можно оплатить до 99% от стоимости покупки бонусами СберСпасибо или поделить оплату на части без процентов. Установите приложение и попробуйте сами. Не забудьте про промокод для новичков — ПИКАБУ1000, он действует до 31 декабря и даёт скидку 1 000 ₽ на первый заказ от 2 500 ₽.
Очень годно. Смешит часть комментаторов, которые пишут, что мол совсем разучились калькулятором пользоваться. Сразу видно, или люди сами в магазин не ходят, или просто недалекие. Господь или эволюция дали нам мозг с помощью которого мы умеем упрощать и адаптировать многие действия. Насколько проще написать прогу, которая, внимание, при наведении на ценник - сканирует его и сразу даёт цену за искомый литр/кг, чем стоять с калькулятором высчитывать, хоть это и элементарное действие, но если у вас полная корзинка в одной руке и плачущий ребёнок в другой или иные обстоятельства, которые мешают комфортно сделать рассчеты. А если вы покупаете много всего, или вам надо сразу сравнить 20 ценников колбасы разного веса? Вооооооот.
Чтобы закупиться всякими нужностями, можно потратить вечер после работы или драгоценный выходной на толкотню в транспорте, километровые пробки и бесконечные очереди у касс. Или же заказать всё необходимое в приложении СберМаркет и заняться более приятным делом — включить любимую киношку и немного расслабиться с котиком под боком.
В СберМаркете легко пополнять список любимых товаров, чтобы отслеживать на них скидки. Просто нажмите на сердечко и тогда точно не упустите ведёрко любимого мороженого по приятной цене :)
Регулярные товары складывайте в один заказ и просто повторяйте его, когда нужно — удобно, что не придётся вообще выделять время на выбор базовой корзины.
Эти небольшие лайфхаки помогут закупаться очень быстро, буквально за несколько кликов. Избавьтесь от ненужных действий уже сегодня — скачайте приложение СберМаркет и сделайте первый заказ. Не забудьте про промокод для новых пользователей — ПИКАБУ1000, действует на покупки от 2 500 ₽ до 31.12.2023.