Управление ярлыками

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

На этой странице описаны эти и другие распространенные способы управления ярлыками.

Поведение ярлыка

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

Видимость ярлыка

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

Класс LauncherApps предоставляет API, с помощью которых приложения для запуска могут получать доступ к ярлыкам.

Закрепленные ярлыки всегда видны на панели запуска. Закрепленный ярлык удаляется с панели запуска только в следующих случаях:

  • Пользователь удаляет его.
  • Приложение, связанное с ярлыком, удалено.
  • Пользователь удаляет данные приложения, выбрав Настройки > Приложения и уведомления, нажав на приложение и выбрав Хранилище > Очистить хранилище.

Цели отправки – это подмножество динамических ярлыков, которые появляются в строке прямой отправки на панели отправки Android.

Панель "Поделиться" в Android
Рисунок 1. Панель "Поделиться" в Android. Получатели Direct Share показываются в первой строке, за ними следуют приложения, отсортированные по частоте использования, а затем – список приложений.

Порядок показа ярлыков

Когда на панели запуска отображаются ярлыки приложения, они должны появляться в следующем порядке:

  1. Статические ярлыки. Метод isDeclaredInManifest() возвращает значение true.
  2. Динамические ярлыки. Ярлыки, для которых метод ShortcutInfo.isDynamic() возвращает значение true.

Внутри каждого типа ярлыки сортируются по возрастанию ранга в соответствии с ShortcutInfo.getRank. При выборе ярлыков для показа пользователям Google Ассистент также учитывает их рейтинг.

Ранги – это неотрицательные последовательные целые числа. Статические ярлыки ранжируются в том порядке, в котором они указаны в файле shortcuts.xml. Для динамических ярлыков можно обновить ранги существующих ярлыков при вызове updateShortcuts(Context, List), addDynamicShortcuts(Context, List), pushDynamicShortcut(Context, ShortcutInfoCompat) или setDynamicShortcuts(Context, List).

Порядок целей зависит от разных факторов, включая историю действий пользователя, давность, частоту, подсказку о ранге, использование приложения и приоритет, заданный для чата, который связан с ярлыком. Цели, созданные с помощью Sharing Shortcuts API, имеют приоритет над целями, созданными с помощью ChooserTargetService, который был объявлен устаревшим в Android 11. В Android 12 и более поздних версиях цели, созданные с помощью устаревшего класса ChooserTargetService, больше не будут показываться в окне "Поделиться".

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

Управление несколькими намерениями и действиями

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

Как запустить одно действие из другого

Статические ярлыки не могут иметь настраиваемые флаги намерений. Для первого намерения статического ярлыка всегда заданы флаги Intent.FLAG_ACTIVITY_NEW_TASK и Intent.FLAG_ACTIVITY_CLEAR_TASK. Это означает, что при запуске статического ярлыка все существующие действия в приложении будут уничтожены. Если вы хотите избежать такого поведения, используйте трамплин – невидимое действие, которое запускает другое действие. Для этого вызовите finish внутри блока launch или onCreate до того, как будет задан контент Compose:

  1. В файле AndroidManifest.xml file добавьте в действие-трамплин атрибут android:taskAffinity="".

  2. В файле ресурсов ярлыков укажите ссылку на действие-трамплин в намерении в статическом ярлыке.

Подробнее о запуске одного действия из другого…

Как задать флаги намерений

Вы можете публиковать динамические ярлыки с любым набором флагов Intent. Рекомендуется указать комбинацию Intent.FLAG_ACTIVITY_SINGLE_TOP и Intent.FLAG_ACTIVITY_CLEAR_TOP в намерении ярлыка. Это гарантирует, что если ComponentActivity уже активно, оно будет выведено на передний план и использовано повторно без уничтожения, что позволит вашей архитектуре с одним действием корректно обрабатывать событие ярлыка через onNewIntent().

Подробнее о задачах и флагах намерений рассказывается в статье Задачи и обратный стек.

Обновить ярлыки

Значок каждого приложения может содержать не больше статических и динамических ярлыков, чем возвращает метод getMaxShortcutCountPerActivity. Количество закрепленных ярлыков, которые может создать приложение, не ограничено.

Если издатель удалит динамический ярлык, закрепленный ярлык останется видимым и доступным для запуска. Это позволяет приложению иметь более getMaxShortcutCountPerActivity ярлыков.

Рассмотрим следующий пример, в котором предполагается, что значение, возвращаемое getMaxShortcutCountPerActivity, – это 4:

  1. Приложение для обмена сообщениями публикует четыре динамических ярлыка, представляющих четыре последних чата: c1, c2, c3 и c4.
  2. Пользователь закрепляет все четыре ярлыка.
  3. Позже пользователь начинает ещё три чата: c5, c6 и c7. Приложение-издатель повторно публикует свои динамические ярлыки. Новый список динамических ярлыков: c4, c5, c6 и c7.

Приложению придется удалить c1, c2 и c3, поскольку оно не может показывать больше четырех динамических ярлыков. Однако c1, c2 и c3 по-прежнему являются закрепленными ярлыками, к которым пользователь может получить доступ и запустить их.

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

  1. Приложение может использовать updateShortcuts(Context, List), чтобы обновить любой из семи существующих ярлыков. Например, вы можете обновить этот набор ярлыков, когда изменятся значки собеседников в чате.
  2. Вы можете использовать методы addDynamicShortcuts(Context, List) и setDynamicShortcuts(Context, List), чтобы обновить существующие ярлыки с теми же идентификаторами. Однако вы не можете использовать их для обновления нединамических закрепленных ярлыков, поскольку эти два метода пытаются преобразовать заданные списки ярлыков в динамические.

Количество ярлыков, которые можно передать для показа в приложениях-помощниках, таких как Google Ассистент, не ограничено. Используйте метод pushDynamicShortcut библиотеки ShortcutManagerCompat Jetpack, чтобы создавать и обновлять ярлыки для приложений-помощников. Также добавьте в приложение библиотеку Google Shortcuts Integration, чтобы динамические ссылки могли появляться в Google Ассистенте.

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

Как обрабатывать изменения региональных настроек системы

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

Отслеживание использования ярлыков

Чтобы определить, в каких ситуациях должны появляться статические и динамические ярлыки, лаунчер анализирует историю их активации. Для статических ярлыков вы можете отслеживать, когда пользователи выполняют определенные действия в приложении, вызывая метод reportShortcutUsed и передавая ему идентификатор ярлыка при возникновении любого из следующих событий:

  • Пользователь выбирает ярлык с заданным идентификатором.
  • В приложении пользователь вручную выполняет действие, соответствующее тому же ярлыку.

Приложение отслеживает использование динамических ярлыков, вызывая метод pushDynamicShortcut и передавая ему идентификатор ярлыка при возникновении соответствующего события. При таком способе приложения-помощники, например Google Ассистент, могут предлагать пользователям подходящие ярлыки. Поскольку метод pushDynamicShortcut сообщает об использовании при вызове, не вызывайте метод reportShortcutUsed для тех же ярлыков.

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

Отключить ярлыки быстрого доступа

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

Ограничение частоты запросов

При использовании методов setDynamicShortcuts, addDynamicShortcuts или updateShortcuts вы можете вызывать их только определенное количество раз в фоновом приложении – приложении без действий или служб на переднем плане. Ограничение на количество вызовов этих методов называется ограничением частоты запросов. Эта функция предотвращает чрезмерное потребление ресурсов устройства приложением ShortcutManagerCompat.

Когда ограничение частоты запросов активно, isRateLimitingActive возвращает значение true. Однако ограничение частоты запросов сбрасывается при определенных событиях, поэтому даже фоновые приложения могут вызывать методы ShortcutManager, пока ограничение не будет достигнуто снова. К ним относятся:

  • Приложение переходит в активный режим.
  • Изменились региональные настройки системы.
  • Пользователь выполняет действие Встроенный ответ в уведомлении.

Если вы столкнулись с ограничением частоты запросов во время разработки или тестирования, выберите Для разработчиков > Сбросить ограничение частоты запросов ShortcutManager в настройках устройства или введите следующую команду в adb:

adb shell cmd shortcut reset-throttling [ --user your-user-id ]

резервное копирование и восстановление;

Вы можете разрешить пользователям выполнять резервное копирование и восстановление данных приложения при смене устройства. Для этого добавьте атрибут android:allowBackup="true" в файл манифеста приложения. Если вы поддерживаете резервное копирование и восстановление, помните о следующем:

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

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

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (ShortcutManagerCompat.getDynamicShortcuts(this).isEmpty()) {
            // Application restored. Re-publish dynamic shortcuts.
            if (ShortcutManagerCompat.getShortcuts(this, ShortcutManagerCompat.FLAG_MATCH_PINNED).isNotEmpty()) {
                // Pinned shortcuts are restored. Use updateShortcuts() to make
                // sure they contain up-to-date information.
            }
        }
    }
    // ...
}