Всем привет!
Хочу рассказать историю о том, как я стал разработчиком под Android. Не в том смысле, что я сейчас этим зарабатываю на жизнь, а в том смысле, что из небольшого интереса к мобильной разработке я дорос до собственного приложения на PlayMarket. Но об этом чуть позже. История немного нетипична. Хотя, наверное, у каждого она своя.
Цель статьи — выплеснуть всё хорошее, что накопилось за несколько лет работы над проектом, а также поделиться своей историей (вдруг кому-то она покажется интересной). Ну, и попиариться немножко. Старался всё же, причём не только для себя. А потому буду рассказывать только о том, что делал сам, с помощью или без. Поехали.
Введение
Года 2-3 назад в новогодние праздники у меня выдались свободные дни, и я размышлял, чем бы мне заняться. Вообще, в программировании и ИТ я, так или иначе, всю жизнь, но вот на мобильные платформы ничего писать не доводилось. Но тянуло… Всё равно мы все с телефоном чуть ли не 24 часа в сутки. Интересно же под него писать то, что мне нужно? Безумно интересно. Погодите, а что мне нужно? Метания не были долгими и мучительными. Банальный «хэлловорлд» писать скучновато и на один вечер, поэтому поначалу я хотел парсить сайт с расписанием сеансов кино. Но, бегло погуглив, сразу понял, что всё это давно есть. Особняком всегда для меня стояли программы для чтения, я пользовался ими со времён коммуникаторов/наладонных компьютеров для WinCE. Именно поэтому выбор пал на проект CoolReader (далее буду звать его CR).
Что такое CR? Это одна из старейших читалок, которая до сих пор крайне популярна. Суждение отчасти субъективное (я много вижу в автобусах и метро читающих именно на CR до сих пор), а отчасти объективное (попробуйте ввести в поиске PlayMarket слово «reader», и CR будет одним из первых предложений). Когда-то давно я выбрал для себя эту читалку и на долгие годы забыл, что существуют вообще другие (естественно ставил всем друзьям и знакомым). Это сейчас их много разных и интересных, а тогда было не особо. Т.е. для меня использование CR было как само-собой разумеющееся, хотя немного напрягало, что с некоторых пор приложение перестало обновляться. Как-то раз я попытался перейти на другое приложение, и даже купил премиум версию. Но всё-таки не пошло — CR оказался удобнее в плане UI, хоть это раскрывается и не сразу. Пример того, с чем я не смог смириться:
- В CR выделить текст можно просто двумя тапами в разное место экрана — текст выделяется между тапами;
- Если нужно выделить одно слово, то можно сделать это просто двойным тапом.
Это позволяет выполнить перевод слова или фразы в словаре за доли секунды. Стандартное андроидовское поведение (сделать длинный тап, подвигать указатели начала и конца) для читалок не подходит, неудобно.
Работа со словарями вообще оказалась критичной для меня, а потому я сразу понял, чего мне не хватало от читалки. Мне нужна возможность настройки двух словарей. Один словарь — это классно: выделили слово/фразу и тут же перевели. Но разные словари — это разные словари. Можно настроить GoldenDict или Abbyy для чтения книг на английском (они оба по-своему хороши). Хорош aard2, в который можно залить, например, оффлайновую википедию (да, всю википедию оффлайн!).
Начало
Поехали делать 2 словаря.
Я нашёл в интернете исходные коды CoolReader — они совершенно спокойно доступны на github. Автор оригинального CR проект к тому времени уже почти забросил, а потому CR обновлялся крайне редко. Попытки скомпилировать CR и запустить (ещё под Eclipse) успехом не увенчались. Это сподвигло на поиски решения, в результате чего на форуме 4pda была найдена доработанная версия от другого энтузиаста, которая уже собиралась под Android Studio. Благодаря ему всё получилось — проект собирается и запускается.
Первая доработка:
- Добавлена настройка «Словарь 2».
- Добавлены действия:
- Перевести в словаре 1;
- Перевести в словаре 2;
- Разово переключить на словарь 2, после чего переводить всё снова в словаре 1.
Где-то в этот же момент на форуме попросили сделать историю поиска в книге по тексту, чтобы можно было быстро повторить ранее выполненный поисковый запрос. Это был более сложный вызов, так как список в Андроиде выводится несколько сложнее. Получилось! Теперь в поиске есть список с историей выполненных поисковых запросов.
Увлечение
Дальше я задался вопросом: «Что можно ещё сделать»? Да много чего...
Иконки
В приложении мне не понравились иконки, которые под современные разрешения выглядят «мылом». Да и вообще так сейчас не рисуют — они выглядят наивными, слишком прямолинейными и подробными, не несут «единого стиля» (господи, это я говорю?). Попробуем поработать в этом направлении. Получилось договориться с проектом icons8 — они дали премиум доступ к своим наборам иконок (для OSS-проектов), за что ребятам огромное спасибо! Дальше начался большой и сложный процесс интеграции современных иконок в приложение. Чтобы было понятнее — читалки в основном пишутся под андроид 4.0-4.4 максимум, так как большинство устройств для чтения электронных книг до сих пор на этой ОС. Стало быть, никаких векторных иконок и «материал» дизайна, а только старый добрый png.
Здесь также помогло решение от второго разработчика на форуме — автомасштабирование векторных иконок под все разрешения устройств. Это скрипт на Perl, который берёт svg, а из неё формирует много png под разные устройства.
Было | Стало |
---|---|
![]() |
![]() |
Данные о книге
Двигаемся дальше — отображение и редактирование информации о книге. Книжные форматы несут в себе достаточно много метаданных — информацию об издательстве, серии, жанрах и т.д. Всего этого, к сожалению, не было в оригинальном CR. А мне надо! Сделал. Ставим галочку, идём дальше.
Было | Стало |
---|---|
![]() |
![]() |
Было | Стало |
---|---|
![]() |
![]() |
Темы оформления
Стандартные темы (с фоном в виде текстуры дерева), конечно, неплохие, но хотелось чего-то более нейтрального. Разобрался, как создаются темы, добавил две серые темы (потемнее и посветлее). Мне, кстати, за них отдельное спасибо сказали.
Я разрабатываю под Android
Пользовательский словарь
Вроде закрутилось-завертелось. Что дальше? Проанализировал issues к оригинальному проекту. Очень заинтересовала одна фича, которую в итоге назвал «пользовательский словарь» (если вдруг забыли, напоминаю: словари — это круто). Как фича мне виделась: читая книги на английском языке часто хочется сохранить перевод сложного слова в собственный «маленький словарь», из которого потом это слово можно было бы подсматривать. Выглядит сейчас это так — под книгой есть небольшая панель, на которой выводятся слова из пользовательского словаря — те, которые встречаются на данной странице. Слова кликабельные, перевод можно посмотреть.
Выбор слова | Перевод |
---|---|
![]() |
![]() |
Закладки
С ними, за исключением багов, было всё нормально, но они были немного расширены:
- «Пользовательский словарь» — о нем выше;
- «Цитата» — можно сохранить понравившуюся цитату;
- «Внутренняя ссылка» — это закладка на закладку (эдакий гиперлинк между закладками), т.е. можно быстро перемещаться по отмеченным (закладками) позициям в документе.
Было | Стало |
---|---|
![]() |
![]() |
Было | Стало |
---|---|
![]() |
![]() |
Панель инструментов
Очень странный инструмент эта панель инструментов. Т.е. она хороша сама по себе, хотя многие и не любят лишний визуальный мусор, но она была совершенно не настраиваемой. Это неправильно, посчитал я. В результате чего были добавлены настройки кнопок в панели инструментов, настройки кнопок в панели «меню», вариации внешнего вида панели (3 размера).
UI/UX (не иконки)
Современная программа должна выглядеть современно, это ведь совершенно очевидно (или нет?). Что здесь добавлено:
- Панель статуса (название книги, позиция прочитанного) — вариант вывода в 2 строки, количество страниц до конца главы;
- Настройка для телефонов с чёлками и вырезами — модная тема, да и непростая. Теперь CR может по-разному отрисовываться на подобных телефонах;
- Множество дополнительных панелей и подсказок. Вопиющий пример — при выборе «перевод в словаре» и не настроенном словаре выводилось сообщение «настройте словарь». Где? Как? Там у нас сотни настроек уже. Решение — просто сразу перекинуть пользователя в настройки словаря. Просто и доступно. И маршрут искать не надо.
Сетевые возможности
Всё плохо… Было. Стало:
Прекрасная функциональность каталогов OPDS (а иначе откуда скачивать книги?) — добавлен поиск, добавлена возможность фиксировать избранные папки, предпросмотр аннотаций, обложек.
Предпросмотр книги | Избранное, поиск |
---|---|
![]() |
![]() |
Добавлена возможность открытия книг с Яндекса/Dropbox.
![]() |
---|
Добавлена синхронизация позиции чтения между устройствами, а также синхронизация закладок и настроек. Думаю, сделана далеко не хуже пропиетарных решений от Onyx, PocketBook и подобных.
Google.Drive. Они сами виноваты. Изначально сделал, затем они свою библиотеку для андроида посчитали устаревшей, на новую переходить уже не захотелось, кончился кредит доверия.
Отдельно отмечу Яндекс — самые что ни на есть некривые и простые API с которыми «не больно» разбираться и «жить дальше». Все остальное — минимум примеров, все устаревшие, все обросло кучей своих (опять же устаревших) API (да, дропбокс и гугл, я о вас, хоть и победил в конце концов).
TTS
Для тех, кто не в курсе, современные читалки умеют аудировать книгу. Эта функция называется TTS — Text to speech. Хороший набор возможностей, но, как выяснилось, тут есть одна общая боль — почему-то все читалки с TTS работают в той или иной степени криво (ОС выгружает программы по своему желанию, когда пользователь этого не ждёт). Здесь внедрён некоторый набор «костылей», которые складываются в довольно устойчивую конструкцию, чтобы проблема проявлялась реже и не у всех.
Словари, онлайн-словари
Словари — это классно! Кажется, я это уже говорил. Современный мир изменился. Мы живем в мире распознавания речи в текст и онлайновых словарей на нейронных сетях. Потому добавил Яндекс.Переводчик и Lingvo. Почему одного показалось мало? Тут всё просто. Яндекс умеет переводить целую страницу, а не только отдельные слова. Lingvo — показывает транскрипцию.
Яндекс | Лингво |
---|---|
![]() |
![]() |
А ещё расширен общий перечень словарей — в него добавлены все программы, которые умеют принимать на вход текст (всякие википедии и прочие). Если появится какая то новая — мы сразу сможем в неё отправить что хотим.
UI/UX. Опять?
Было | Стало |
---|---|
![]() |
![]() |
Да, опять. Потому что хочется, чтобы было удобно. А потому доработок много. Это и два действия на кнопке на панели (обычное — «короткий тап» и зеркальное — «длинный тап»), и поиск в настройках, и дополнительная информация о настройке (иконка со знаком вопроса) — здесь помогли обитатели форума. Они классные. Спасибо всем и каждому, кто помогал. Тем, кто мешал, тоже спасибо. Вы тоже классные. О чём я? А, ещё поиск в списках настроек, красивый диалог выбора шрифта (с панграммами на разных языках), возможность быстро скачать и установить шрифты.
Было | Стало |
---|---|
![]() |
![]() |
А ещё возможность изменения полей и размера шрифта жестами (щипками 2 пальцами).
Было | Стало |
---|---|
![]() |
![]() |
Редкие возможности
Помимо стандартных для всех читалок возможностей и настроек (словари в этот список не входят), у CR появились и изюминки, среди которых:
- «Сказка на ночь». Основная идея в том, что если вы слушаете аудиокнигу, а телефон не шевелится (вы уснули или же вы йог на тренировке), то CR остановит чтение через время, определённое в настройках. Телефон не разрядится в 0, вам не придётся долго искать, на каком моменте вы уснули и т.д. Говорим спасибо автору фичи S-trace.
- «Метро и транспорт». Если вы едете в транспорте и слушаете музыку в наушниках, то есть шанс, что вы можете пропустить нужную вам остановку. С этой возможностью программа будет оповещать вас о ближайших станциях метро/наземного транспорта (наземный транспорт — только в Москве). Баловство конечно, но зато интересно. Заодно пообщались с Евгением Варфоломеевым и его проектом 3D-карта метро — очень интересный проект, рекомендую.
- Отправить веб-страницу в СR. Нормально, веб-страница будет читаться как обычная книга. При этом будет предложено или сохранить форматирование в html или преобразовать в обычный текст;
- Отправить картинку в СR. Тоже можно — будет предложено или поставить её на подложку для чтения книги или вы сможете заменить обложку у любой имеющейся книги.
Вместо заключения
Мало, скажете вы? Не соглашусь. Так вышло, что доработанным оказался каждый диалог в оригинальном CR, а также добавлено больше половины новых (от того, что было). И тут я задался вопросом: наверное, это уже не CR? Вероятно, это так. Или нет? Напишите об этом в комментариях, а мы пока пойдём дальше, потому что с этого момента начинается своя история — история KnownReader (далее — KR), где «known» применяется не в смысле «знаменитый», а в смысле «знакомый». Т.е. знакомый по родительскому проекту. Эта история только началась, и она плавно перетекает на PlayMarket, хотя, соблюдая лицензию и в целом исповедуя принципы OSS, репозиторий на github по-прежнему открыт, а на 4pda как и раньше выкладываются готовые сборки (иногда даже раньше, чем на PlayMarket). К слову, заходите в гости на форум — у нас там уютно.
Я и мой товарищ (о нём ещё скажу) полны энтузиазма и очень активно развиваем проект:
- Общаемся с аудиторией, причём как с уже нашей, так и с аудиторией оригинального CR, потому что болячки очень часто общие, а потому мы рассматриваем это как возможность сделать KR лучше. С некоторыми пользователями даже общаемся индивидуально (telegram, QMS на 4pda).
- Исправляем дефекты и решаем проблемы, причём некоторые очень даже старые. Например, в одном из последних релизов мне удалось ускорить работу с большими библиотеками, благодаря чему список из более чем 1000 книг теперь формируется за ~3 секунды вместо ~40 секунд ранее.
- Добавляем новые возможности или изменяем существовавшие ранее, доводим до ума то, что нас просят. Мой товарищ неплохо подхватил эту активность. Будучи системным аналитиком он неплохо собирает требования.
- Выпускаем релизы, не забывая при этом ни о тех, кто сидит на PlayMarket, ни о тех, кто ставит себе приложения с помощью apk-файлов. Постим сообщения на форум, разъясняя, что уже добавлено, что будет добавлено позже, как что-то работает, почему мы сделали именно так и т.п.
- Вот и до статьи добрались. Давно уже хотели, да всё руки не доходили. Шила в мешке не утаишь, а потому откровенно скажу, что очень рассчитываем на «хабраэффект». Больше пользователей — больше нашей ответственности перед ними, а, значит, больше интересной работы и общения.
Благодарности и ссылки
Хочется выразить благодарность:
- Автору оригинального проекта: Вадиму Лопатину. Без него не было бы этой истории. Была бы другая, но этой не было бы.
- Всем контрибьюторам в исходный код CR. Без них не было бы проекта в том виде, в котором он есть сейчас.
- Особенно отмечу авторов доработок оригинальной версии на форуме 4pda: virxkane, S-trace, pkbo. Спасибо вам за вклад в развитие движка, за адаптацию изменений koreader (не путать с KR).
- Проекту koreader, за их вклад в движок crengine. Хоть они всё делают и для себя, но это не помешало нам «всё их» применить к себе.
- Разработчикам читалок. Это дивный новым мир, в котором со всеми можно делиться идеями и кодом. Очень помогли лидеры проектов Alreader (Alan, спасибо), PocketBookReader (ребята, ваш файл «манифеста» один из лучших), Librera (foobnix, привет).
- Проекту FBReader. Хоть мы и не общались напрямую, но кое-какой код был очень кстати, например, отображение словаря Lingvo.
- Проекту icons8, который не пожадничал и поделился библиотекой иконок.
- Всем, кто пользуется KR и не стесняется писать о возникающих проблемах, помогает тестировать приложение и готовить материалы для FAQ (мир полон неравнодушных людей). Особенно хочу отметить самых активных пользователей сообщества: Sergey_TSA, SvyatKV.
- Виталику (профиль на habr.ru, профиль на 4pda) — человеку, который помог в нужный момент сделать следующий шаг, активно включившись в проект: перенял на себя часть работы с аудиторией на форуме 4pda и за его пределами, занимается публикацией (первичной и обновлений) KR в PlayMarket (тестирует KR, готовит описания, отвечает на отзывы и т.п.), создал сайт KR и поддерживает его в рабочем состоянии (он в плане frontend-разработки подмастерье, так что воспринимайте сайт как его собственный pet-проект), организовал систему доната через Яндекс.Деньги (на сайте опять же), помог мне разобрать, привести в порядок и поддерживать в хорошем состоянии backlog, вычитывал и правил эту статью, а также делает ещё много мелкой, но важной работы, что очень важно для меня и проекта в целом, но обычному пользователю может быть незаметно.
- Кошке Маше и коту Коле, с которыми мы провели множество интересных вечеров программирования.
- И, наконец, главное. Моей жене — за терпение к многочисленным увлечениям ;)
Напоследок
Я тут расписал так, что получается «картина маслом» — всё красиво, все помогают, проблем нет, одни успехи. Но, к сожалению, без ложки дёгтя не обойтись. Количество задач в backlog'е постепенно растёт, и справляться с ними своими силами не успеваю, несмотря на огромное желание и задор. Смею предположить, что на хабре найдутся неравнодушные люди, которые ищут, чем бы себя занять, не определились с хобби, просто хотят помочь или сделать свой вклад в OSS. Все ведь поняли, к чему я веду? Нужны контрибьюторы. Не к нам, так в проект, с которого всё начиналось (мы люди не гордые). В большей степени даже C++ контрибьюторы. Буду благодарен за поддержку. Да и не только я. Вокруг читалки сложилось определённое сообщество, которое, я уверен, тоже будет благодарно. А потому — милости просим.