Привет. Так сложилось, что в основном посты в нашем блоге написаны для потенциальных пользователей и просто интересующихся ходом разработки YotaPhone. А для разработчиков ПО мы публиковали гораздо меньше информации, что и хотим исправить: сегодня мы расскажем вам об особенностях разработки приложений для YotaPhone и созданном нами для этого инструментарии.
Инструменты для разработчика
Для начала несколько слов об инструментарии для разработки приложений для YotaPhone. Вам понадобится установить пакет Android SDK, поверх которого поставить YotaPhone SDK. Подробные инструкции по установке и настройке под разные ОС вы найдёте на нашем сайте для разработчиков.
Мы постарались сделать YotaPhone SDK максимально понятным и удобным для любого Android-разработчика, чтобы терминология и внутренняя логика были наиболее близки к таковым в Android SDK.
Второй экран выполнен по технологии электронных чернил и обладает рядом особенностей, которые необходимо учитывать при разработке приложений:
• Цветовое пространство состоит из 16 цветов (оттенков серого)
• Длительное время обновления изображения
• Ghosting-эффект, изначально присущий этой технологии
• Отсутствие подсветки матрицы
Архитектура приложений
Прежде чем приступать к разработке своего первого приложения для YotaPhone, ознакомьтесь с принятой программной архитектурой. В целом, она аналогична традиционной Android-архитектуре:
Схема взаимодействия между архитектурными компонентами:
Несколько слов о каждом из компонентов представленной схемы.
• Application Layer. Это наиболее важный компонент для сторонних разработчиков, поскольку установка их продуктов возможна только в пределах этого уровня. Он работает на одном уровне с приложениями Google и сервисами, и содержит различные дополнительные приложения, такие как Органайзер, Блокнот, Обои и т.д. Взаимодействие с SDK происходит в обоих направлениях.
• SDK. Этот уровень предназначен для использования приложениями именно для YotaPhone. SDK поддерживает некоторое количество высокоуровневых сервисов для фронт-энд приложений в виде Java-классов. Эти сервисы также доступны при разработке приложений для второго дисплея. SDK содержит двусторонние интерфейсы между сервисами и дополнительными приложениями.
• YotaPhone Manager. Это важная часть архитектуры. Данный компонент управляет взаимодействием между приложениями и низкоуровневыми методами. Любые приложения сторонних разработчиков взаимодействуют с SDK через YotaPhone Manager.
• YotaPhone Daemon. Это низкоуровневый программный компонент, ответственный за передачу команд от приложений/сервисов, через YotaPhone Manager, к E-ink controller driver.
• E-ink controller driver. Он разработан производителем и отвечает за выполнение команд, полученных от приложений, сервисов или ОС.
• Android Framework. В YotaPhone используется стандартный Android-фреймворк, с минимальными изменениями.
Схема работы со вторым экраном
За отображение информации на втором дисплее YotaPhone отвечает класс BSActivity (Back Screen Activity), основанный на стандартном Android service. При разработке приложения для второго дисплея необходимо создать свой класс, унаследованный от BSActivity, и описать его в файле AndroidManifest.xml:
<service
android:name="com.yotadevices.example.BSActivity"/>
Жизненный цикл самого BSActivity можно представить следующим образом:
Запуск приложения на втором дисплее выполняется так же, как запуск стандартного Android service:
mContext.startService(BSActivityIntent);
Опишем подробнее представленный жизненный цикл:
Во время запуска BSActivity получает callback onBSCreate() и регистрирует себя в YotaPhone Manager в качестве Приложения для второго дисплея, которое получает иконку, заголовок и становится видно в Task Manager. Оно появляется при долгом нажатии на сенсорную зону второго дисплея.
Когда запускается какое-либо приложение для второго дисплея или пользователь открывает менеджер задач, YotaPhone Manager останавливает работу текущего BSActivity, посылая call back onBSPause(), onBSStop(). После этого приложение получает call back onBSDestroy() (аналогично onDestroy() в стандартном Android service) и завершается.
В call back onBSSaveInstanceState(Bundle savedInstanceState), который вызывается после onBSPause(), можно сохранять любые данные. Когда приложение на втором дисплее получает callback onBSPause(), оно становится не активным (не может выводить изображения на второй дисплей и получать информацию о жестах управления от сенсорной зоны второго дисплея). При этом в любое время приложение может получить call back onBSStop(). Если вы хотите передать информацию в BSActivity, то для доступа к ней нужно переопределить при запуске метод onHandleIntent(Intent intent).
Особенности вывода изображений на второй экран
Как вы помните, экран на электронных чернилах обладает рядом особенностей, которые необходимо учитывать при разработке. Типичный метод вывода изображения на второй экран выглядит следующим образом:
getBSDrawer().drawBitmap(bitmap, Waveform.WAVEFORM_GC_FULL);
Вторым аргументом здесь является waveform. Это набор инструкций для контроллера дисплея о том, как нужно отрисовывать изображение. В YotaPhone SDK существует четыре основных вида waveform, которые могут комбинироваться друг с другом.
• GC_FULL. Используется для полного обновления дисплея, когда текущее изображение заменяется новым. Обеспечивает высокое качество изображения.
o 4 бита, 16 градаций серого
o ~600 мс
o Процесс отрисовки сопровождается однократным мерцанием дисплея
o Низкий уровень ghosting-эффекта
• GC_PARTIAL. Применяется для частичного обновления изображения. Перерисовывается только та часть экрана, где изменилось изображение.
o 4 бита, 16 градаций серого
o ~600 мс
o Мерцания нет
o Присутствует ghosting-эффект
• DU (Direct update). Быстрый метод обновления, который поддерживает только два цвета: чёрный и белый. Никакие оттенки не поддерживаются. Эту waveform удобнее всего использовать для индикаторов выбора меню или для отображения текста.
o 1 бит (чёрный или белый)
o ~250 мс
o Мерцания нет, обновляется только часть изображения
o Присутствует ghosting-эффект
• A2. Ещё более быстрый метод, который предназначен для оперативного обновления страницы или создания простенькой чёрно-белой анимации. Поддерживает только два цвета — чёрный и белый.
o 1 бит черный или белый
o ~120 мс
o Мерцания нет, обновляется только часть изображения
o Присутствует ghosting-эффект
Оптимизация изображения на втором дисплее
EPD очень сильно отличаются от LCD, и потому изображения, хорошо выглядящие на основном дисплее, зачастую на втором могут выглядеть посредственно. Однако в YotaPhone SDK содержится несколько методов, позволяющих улучшить качество отображения на втором дисплее. В частности, можно настраивать dithering (смешивание цветов), резкость, яркость и контрастность.
Сглаживание. Поскольку электронные чернила отображают 16 цветов (оттенков серого), а LCD — 16 777 216 цветов, то смешивание цветов является наиболее логичным шагом. YotaPhone SDK поддерживает два алгоритма: Atkinson (применяется в большинстве случаев) и Floyd-Steinberg (для изображений с большим количеством градиентов).
Вы можете применять два способа применения смешивания цветов:
•
bitmap = EinkUtils.ditherBitmap(bitmap, ATKINSON_DITHERING);
•
getBSDrawer().drawBitmap(0, 0, bitmap, BSDrawer.Waveform.WAVEFORM_GC_PARTIAL, EinkUtils.ATKINSON_DITHERING);
Резкость. Электронные чернила несколько размывают изображение, и повышение резкости помогает бороться с этим эффектом. В используемом нами алгоритме применяется матрица скручивания:
Пример кода повышения резкости при k=0,15:
bitmap = BitmapUtils.sharpenBitmap(context, bitmap, 0.15f);
Контрастность и яркость. Усиление контрастности также помогает снизить эффект размытости изображения на втором дисплее. Но оно также влияет и на яркость, которую необходимо в этом случае понизить.
Пример кода для увеличения контрастности с коэффициентом 1,2 и снижения яркости на 30:
bitmap = BitmapUtils.changeBitmapContrastBrightness(bitmap, 1.2f, -30)
Пример кода стандартной обработки изображения для вывода на второй дисплей:
1) Повышение резкости при k=0,15
2) Увеличения контрастности с коэффициентом 1,2 и снижения яркости на 30
3) Применение алгоритма смешивания Atkinson для конвертации в 16-цветовую палитру:
bitmap = BitmapUtils.prepareImageForBS(context, bitmap);
getBSDrawer().drawBitmap(0, 0, bitmap, BSDrawer.Waveform.WAVEFORM_GC_PARTIAL, EinkUtils.ATKINSON_DITHERING);
Уведомления
Одним из главных преимуществ второго дисплея в YotaPhone является возможность отображения пользовательских уведомлений. Всего их существует три вида, и тип конкретного уведомления, его позиция на экране и время отображения определяются родительским приложением.
• Полноэкранное уведомление. Лучше всего подходит для отображения картинок или сравнимого количества текста.
• Уведомление на половину экрана. Всегда располагается в нижней части, в основном применяется для коротких текстовых сообщений.
• Панельные уведомления. Самый маленький вид, могут содержать иконки и текст.
Полноэкранные и половинчатые уведомления через 60 секунд уменьшаются до размеров панельного. Ещё через 60 секунд уведомления отображаются только в счётчике непрочитанных уведомлений.
Rotation-алгоритм
Поскольку у YotaPhone две сенсорные поверхности, то требуется очень аккуратный механизм разблокировки, чтобы предотвратить случайные действия со стороны пользователя. Для этого нами разработан «алгоритм переключения», который использует информацию с датчиков устройства, чтобы определить его положение в пространстве и разблокировать соответствующий дисплей. Благодаря этому у пользователя создаётся впечатление единого рабочего пространства на двух дисплеях, а не двух разрозненных устройств.
Алгоритм 1:
• Пользователь осуществляет какое-то действие со смартфоном —> включаются гироскоп и акселерометр
• Если пользователь не переворачивает смартфон в течение 4 секунд, то датчики отключаются
• Если не переворачивать в течение 4 секунд —> блокируется основной дисплей и разблокируется второй (если это действие не блокируется программно). Датчики продолжают работать ещё в течение 4 секунд
• Если в течение этих вторых 4 секунд пользователь переворачивает смартфон обратно —> второй дисплей блокируется, основной разблокируется, датчики выключаются
• Если не переворачивать смартфон в течение вторых 4 секунд —> датчики блокируются, основной дисплей выключается, пользователь продолжает пользоваться вторым дисплеем.
Алгоритм 2:
• Пользователь осуществляет какое-то действие со вторым дисплеем —> включаются гироскоп и акселерометр
• Если пользователь не переворачивает смартфон в течение 4 секунд —> датчики отключаются, состояние основного дисплея не меняется, пользователь продолжает пользоваться вторым дисплеем
• Если пользователь переворачивает смартфон в течение 4 секунд —> второй дисплей блокируется, основной включается и разблокируется, датчики отключаются.
Ниже приведён пример кода, который запускает алгоритм переключения после нажатия кнопки на основном дисплее, в результате чего пользователь ожидает переключения на второй дисплей:
mButtonP2B.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
RotationAlgorithm.getInstance(getApplicationContext()
).issueStandardToastAndVibration(); //To let the user know that he is expected to rotate the phone now
RotationAlgorithm.getInstance(getApplicationContext()
).turnScreenOffIfRotated(); //Perform drawing on back screen here
}
});
Послесловие
Как вы уже заметили, мы постарались максимально облегчить труд разработчиков приложений для YotaPhone. Если у вас уже есть опыт разработки под Android, то освоение нашего SDK не вызовет никаких затруднений.
Отдельно хотим обратить ваше внимание на разработку приложений для второго дисплея. Особенности технологии электронных чернил и сам факт наличия двух дисплеев у смартфона требуют внимательного подхода к адаптации изображения. Для более глубокого изучения этого вопроса рекомендуем обратиться к соответствующему разделу на нашем сайте для разработчиков.
Мы также существенно переработали и улучшили архитектуру SDK для второго поколения YotaPhone. С началом продаж смартфона, SDK будет доступен всем желающим.
Автор: YotaDevices