Обзор Android Shortcuts

в 9:57, , рубрики: android, android development, android shortcuts, Блог компании Тинькофф Банк, Разработка под android

С версии ОС Android 7.1 (API 25) Google предлагает нам новый механизм работы с приложениями — Android Shortcuts. Мы написали краткий обзор этой фичи, созданной для удобства пользователей.

image

Общий обзор

В переводе с английского «shortcut» — кратчайший путь, такое название хорошо отражает основное предназначение шорткатов. Они позволяют нам попасть в какую-то определенную точку приложения и выполнить конкретное действие всего за пару нажатий. Шорткаты неплохо смотрятся, например, если пользователю надо:
• выбрать заранее определенный маршрут в навигаторе;
• начать беседу с другом в мессенджере;
• продолжить игру с последней точки сохранения.

image

Основные компоненты

Шорткат включает в себя:
1) интент или массив интентов, которые запускают конкретное действие;
2) идентификатор или ID, определяющий именно этот шорткат;
3) короткое и длинное сообщения, отображающиеся при его показе;
4) иконка слева от текста.
Чтобы лучше разобраться в механике работы с шорткатами, рассмотрим их классификацию.

Виды шорткатов

Android предлагает 2 вида шорткатов (на самом деле их три, но об этом ниже): статические и динамические. Далее рассмотрим каждый тип шорткатов с небольшими примерами и пояснениями.

Статические шорткаты

Описание статических шорткатов содержится в xml-файле. Они создаются один раз, их нельзя удалить, добавить и изменить без обновления приложения, но их достаточно просто создать.

Пример создания

Файл shortcuts.xml, содержащийся в res/xml/:
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
  <shortcut
    android:shortcutId="id1"
    android:enabled="true"
    android:icon="@drawable/shortcut_search"
    android:shortcutShortLabel="@string/shortcut_short_label"
    android:shortcutLongLabel="@string/shortcut_long_label"
    android:shortcutDisabledMessage="@string/disabled_message">
    <intent
      android:action="android.intent.action.VIEW"
      android:targetPackage="com.example.myapplication"
      android:targetClass="com.example.myapplication.MainActivity" />
    <categories android:name="android.shortcut.conversation" />
  </shortcut>
</shortcuts>

И пара строк в AndroidManifest.xml:

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <meta-data android:name="android.app.shortcuts"
               android:resource="@xml/shortcuts" />
</activity>

Удалить шорткат или поменять его составляющие никак не получится, пока приложение не будет обновлено.
Статические шорткаты рекомендуется использовать для тех действий, которые точно никак не изменятся из-за пользовательских манипуляций с приложением и всегда будут доступны. Например, открыть новый поисковый запрос, перейти в настройки уведомлений, начать новую беседу. Однако использовать статический шорткат, к примеру, для того, чтобы отправлять пользователя сразу на экран авторизации — не очень хорошая идея. А что, если он уже авторизован? Тогда это действие не имеет смысла. В таких случаях нам пригодятся динамические шорткаты.

Динамические шорткаты

Их можно добавлять, удалять, изменять в режиме реального времени, то есть в зависимости от тех или иных событий. Вернемся к примеру с авторизацией: если пользователь не авторизован, то добавляем этот шорткат, как только авторизовался — удаляем.
Все взаимодействие с шорткатами программно происходит через класс ShortcutManager, доступный для 23 версии API, однако большинство его методов доступны только для 25 версии API. Операции с ними достаточно просты, но есть некоторые нюансы, которые будут подробно рассмотрены дальше.

Пример создания

ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);

ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "id1")
    .setShortLabel("Search")
    .setLongLabel("Start new search")
    .setIcon(Icon.createWithResource(context, R.drawable.shortcut_search))
    .setIntent(new Intent(Intent.ACTION_VIEW,
                   Uri.parse("shortcutapp://search")))
    .build();

shortcutManager.setDynamicShortcuts(Collections.singletonList(shortcut));

Удалять и изменять динамические шорткаты также достаточно просто:

Удаление
ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
shortcutManager.removeDynamicShortcuts(Arrays.asList("id1", "id2"));

Изменение

ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
shortcutManager.updateShortcuts(Arrays.asList(shortcut1, shortcut2));

Закрепленные шорткаты

На самом деле есть еще один вид шорткатов — это, если дословно переводить, «приколотые» или «закрепленные» (pinned) шорткаты. Выглядят они так:

image

Создавать такие шорткаты программным образом нельзя, как и удалять. Это может сделать только сам пользователь. Но с помощью кода их можно отключить (disableShortcuts()). Можно закреплять как статические, так и динамические шорткаты.

Статический случай

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

Динамический случай

Если удалить динамический шорткат, то вынесенный («закрепленный») соответствующий шорткат останется на месте, и его можно будет использовать. С одной стороны, это серьезное преимущество, позволяющее расширить число шорткатов, но с другой стороны, это потенциальный источник багов, так как удаление динамического шортката может быть связано и с удалением соответствующей функциональности для обработки действия.
Прежде, чем удалять динамический шорткат, убедитесь, что закрепленный тоже будет отключен, иначе это может вызвать проблемы в работе приложения.

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

Пример

ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
shortcutManager.disableShortcuts(Collections.singletonList(id), "Removed");

image

Мы ознакомились с шорткатами и основными принципами их работы в целом. Теперь можно перейти к деталям, особенностям и практическим советам.

Детали и тонкости применения

1. При добавлении шорткатов в большинстве случаев они будут отображаться от первого добавленного к последнему, первый добавленный будет ближе всех к иконке приложения. Сначала будут отображены статические, затем динамические.

Вид

image image

Ранги шорткатов

В Android Development утверждают, что у каждого шортката есть ранг — его можно получить, используя getRank(). Но самостоятельно этот ранг задать нельзя, его устанавливает ОС по своим соображениям. Пока во всех случаях, что нам встречались, этот ранг задавался в зависимости от очередности добавления. Ранг, к слову, это неотрицательное число, и чем ниже это число, тем «приоритетнее» считается шорткат, тем ближе он расположится к иконке приложения (ранг 0 — самый близкий).

2. При создании шортката необходимо установить длинное и короткое сообщения. Длинное сообщение указывается в списке, если оно не вмещается — то короткое. Google рекомендует устанавливать короткое сообщение не более 10 символов, а длинное — не более 25.

Дополнительные факты

Если оба сообщения чересчур велики, то будет отображено короткое в сокращенном виде. Также «закрепленные» шорткаты в любом случае подписываются коротким сообщением, даже если в коротком сообщении больше символов, чем в длинном.

3. Несмотря на то, что можно добавить максимально пять шорткатов, Google рекомендует не добавлять более четырех. Да и в списке больше четырех шорткатов не отобразится (последний добавленный не покажется). Зачем нужен пятый шорткат — загадка, ведь на планшетах он тоже не отображается.

4. У атрибута targetPackage статических шорткатов есть одна особенность — он может иметь только хардкод-значение. Если у Вас для разных сборок приложения используются различные суффиксы applicationId, то при объявлении шортката указать значение targetPackage ссылкой, например, @string/shortcut_target_package, не получится. Придется создавать файл shortcuts.xml отдельно для каждого buildFlavour приложения и прописывать необходимый targetPackage вручную с нужным суффиксом applicationId.

5. Важно, что Android сам никак не регулирует количество добавляемых шорткатов. Если вы по какой-то причине захотите добавить шестой шорткат, приложение просто упадет, выбросив IllegalArgumentException: Max number of dynamic shortcuts exceeded. Самостоятельно следите за количеством добавляемых шорткатов.

6. Если не задать хотя бы одному интенту шортката атрибут action, то в случае динамического шортката приложение упадет при создании этого шортката, а в случае статического — шорткат просто не будет создан. Отметим, что в extras интентов шортката нельзя положить некоторые типы, например, Serializable, допустимые типы можно увидеть в исходниках PersistableBundle.

7. Если попытаться вызвать getSystemService(ShortcutManager.class) на устройстве ниже 23 API, то приложение упадет с ClassNotFoundException.

8. При добавлении нескольких интентов к шорткату, которые обрабатываются разными активностями, можно выстроить определенный стек активностей. Самой нижней в этом стеке будет активность, обработавшая первый добавленный интент.

Реализация на практике

image

9. Если пользователь заблокирован на устройстве, то воспользоваться шорткатами у него не получится — они содержатся в зашифрованном хранилище.

10. Если пользователь хочет поддерживать приложение на другом устройстве, то только «закрепленные» шорткаты будут воссозданы на нем. Динамические и статические не воссоздаются, однако статические будут заново определены при установке приложения. Если вас волнует поддержка приложения на разных устройствах, и вы не поставили флаг allowBackup = false в Манифесте, нужно заботиться только о ручном воссоздании динамических шорткатов.

11. Android developers также предлагают нам использовать метод reportShortcutUsed(String id) при выполнении действия из соответствующего шортката — как при нажатии на шорткат, так и локально в приложении, если действие то же самое. Как утверждают разработчики, должна быть статистика использования тех или иных действий из шорткатов, и на основе этой статистики пользователю могут предлагаться определенные шорткаты. Возможно, именно здесь должен раскрыться потенциал пятого шортката.

Принцип работы

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

Напоследок парочка еще не упомянутых советов от Android developers.

1. Обновляйте шорткаты (updateShortcuts()), если их содержание и значение не изменилось, а изменилось только отображаемое сообщение или иконка. Если вы хотите убрать один шорткат и добавить другой, то не используйте обновление, выполните операции удаления, а затем добавления. Пренебрегая этим советом, можно получить разного рода казусы с «закрепленными» шорткатами.

2. Следуйте руководству по дизайну шорткатов. Это небольшой документ, которому нетрудно следовать.

Основное

• иконка должна быть круглой в общем случае (диаметр – 44 dp);
• внутри иконки должен быть простенький значок, вроде плюсика (размер — 24 х 24 dp);
• цвета должны соответствовать общей теме приложения;
• при выборе иконки помните, что она будет отображаться на «закрепленных» шорткатах вместе с основной иконкой приложения справа внизу, поэтому не стоит выбирать что-то наподобие такого:

image

Заключение

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

Автор: Тинькофф Банк

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js