- PVSM.RU - https://www.pvsm.ru -
Привет! Совсем недавно прошёл Google I/O (если кто пропустил наш репортаж — вам сюда), где увидел свет новый API для отображения данных на циферблатах часов. Название его пришло из часовой отрасли: по-русски их традиционно зовут «Усложнения», ну а по-английски —«Complications».

Если вкратце — это механизм отображения какой-либо дополнительной информации на часах, помимо, собственно времени: в реальных могут быть всякие планеты-звёзды-календари, ну а в нашем случае — всё, что придёт вам в голову. Сегодня мы покажем, на что способен API Watch Face Complications и как с ним работать.
Привет, я Александр Куликовский, занимаюсь разработкой для Android с 2010 года. На данный момент работаю в компании Sebbia [2] в должности Senior Android Engineer и возглавляю GDG Ростова-на-Дону.
Итак, чтобы попробовать новые возможности Android Watch 2.0 нам потребуется чистый проект. Создаём его, указываем API N в качестве минимальной версии SDK (minSdk) для телефона и часов.

Activity для телефона нам не нужна, поэтому выбираем шаблон «Add no activity». Для часов же возьмём стандартный шаблон Watch Face. Дадим имя сервису ComplicationWatchFaceService, стиль — аналоговый.

После этого получим стандартный проект.
Перед тем как продолжим, нам необходимо убедиться в том, что в gradle-файле, описывающем модуль wear, в разделе зависимостей wearable подключены не ниже версии 2.0.0:
compile 'com.google.android.support:wearable:2.0.0-alpha1'
Добавляем complication к нашему watchface. В реальном приложении пользователь сможет выбирать источники информации для получения complication-данных, нам же надо обеспечить получение и отображения такого рода информации.
Чтобы начать получать complication-данные, мы вызваем метод setActiveComplications в ComplicationWatchFaceService.Engine, и получаем список идентификаторов посадочных мест для отображения информации:
// Unique IDs for each complication.
private static final int LEFT_DIAL_COMPLICATION = 0;
private static final int RIGHT_DIAL_COMPLICATION = 1;
// Left and right complication IDs as array for Complication API.
public static final int[] COMPLICATION_IDS = {LEFT_DIAL_COMPLICATION, RIGHT_DIAL_COMPLICATION};
….
public void onCreate(SurfaceHolder holder) {
...
setActiveComplications(COMPLICATION_IDS);
...
}
Данные для отображения приходят в методе onComplicationDataUpdate нашего ComplicationWatchFaceService.Engine.
По спецификации [3] мы вольны отображать полученные данные как угодно, но для каждого типа данных есть набор обязательных полей для отображения. Более детально об этом можно посмотреть в таблице [4].
@Override
public void onComplicationDataUpdate(int watchFaceComplicationId, ComplicationData data) {
super.onComplicationDataUpdate(watchFaceComplicationId, data);
mActiveComplicationDataSparseArray.put(watchFaceComplicationId, data);
invalidate();
}
Само рисование на canvas’е нам не интересна — про это уже сто раз рассказывали. А вот на что надо обратить внимание, так это на то, откуда, собственно, взять данные, которые мы будем отображать. В случае с TYPE_SHORT_TEXT код будет выглядеть следующим образом:
private void drawComplications(Canvas canvas, long currentTimeMillis) {
ComplicationData complicationData;
for (int i = 0; i < COMPLICATION_IDS.length; i++) {
complicationData = mActiveComplicationDataSparseArray.get(COMPLICATION_IDS[i]);
if ((complicationData != null)
&& (complicationData.isActive(currentTimeMillis))
&& (complicationData.getType() == ComplicationData.TYPE_SHORT_TEXT)) {
ComplicationText mainText = complicationData.getShortText();
ComplicationText subText = complicationData.getShortTitle();
CharSequence complicationMessage =
mainText.getText(getApplicationContext(), currentTimeMillis);
if (subText != null) {
complicationMessage = TextUtils.concat(
complicationMessage,
" ",
subText.getText(getApplicationContext(), currentTimeMillis));
}
……..
Но теперь, если запустить проект, мы никаких complications не увидим. А всё потому, что пользователь не задал источники информации для отображения. Потому что не мог — меню настроек-то мы ему не выделили… Исправим это: создадим активити настроек и пропишем её в манифесте:
<service
….
<meta-data
android:name="com.google.android.wearable.watchface.wearableConfigurationAction" android:value="com.example.complicationwatchface.CONFIG_COMPLICATION_SIMPLE"/>
….
</service>
<activity
android:name=".ComplicationConfigActivity"
android:label="@string/complication_simple">
<intent-filter>
<action android:name="com.example.complicationwatchface.CONFIG_COMPLICATION_SIMPLE"/>
<category android:name="com.google.android.wearable.watchface.category.WEARABLE_CONFIGURATION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
В данной активити мы отобразим список информации о доступных посадочных местах для complications, апо клику на элемент будем запускать стандартный экран выбора доступных источников данных:
Integer tag = (Integer) viewHolder.itemView.getTag();
ComplicationItem complicationItem = mAdapter.getItem(tag);
startActivityForResult(ProviderChooserIntent.createProviderChooserIntent(
complicationItem.watchFace,
complicationItem.complicationId,
complicationItem.supportedTypes), PROVIDER_CHOOSER_REQUEST_CODE);
Если вы всё сделали правильно, то в результате в момент выбора у вас получится примерно такая картина:

Проверим интерфейс в деле: выбираем для левого complication отображение даты, а для правого — просто произвольное число.
Теперь, как только появятся новые данные в выбранных пользователем источниках информации, будет вызван метод onCompliationDataUpdate, все данные будут сохранены в SparseArray и при следующем вызове onDraw будут отображены на экране нашего циферблата.
Как видите, работа с «усложнениями» максимально проста: десяток-другой строк кода, и всё работает. Дело за малым — обновить ваши проекты и добавить поддержку новых возможностей. Удачи!
Автор: Google
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/razrabotka-pod-android/145584
Ссылки в тексте:
[1] Александр Куликовский: https://plus.google.com/+%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%9A%D1%83%D0%BB%D0%B8%D0%BA%D0%BE%D0%B2%D1%81%D0%BA%D0%B8%D0%B9
[2] Sebbia: http://sebbia.com/ru
[3] спецификации: https://developer.android.com/wear/preview/features/complications.html#receiving_data_and_rendering_complications
[4] таблице: https://developer.android.com/wear/preview/features/complications.html#types_and_fields
[5] Источник: https://habrahabr.ru/post/304260/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.