Engage SDK Social: инструкции по технической интеграции сторонних разработчиков

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

Этот документ содержит инструкции для партнеров-разработчиков по интеграции своего социального контента с помощью Engage SDK для заполнения этой новой области поверхности.

Детали интеграции

В следующем разделе описываются детали интеграции.

Терминология

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

Ваши рекомендации имеют следующую структуру:

Кластер рекомендаций : представление пользовательского интерфейса, содержащее группу рекомендаций от одного и того же партнера-разработчика.

Каждый кластер рекомендаций состоит из одного из следующих двух типов объектов:

  • ПортретСМИСущность
  • СоциальнаяПостEntity

PortraitMediaEntity должен содержать 1 портретное изображение для публикации. Метаданные, связанные с профилем и взаимодействием, не являются обязательными.

  • Почта

    • Изображение в портретном режиме и отметка времени или
    • Изображение в портретном режиме + текстовое содержимое и временная метка
  • Профиль

    • Аватар, Имя или ник, Дополнительное изображение
  • Взаимодействия

    • Только подсчитайте и пометьте, или
    • Счет и визуальное (значок)

SocialPostEntity содержит метаданные, связанные с профилем, публикацией и взаимодействием.

  • Профиль

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

    • Текст и временная метка или
    • Мультимедийная информация (изображение или расширенный URL-адрес) и временная метка или
    • Текст и мультимедийные материалы (изображение или расширенный URL-адрес) и временная метка или
    • Предварительный просмотр видео (миниатюра и продолжительность) и временная метка
  • Взаимодействия

    • Только подсчет и маркировка, или
    • Подсчет и визуальное отображение (значок)

Предварительная работа

Минимальный уровень API: 19

Добавьте библиотеку com.google.android.engage:engage-core в свое приложение:

dependencies {
    // Make sure you also include that repository in your project's build.gradle file.
    implementation 'com.google.android.engage:engage-core:1.5.2'
}

Краткое содержание

Проект основан на реализации привязанного сервиса .

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

Тип кластера Ограничения кластера Минимальные ограничения на сущности в кластере Максимальные ограничения объектов в кластере
Кластер(ы) рекомендаций Максимум 5 Не менее 5 ( PortraitMediaEntity или SocialPostEntity ). Не более 25 ( PortraitMediaEntity или SocialPostEntity ).

Шаг 1. Предоставьте данные об объекте

В SDK определены разные объекты для представления каждого типа элементов. SDK поддерживает следующие объекты категории «Социальные сети»:

  1. PortraitMediaEntity
  2. SocialPostEntity

В таблицах ниже показаны доступные атрибуты и требования для каждого типа.

PortraitMediaEntity

Атрибут Требование Описание Формат
URI действия Необходимый

Глубокая ссылка на объект в приложении поставщика.

Примечание. Для атрибуции можно использовать глубокие ссылки. Обратитесь к этому FAQ

URI
Метаданные, связанные с публикацией (обязательно)
Изображения Необходимый

Изображения должны быть в портретном соотношении сторон.

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

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

Дополнительные сведения см. в разделе «Спецификации изображения» .
Текстовый контент Необязательный Основной текст поста, апдейта и т.п. Строка (рекомендуется максимум 140 символов)
Временная метка Необязательный Время публикации поста. Временная метка эпохи в миллисекундах
Видеоконтент Необязательный Пост это видео? логическое значение
Продолжительность видео Необязательный Длительность видео в миллисекундах. Длинный
Метаданные, связанные с профилем (необязательно)
Имя Необходимый Имя профиля, идентификатор или дескриптор, например «Джон Доу», «@TeamPixel». Строка (рекомендуется максимум 25 символов)
Аватар Необходимый

Изображение профиля или изображение аватара пользователя.

Квадратное изображение 1:1

Дополнительные сведения см. в разделе «Спецификации изображения» .
Дополнительное изображение Необязательный

Значок профиля. например - проверенный значок

Квадратное изображение 1:1

Дополнительные сведения см. в разделе «Спецификации изображения» .
Метаданные, связанные с взаимодействиями (необязательно)
Считать Необязательный

Укажите количество взаимодействий, например – «3,7 М.».

Примечание. Если указаны и Count, и Count Value, будет использоваться Count.

Нить

Рекомендуемый размер текста: максимум 20 символов для количества и метки вместе взятых.

Значение подсчета Необязательный

Количество взаимодействий как величина.

Примечание. Укажите значение числа вместо числа, если ваше приложение не обрабатывает логику оптимизации большого числа для разных размеров дисплея. Если указаны и Count, и Count Value, используется Count.

Длинный
Этикетка Необязательный Укажите, для чего нужна метка взаимодействия. Например – «Нравится».

Нить

Рекомендуемый размер текста: максимум 20 символов для количества и метки вместе взятых.

Визуальный Необязательный

Укажите, для чего предназначено взаимодействие. Например: изображение со значком «Нравится» и смайликом.

Можно предоставить более 1 изображения, но не все могут отображаться во всех форм-факторах.

Примечание. Должно быть квадратное изображение 1:1.

Дополнительные сведения см. в разделе «Спецификации изображения» .
DisplayTimeWindow (необязательно) — установите временное окно для отображения содержимого на поверхности.
Начальная временная метка Необязательный

Временная метка эпохи, после которой содержимое должно отображаться на поверхности.

Если не установлено, контент может отображаться на поверхности.

Временная метка эпохи в миллисекундах
Конечная временная метка Необязательный

Временная метка эпохи, после которой содержимое больше не отображается на поверхности.

Если не установлено, контент может отображаться на поверхности.

Временная метка эпохи в миллисекундах

SocialPostEntity

Атрибут Требование Описание Формат
URI действия Необходимый

Глубокая ссылка на объект в приложении поставщика.

Примечание. Для атрибуции можно использовать глубокие ссылки. Обратитесь к этому FAQ

URI

Метаданные, связанные с публикацией (обязательно)

Требуется хотя бы один из TextContent, Image или WebContent.

Изображения Необязательный

Изображения должны быть в портретном соотношении сторон.

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

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

Дополнительные сведения см. в разделе «Спецификации изображения» .
Текстовый контент Необязательный Основной текст поста, апдейта и т.п. Строка (рекомендуется максимум 140 символов)
Видеоконтент (необязательно)
Продолжительность Необходимый Длительность видео в миллисекундах. Длинный
Изображение Необходимый Предварительный просмотр видеоконтента. Дополнительные сведения см. в разделе «Спецификации изображения» .
Предварительный просмотр ссылки (необязательно)
Предварительный просмотр ссылки — заголовок Необходимый Текст, обозначающий заголовок содержимого веб-страницы. Нить
Предварительный просмотр ссылки — имя хоста Необходимый Текст, обозначающий владельца веб-страницы, например «INSIDER». Нить
Предварительный просмотр ссылки — изображение Необязательный Главное изображение для веб-контента Дополнительные сведения см. в разделе «Спецификации изображения» .
Временная метка Необязательный Время публикации поста. Временная метка эпохи в миллисекундах
Метаданные, связанные с профилем (необязательно)
Имя Необходимый Имя, идентификатор или дескриптор профиля, например «Джон Доу», «@TeamPixel». Строка (рекомендуется максимум 25 символов)
Дополнительный текст Необязательный

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

Например, «@Джон-Доу», «5 миллионов подписчиков», «Вам может понравиться», «В тренде», «5 новых сообщений».

Строка (рекомендуется максимум 40 символов)
Аватар Необходимый

Изображение профиля или изображение аватара пользователя.

Квадратное изображение 1:1

Дополнительные сведения см. в разделе «Спецификации изображения» .
Дополнительное изображение Необязательный

Значок профиля, например — проверенный значок.

Квадратное изображение 1:1

Дополнительные сведения см. в разделе «Спецификации изображения» .
Метаданные, связанные с взаимодействиями (необязательно)
Считать Необходимый Укажите количество взаимодействий, например – «3,7 М». Строка (рекомендуется максимум 20 символов для количества и метки вместе взятых)
Этикетка

Необязательный

Если не указано, необходимо предоставить Visual .

Укажите, для чего предназначено взаимодействие. Например – «Нравится». Строка (рекомендуется максимум 20 символов для количества и метки вместе взятых)
Визуальный

Необязательный

Если не указано, необходимо предоставить метку .

Укажите, для чего предназначено взаимодействие. Например: изображение со значком «Нравится» и смайликом.

Можно предоставить более 1 изображения, но не все могут отображаться во всех форм-факторах.

Квадратное изображение 1:1

Дополнительные сведения см. в разделе «Спецификации изображения» .
DisplayTimeWindow (необязательно) — установите временное окно для отображения содержимого на поверхности.
Начальная временная метка Необязательный

Временная метка эпохи, после которой содержимое должно отображаться на поверхности.

Если не установлено, контент может отображаться на поверхности.

Временная метка эпохи в миллисекундах
Конечная временная метка Необязательный

Временная метка эпохи, после которой содержимое больше не отображается на поверхности.

Если не установлено, контент может отображаться на поверхности.

Временная метка эпохи в миллисекундах

Характеристики изображения

Изображения должны размещаться на общедоступных CDN, чтобы Google мог получить к ним доступ.

Форматы файлов

PNG, JPG, статический GIF, WebP

Максимальный размер файла

5120 КБ

Дополнительные рекомендации

  • Безопасная область изображения: поместите важный контент в центр 80% изображения.
  • Используйте прозрачный фон, чтобы изображение правильно отображалось в настройках темной и светлой темы.

Шаг 2. Предоставьте данные кластера

Рекомендуется, чтобы задание публикации контента выполнялось в фоновом режиме (например, с помощью WorkManager ) и планировалось на регулярной основе или на основе событий (например, каждый раз, когда пользователь открывает приложение или когда пользователь только что подписался на новое счет)

AppEngageSocialClient отвечает за публикацию социальных кластеров.

Существуют следующие API для публикации кластеров в клиенте:

  • isServiceAvailable
  • publishRecommendationClusters
  • publishUserAccountManagementRequest
  • updatePublishStatus
  • deleteRecommendationsClusters
  • deleteUserManagementCluster
  • deleteClusters

isServiceAvailable

Этот API используется для проверки доступности сервиса для интеграции и возможности представления контента на устройстве.

Котлин

client.isServiceAvailable.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Handle IPC call success
        if(task.result) {
          // Service is available on the device, proceed with content
          // publish calls.
        } else {
          // Service is not available, no further action is needed.
        }
    } else {
      // The IPC call itself fails, proceed with error handling logic here,
      // such as retry.
    }
}

Ява

client.isServiceAvailable().addOnCompleteListener(task - > {
    if (task.isSuccessful()) {
        // Handle success
        if(task.getResult()) {
          // Service is available on the device, proceed with content
          // publish calls.
        } else {
          // Service is not available, no further action is needed.
        }
    } else {
      // The IPC call itself fails, proceed with error handling logic here,
      // such as retry.
    }
});

publishRecommendationClusters

Этот API используется для публикации списка объектов RecommendationCluster .

Объект RecommendationCluster может иметь следующие атрибуты:

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

Название кластера рекомендаций (например, «Последние от ваших друзей »).

Рекомендуемый размер текста: до 25 символов (слишком длинный текст может содержать многоточие).

Субтитры Необязательный Подзаголовок кластера рекомендаций.
Действие Ури Необязательный

Глубокая ссылка на страницу партнерского приложения, где пользователи могут увидеть полный список рекомендаций.

Примечание. Для атрибуции можно использовать глубокие ссылки. Обратитесь к этому FAQ

Котлин

client.publishRecommendationClusters(
            PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Latest from your friends")
                        .build())
                .build())

Ява

client.publishRecommendationClusters(
            new PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    new RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Latest from your friends")
                        .build())
                .build());

Когда сервис получает запрос, в рамках одной транзакции происходят следующие действия:

  • Все существующие данные кластера рекомендаций будут удалены.
  • Данные запроса анализируются и сохраняются в новых кластерах рекомендаций.

В случае ошибки весь запрос отклоняется и существующее состояние сохраняется.

publishUserAccountManagementRequest

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

Следующие метаданные являются частью карты входа:

Атрибут Требование Описание
Действие Ури Необходимый Глубокая ссылка на действие (т. е. переход на страницу входа в приложение)
Изображение Необязательно: если не указано, необходимо указать название.

Изображение на карте

Изображения с соотношением сторон 16x9 и разрешением 1264x712.

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

Котлин

var SIGN_IN_CARD_ENTITY =
      SignInCardEntity.Builder()
          .addPosterImage(
              Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(500)
                  .setImageWidthInPixel(500)
                  .build())
          .setActionText("Sign In")
          .setActionUri(Uri.parse("http://xx.com/signin"))
          .build()

client.publishUserAccountManagementRequest(
            PublishUserAccountManagementRequest.Builder()
                .setSignInCardEntity(SIGN_IN_CARD_ENTITY)
                .build());

Ява

SignInCardEntity SIGN_IN_CARD_ENTITY =
      new SignInCardEntity.Builder()
          .addPosterImage(
              new Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(500)
                  .setImageWidthInPixel(500)
                  .build())
          .setActionText("Sign In")
          .setActionUri(Uri.parse("http://xx.com/signin"))
          .build();

client.publishUserAccountManagementRequest(
            new PublishUserAccountManagementRequest.Builder()
                .setSignInCardEntity(SIGN_IN_CARD_ENTITY)
                .build());

Когда сервис получает запрос, в рамках одной транзакции происходят следующие действия:

  • Существующие данные UserAccountManagementCluster от партнера-разработчика удаляются.
  • Данные запроса анализируются и сохраняются в обновленном кластере UserAccountManagementCluster.

В случае ошибки весь запрос отклоняется и существующее состояние сохраняется.

updatePublishStatus

Если по каким-либо внутренним бизнес-причинам ни один из кластеров не опубликован, мы настоятельно рекомендуем обновить статус публикации с помощью API updatePublishStatus . Это важно, потому что:

  • Предоставление статуса во всех сценариях, даже когда контент опубликован (СТАТУС == ПУБЛИКИРОВАНО), имеет решающее значение для заполнения панелей мониторинга, которые используют этот явный статус для передачи работоспособности и других показателей вашей интеграции.
  • Если контент не опубликован, но статус интеграции не нарушен (STATUS == NOT_PUBLISHED), Google может избежать появления оповещений на панелях состояния приложения. Это подтверждает, что контент не публикуется по причине ожидаемой с точки зрения провайдера ситуации.
  • Это помогает разработчикам получить представление о том, когда данные публикуются, а когда нет.
  • Google может использовать коды состояния, чтобы подтолкнуть пользователя к выполнению определенных действий в приложении, чтобы он мог увидеть содержимое приложения или преодолеть его.

Список подходящих кодов статуса публикации:

// Content is published
AppEngagePublishStatusCode.PUBLISHED,

// Content is not published as user is not signed in
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN,

// Content is not published as user is not subscribed
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SUBSCRIPTION,

// Content is not published as user location is ineligible
AppEngagePublishStatusCode.NOT_PUBLISHED_INELIGIBLE_LOCATION,

// Content is not published as there is no eligible content
AppEngagePublishStatusCode.NOT_PUBLISHED_NO_ELIGIBLE_CONTENT,

// Content is not published as the feature is disabled by the client
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_FEATURE_DISABLED_BY_CLIENT,

// Content is not published as the feature due to a client error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_CLIENT_ERROR,

// Content is not published as the feature due to a service error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_SERVICE_ERROR,

// Content is not published due to some other reason
// Reach out to engage-developers@ before using this enum.
AppEngagePublishStatusCode.NOT_PUBLISHED_OTHER

Если контент не публикуется из-за того, что пользователь не вошел в систему, Google рекомендует опубликовать карту входа. Если по какой-либо причине поставщики не могут опубликовать карту входа, мы рекомендуем вызвать API updatePublishStatus с кодом состояния NOT_PUBLISHED_REQUIRES_SIGN_IN.

Котлин

client.updatePublishStatus(
   PublishStatusRequest.Builder()
     .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN)
     .build())

Ява

client.updatePublishStatus(
    new PublishStatusRequest.Builder()
        .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN)
        .build());

deleteRecommendationClusters

Этот API используется для удаления содержимого кластеров рекомендаций.

Котлин

client.deleteRecommendationClusters()

Ява

client.deleteRecommendationClusters();

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

deleteUserManagementCluster

Этот API используется для удаления содержимого кластера UserAccountManagement.

Котлин

client.deleteUserManagementCluster()

Ява

client.deleteUserManagementCluster();

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

deleteClusters

Этот API используется для удаления содержимого кластера определенного типа.

Котлин

client.deleteClusters(
    DeleteClustersRequest.Builder()
      .addClusterType(ClusterType.TYPE_RECOMMENDATION)
      ...
      .build())

Ява

client.deleteClusters(
            new DeleteClustersRequest.Builder()
                .addClusterType(ClusterType.TYPE_RECOMMENDATION)
                ...
                .build());

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

Обработка ошибок

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

client.publishRecommendationClusters(
              new PublishRecommendationClustersRequest.Builder()
                  .addRecommendationCluster(...)
                  .build())
          .addOnCompleteListener(
              task -> {
                if (task.isSuccessful()) {
                  // do something
                } else {
                  Exception exception = task.getException();
                  if (exception instanceof AppEngageException) {
                    @AppEngageErrorCode
                    int errorCode = ((AppEngageException) exception).getErrorCode();
                    if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) {
                      // do something
                    }
                  }
                }
              });

Ошибка возвращается как AppEngageException , а причина указывается в виде кода ошибки.

Код ошибки Название ошибки Примечание
1 SERVICE_NOT_FOUND Услуга недоступна на данном устройстве.
2 SERVICE_NOT_AVAILABLE Услуга доступна на данном устройстве, но недоступна на момент звонка (например, отключена явно).
3 SERVICE_CALL_EXECUTION_FAILURE Выполнение задачи не удалось из-за проблем с потоками. В этом случае его можно повторить.
4 SERVICE_CALL_PERMISSION_DENIED Вызывающий абонент не имеет права совершать вызов службы.
5 SERVICE_CALL_INVALID_ARGUMENT Запрос содержит недопустимые данные (например, количество кластеров превышает допустимое).
6 SERVICE_CALL_INTERNAL Ошибка на стороне сервиса.
7 SERVICE_CALL_RESOURCE_EXHAUSTED Вызов службы поддержки осуществляется слишком часто.

Шаг 3. Обработка намерений трансляции

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

Целью широковещательных намерений является главным образом повторная активация приложений и принудительная синхронизация данных. Широковещательные намерения не предназначены для частой отправки. Он срабатывает только тогда, когда служба Engage определяет, что контент может быть устаревшим (например, недельной давности). Таким образом, появляется больше уверенности в том, что пользователь сможет получить новый контент, даже если приложение не запускалось в течение длительного периода времени.

BroadcastReceiver необходимо настроить двумя следующими способами:

  • Динамически зарегистрируйте экземпляр класса BroadcastReceiver с помощью Context.registerReceiver() . Это позволяет осуществлять связь с приложениями, которые все еще находятся в памяти.
class AppEngageBroadcastReceiver extends BroadcastReceiver {
// Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION broadcast
// is received
}

public static void registerBroadcastReceivers(Context context) {

context = context.getApplicationContext();

// Register Recommendation Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_RECOMMENDATION));

}

  • Статически объявите реализацию с помощью тега <receiver> в файле AndroidManifest.xml . Это позволяет приложению получать широковещательные намерения, когда оно не запущено, а также позволяет приложению публиковать контент.
<application>
   <receiver
      android:name=".AppEngageBroadcastReceiver"
      android:exported="true"
      android:enabled="true">
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_RECOMMENDATION" />
      </intent-filter>
   </receiver>
</application>

Служба отправит следующие намерения :

  • com.google.android.engage.action.PUBLISH_RECOMMENDATION При получении этого намерения рекомендуется запустить publishRecommendationClusters .

Рабочий процесс интеграции

Пошаговое руководство по проверке интеграции после ее завершения см. в разделе Рабочий процесс интеграции с разработчиками .

Часто задаваемые вопросы

См . Часто задаваемые вопросы по Engage SDK .

Контакт

Если в процессе интеграции возникнут какие-либо вопросы, свяжитесь с нами по адресу Engage-developers@google.com . Наша команда ответит как можно скорее.

Следующие шаги

После завершения интеграции ваши следующие действия будут следующими:

  • Отправьте электронное письмо на адрес Engage-developers@google.com и прикрепите интегрированный APK-файл, готовый к тестированию Google.
  • Google выполняет внутреннюю проверку и проверку, чтобы убедиться, что интеграция работает должным образом. Если потребуются изменения, Google свяжется с вами и предоставит всю необходимую информацию.
  • Когда тестирование будет завершено и никаких изменений не потребуется, Google свяжется с вами и уведомит вас о том, что вы можете начать публикацию обновленного и интегрированного APK в Play Store.
  • После того как Google подтвердит, что обновленный APK-файл опубликован в Play Store, ваши рекомендации и кластеры будут опубликованы и видны пользователям.