Статьи

Сигналы и микровзаимодействия для умных часов: практический

В предыдущей статье я представил два принципа дизайна, предназначенных для носимых устройств, сигналов и микровзаимодействий. В этой статье мы создадим пример проекта Android Wear, чтобы показать, как эти принципы применяются на практике.

Представьте, что вы находитесь в последний час войны за столь желанный предмет. Последнее, что вы хотите, и то, что часто случается, — это перебазирование непосредственно перед закрытием заявки. В этом сценарии есть очевидные преимущества наличия умных часов, которые позволяют вам удобно отслеживать такую ​​ставку и своевременно предпринимать действия, не беспокоя вас, пользователя. В нашем примере проекта мы рассмотрим, как мы можем реализовать это на устройстве Android Wear.

Торговый сайт, на котором мы будем основывать наш пример, называется TradeMe , эквивалент моей страны в eBay. Как и большинство успешных онлайн-сервисов, TradeMe предоставляет чистый и простой API, который предоставляет большую часть функциональности разработчикам. Поскольку эта статья посвящена Android Wear, мы сосредоточимся только на коде, связанном с Android Wear.

Блок-схема ниже показывает основную логику нашего проекта.

Основная часть этой логики обрабатывается службой BidWatcherService на сопряженном контроллере, где она обычно опускает список наблюдения пользователя. Для каждого элемента служба проверяет, были ли внесены какие-либо изменения и был ли пользователь перекуплен. Для тех, которые соответствуют этим критериям, служба создает уведомление, посредством которого пользователь уведомляется об изменениях и предоставляет возможность легко предпринять действия, например, повысить свою ставку.

Фактический код Android Wear занимает очень мало общего приложения, но, как мы надеемся, подчеркивается в этой статье, проблема заключается в разработке соответствующего контекстного опыта, а не фактической реализации. Конечно, вы можете создать собственный сложный пользовательский интерфейс, если пожелаете.

Чтобы использовать функции, специфичные для Android Wear, необходимо убедиться, что ваш проект ссылается на библиотеку поддержки v4 . Начнем с получения ссылки на менеджер уведомлений системы во время инициализации. Для этого мы используем класс NotificationManagerCompat из библиотеки поддержки, а не класс NotificationManager .

1
2
3
protected NotificationManagerCompat mNotificationManager;
mNotificationManager = NotificationManagerCompat.from(mContext);

Для каждого элемента нашего списка отслеживания, который изменился и считается достаточно важным для уведомления пользователя, мы создаем и показываем уведомление.

1
2
3
4
5
6
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.small_icon)
    .setContentTitle(mContext.getString(R.string.title_auction_update))
    .setContentText(item.mTitle);
 
mNotificationManager.notify(notificationId, notificationBuilder.build());

Вот и все. Теперь мы можем уведомлять пользователя о любых просматриваемых элементах, которые изменились. Это показано на скриншотах ниже.

На приведенных выше снимках экрана показана эмулированная версия нашего уведомления на устройстве Android Wear. Крайний левый скриншот показывает предварительный просмотр уведомления. В центре и на самых правых скриншотах отображаются уведомления в фокусе.

Мы можем, как предполагает документация Android Wear, сделать эту информацию более наглядной, добавив фоновое изображение к уведомлению, чтобы придать ему больше контекста. Есть два способа добиться этого. Мы можем установить BigIcon уведомления, используя метод setBigIcon или расширив уведомление объектом WearableExtender и установив его фоновое изображение. Поскольку мы ориентируемся на Android Wear, мы будем использовать класс WearableExtender .

Как следует из его названия, класс WearableExtender является вспомогательным классом, который упаковывает расширения уведомлений, характерные для носимых устройств. Следующий код демонстрирует, как мы добавляем фоновое изображение в наши уведомления.

01
02
03
04
05
06
07
08
09
10
11
NotificationCompat.WearableExtender wearableExtender = new NotificationCompat.WearableExtender();
 
wearableExtender.setBackground(
  BitmapFactory.decodeResource(
    getResources(), R.drawable.notification_background));
 
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
  .setSmallIcon(R.drawable.small_icon)
  .setContentTitle(mContext.getString(R.string.title_auction_update))
  .setContentText(item.mTitle)
  .extend(wearableExtender);

Мы создаем объект WearableExtender , устанавливаем его фон и назначаем его уведомлению, используя метод extend . На следующем снимке экрана показано обновленное уведомление.

У меня есть три пункта в моем списке наблюдения. На данный момент у меня есть отдельная карта для каждого из предметов. При разработке уведомлений для портативного устройства мы использовали бы сводное уведомление, но это не очень хорошо подходит для устройств Android Wear. По этой причине была введена концепция стека .

Стеки создаются путем назначения связанных уведомлений одной и той же группе. Это позволяет пользователю отбрасывать или игнорировать их как группу или расширять их для обработки каждого уведомления в отдельности. Это достигается путем установки group каждого уведомления с использованием метода setGroup как показано в следующем блоке кода.

1
2
3
4
5
6
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
 .setSmallIcon(R.drawable.small_icon)
 .setContentTitle(mContext.getString(R.string.title_auction_update))
 .setContentText(item.mTitle)
 .setGroup(NOTIFICATION_GROUP_KEY)
 .extend(wearableExtender);

На следующих снимках экрана показаны примеры размещения и расширения уведомлений.

Стеки являются заменой сводных уведомлений на портативном устройстве. Стеки не отображаются на контроллере, и поэтому вам необходимо явно создать сводное уведомление для контроллеров. Аналогично тому, что мы делали в приведенном выше блоке кода, установите группу уведомлений, используя метод setGroup , для группы стеков, но также установите для сводки группы значение true , вызвав метод setGroupSummary .

В некоторых случаях вы можете захотеть отобразить более подробную информацию для пользователя. Это может быть полезно для предоставления пользователю дополнительной информации, не требуя от него извлечения карманного компьютера. По этой причине в Android Wear есть страницы . Страницы позволяют назначать дополнительные карты уведомлению, чтобы предоставить больше информации. Они выявлены, проводя влево.

Чтобы добавить дополнительную страницу, мы просто создаем новое уведомление и добавляем его в наш объект WearableExtender используя метод addPage .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
BigTextStyle autionDetailsPageStyle =
  new NotificationCompat.BigTextStyle()
    .setBigContentTitle(mContext.getString(R.string.title_auction_details))
    .bigText(String.format(this.getString(
      R.string.copy_notification_details),
      item.mMaxBidAmount,
      item.getTimeRemainingAsString(),
      item.mBidCount));
                   
Notification detailsPageNotification = new NotificationCompat.Builder(this)
  .setSmallIcon(R.drawable.small_icon)
  .setStyle(autionDetailsPageStyle)
  .build();
  
NotificationCompat.WearableExtender wearableExtender = new NotificationCompat.WearableExtender();
 
wearableExtender.setBackground(
  BitmapFactory.decodeResource(getResources(),
  R.drawable.notification_background));
  wearableExtender.addPage(detailsPageNotification);

На следующих снимках экрана показано уведомление с двумя страницами. Теперь мы предоставляем пользователю своевременную и актуальную информацию.

Последний шаг — сделать эту информацию действенной. Для этого мы добавляем действия, как мы делали с уведомлениями ранее. Два действия, которые мы добавляем, позволяют пользователю автоматически увеличивать ставку или явно устанавливать ставку.

Давайте сначала добавим автоматическую ставку. Следующий фрагмент кода должен выглядеть знакомым любому разработчику Android.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Intent defaultBidIntent = new Intent(DEFAULT_BID_ACTION)
  .putExtra(EXTRA_WATCHLIST_ITEM, item)
  .putExtra(EXTRA_NOTIFICATION_ID, notificationId);
 
PendingIntent pendingDefaultBidIntent = PendingIntent.getBroadcast(
  mContext,
  0,
  defaultBidIntent,
  PendingIntent.FLAG_UPDATE_CURRENT);
 
NotificationCompat.Action defaultBidAction = new NotificationCompat.Action.Builder(
  R.drawable.icon_action_bid,
  mContext.getString(R.string.label_auto_bid),
  pendingDefaultBidIntent).build();
 
NotificationCompat.WearableExtender wearableExtender = new NotificationCompat.WearableExtender();
 
wearableExtender.setBackground(
  BitmapFactory.decodeResource(getResources(),
  R.drawable.notification_background));
 
wearableExtender.addPage(detailsPageNotification);
wearableExtender.addAction(defaultBidAction);

На следующих снимках экрана показано действие и состояние подтверждения.

Вторым действием мы хотим разрешить пользователю устанавливать конкретную цену. Работая с ограничениями устройства Android Wear, мы предлагаем следующие варианты:

  • запустить соответствующий экран на контроллере
  • обеспечить шаговый контроль, который пользователь может использовать для увеличения текущей ставки
  • предоставить пользователю некоторые предопределенные параметры
  • позволить пользователю использовать свой голос

Одним из привлекательных аспектов Android Wear является его архитектура и дизайн в отношении голоса. Это имеет смысл, учитывая форм-фактор и контекст, в котором используется носимое устройство, такое как умные часы.

Реализация этого аналогична описанной выше, но в дополнение к объекту RemoteInput мы создаем экземпляр объекта RemoteInput и назначаем его действию. Экземпляр RemoteInput позаботится обо всем остальном.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Intent customBidIntent = new Intent(CUSTOM_BID_ACTION)
  .putExtra(EXTRA_WATCHLIST_ITEM, item)
  .putExtra(EXTRA_NOTIFICATION_ID, notificationId);
 
PendingIntent pendingCustomBidIntent = PendingIntent.getBroadcast(
  mContext,
  0,
  customBidIntent,
  PendingIntent.FLAG_UPDATE_CURRENT);
 
RemoteInput remoteInput = new RemoteInput
  .Builder(EXTRA_BID_AMOUNT)
  .setLabel(mContext.getString(R.string.copy_specify_bid))
  .build();
 
NotificationCompat.Action customBidAction = new NotificationCompat.Action
  .Builder(
    R.drawable.icon_action_bid,
    mContext.getString(R.string.label_bid),
    pendingCustomBidIntent).addRemoteInput(remoteInput).build();
 
NotificationCompat.WearableExtender wearableExtender = new NotificationCompat.WearableExtender();
 
wearableExtender.setBackground(
  BitmapFactory.decodeResource(getResources(),
  R.drawable.notification_background));
 
wearableExtender.addPage(detailsPageNotification);
wearableExtender.addAction(defaultBidAction).addAction(customBidAction);

Объект RemoteInput принимает строку в конструкторе. Эта строка EXTRA_BID_AMOUNT является идентификатором, используемым получателем широковещательной передачи при получении результата, как показано ниже.

1
2
3
4
5
6
7
8
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput != null) {
  CharSequence inputAsCharSequence = remoteInput.getCharSequence(EXTRA_BID_AMOUNT);
 
  if( inputAsCharSequence != null ){
    input = inputAsCharSequence.toString();
  }
}

На следующем RemoteInput экрана показан пример экземпляра RemoteInput в действии.

Очевидным расширением этого было бы предоставление пользователю возможности явно запрашивать обновление. Чтобы реализовать это, вы должны создать Activity для устройства Android Wear, которое слушает голосовые команды. После получения передайте запрос на сопряженное мобильное устройство и завершите действие. Но это в другой раз.

На этом завершается наш пример проекта, в котором мы теперь предлагаем пользователям актуальную и полезную информацию, предоставляя ее им с минимальными помехами. Как упоминалось в предыдущей статье , Android Wear позволяет вам реализовывать все, что вы захотите, но я надеюсь, что в этой статье показано, как расширенные уведомления являются эффективным и действенным способом распространения вашего сервиса на устройства Android Wear.