На этой странице объясняется, как реализовать Recall API в вашей игре. Сначала рассматривается настройка игрового сервера и клиента для поддержки API, а затем — хранение и извлечение токенов.
Настройка игрового сервера
Настройте свой игровой сервер для выполнения вызовов Recall API к серверам Google.
1. Настройте свой проект Play Games Services
Если вы еще этого не сделали, следуйте инструкциям в разделе Настройка игровых сервисов Google Play .
2. Создайте учетную запись для игры.
Следуйте инструкциям по созданию учётной записи сервиса . В результате вы получите JSON-файл с учётными данными учётной записи сервиса.
3. Загрузите серверную библиотеку Java для PlayGamesServices.
Загрузите последнюю версию библиотеки google-api-services-games и загрузите ее на свой сервер.
4. Подготовьте учетные данные для вызовов API Recall.
Дополнительную информацию см. в разделе Подготовка к выполнению авторизованного вызова API .
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.games.Games;
import com.google.api.services.games.GamesScopes;
// ...
GoogleCredential credential =
  GoogleCredential.fromStream(new FileInputStream("<credentials>.json"))
    .createScoped(Collections.singleton(GamesScopes.ANDROIDPUBLISHER));
Games gamesApi =
    new Games.Builder(httpTransport, JSON_FACTORY, credential).build();
Настройка игрового клиента
Настройте свой игровой клиент для получения идентификаторов сеансов отзыва, используемых нашим сервером для связи с серверами Google.
Java SDK
 Настройте Java SDK в своем клиенте и обязательно включите com.google.android.gms:play-services-games-v2:19.0.0
 и com.google.android.gms:play-services-tasks:18.0.2 или выше в вашем файле gradle.
Чтобы обмениваться данными с серверами Google, предоставляя им корректную информацию, вам необходимо запросить идентификатор сеанса Recall у клиентского SDK, который вы отправите на сервер своей игры.
Котлин
PlayGames.getRecallClient(getActivity())
                .requestRecallAccess()
                .addOnSuccessListener { recallAccess -> val recallSessionId: String = recallAccess.getSessionId() }
                // Send the recallSessionId to your game server
Ява
PlayGames.getRecallClient(getActivity())
  .requestRecallAccess()
  .addOnSuccessListener(
    recallAccess -> {
      String recallSessionId = recallAccess.getSessionId();
      // Send the recallSessionId to your game server
    });
Unity SDK
Если это еще не сделано, настройте Unity SDK в своем клиенте .
Чтобы обмениваться данными с серверами Google, предоставляя им корректную информацию, вам необходимо запросить идентификатор сеанса Recall у клиентского SDK и отправить его на сервер вашей игры.
PlayGamesPlatform.Instance.RequestRecallAccess(
    recallAccess => {
        string recallSessionId = recallAccess.sessionId;
        // Send the recallSessionId to your game server
    });
Используйте Recall API на вашем игровом сервере
 После настройки сервера и клиента вы можете отправить recallSessionID из вашего игрового клиента на ваш игровой сервер и следовать следующим инструкциям, чтобы начать использовать Java API для хранения, извлечения или удаления токенов Recall на стороне сервера.
Токены магазина
Учетная запись игрока в API Google Play Games Recall состоит из двух частей информации:
- Персона, служащая стабильным идентификатором для игрового аккаунта
- Токен, служащий ключом для безопасной регистрации игрока в аккаунте
 Вы можете хранить персону и токен пользователя с помощью объекта LinkPersonaRequest . Используйте GoogleCredential для вызова API Google (см. раздел Вызов API Google для получения контекста). Персона имеет ограничение мощности 1:1 : один профиль PGS может содержать только одну персону, и персона может существовать только в одном профиле PGS. Настройте политику разрешения конфликтующих ссылок , чтобы определить, как должны разрешаться нарушения ограничения мощности 1:1.
 При необходимости задайте срок действия токена. Используйте SetTtl() с объектом Durations для установки срока действия или укажите точное время действия с помощью setExpireTime() .
Персона и игровой токен должны быть зашифрованы, и они не должны содержать персональную информацию. Длина строк персоны и токена не должна превышать 256 символов.
import com.google.api.services.games.Games.Recall.LinkPersona;
import com.google.api.services.games.model.LinkPersonaRequest;
import com.google.api.services.games.model.LinkPersonaResponse;
import com.google.protobuf.util.Durations;
// ...
Games gamesApi =
    new Games.Builder(httpTransport, JSON_FACTORY, credential).build();
String recallSessionId = ... // recallSessionID from game client
String persona = ... // encrypted opaque string, stable for in-game account
String token = ... // encrypted opaque string encoding the progress line
LinkPersonaRequest linkPersonaRequest =
  LinkPersonaRequest.newBuilder()
    .setSessionId(recallSessionId)
    .setPersona(persona)
    .setToken(token)
    .setCardinalityConstraint(ONE_PERSONA_TO_ONE_PLAYER)
    .setConflictingLinksResolutionPolicy(CREATE_NEW_LINK)
    .setTtl(Durations.fromDays(7)) // Optionally set TTL for token
    .build();
LinkPersonaResponse linkPersonaResponse =
  gamesApi.recall().linkPersona(linkPersonaRequest).execute();
if (linkPersonaResponse.getState() == LINK_CREATED) {
  // success
}
Получить токены
Существует три способа получить токен, в зависимости от потребностей вашей игры. Вы можете запросить следующее:
- Токены, связанные с текущей игрой, включая токены отзыва, относящиеся к игре.
- Последний токен, сохраненный во всех играх, принадлежащих аккаунту разработчика.
- Учитывая список игр, принадлежащих аккаунту разработчика, все токены отзыва, связанные с каждой игрой.
Жетоны отзыва в рамках игры
 Чтобы извлечь токены отзыва из текущей игры, получите recallSessionId от клиента и передайте его в retrieveTokens API:
import com.google.api.services.games.Games;
import com.google.api.services.games.model.RetrievePlayerTokensResponse;
import com.google.api.services.games.model.RecallToken;
// ...
String recallSessionId = ... // recallSessionID from game client
RetrievePlayerTokensResponse retrievePlayerTokensResponse =
  gamesApi.recall().retrieveTokens(recallSessionId).execute();
for (RecallToken recallToken : retrievePlayerTokensResponse.getTokens()) {
  String token recallToken.getToken();
  // Same string as was written in LinkPersona call
  // decrypt and recover in-game account
}
Последний токен отзыва для всех игр, принадлежащих аккаунту разработчика
 Чтобы получить последний токен, сохранённый для всех игр, принадлежащих учётной записи разработчика в консоли Google Play, необходимо получить от клиента параметр recallSessionId и передать его в API lastTokenFromAllDeveloperGames , как показано в следующем фрагменте кода. В ответе вы можете проверить идентификатор приложения, связанный с этим токеном.
import com.google.api.services.games.Games;
import com.google.api.services.games.model.RetrieveDeveloperGamesLastPlayerTokenResponse;
import com.google.api.services.games.model.GamePlayerToken;
import com.google.api.services.games.model.RecallToken;
// ...
String recallSessionId = ... // recallSessionID from game client
RetrieveDeveloperGamesLastPlayerTokenResponse response =
        gamesApi.recall().lastTokenFromAllDeveloperGames(recallSessionId)
        .execute();
if (response.hasGamePlayerToken()) {
    GamePlayerToken gamePlayerToken = response.getGamePlayerToken();
    // The ID of the application that the token is associated with.
    String applicationId = gamePlayerToken.getApplicationId();
    // Same string as was written in LinkPersona call.
    RecallToken recallToken = gamePlayerToken.getRecallToken();
    // Decrypt and recover in-game account.
}
Все токены отзыва в указанном списке игр, принадлежащих аккаунту разработчика
 Чтобы получить все токены, связанные со списком игр, принадлежащих вашей учётной записи разработчика в Google Play Console, получите recallSessionId от клиента и передайте его в API gamesPlayerTokens . Предоставьте список идентификаторов приложений .
import com.google.api.services.games.Games;
import com.google.api.services.games.model.RetrieveGamesPlayerTokensResponse;
import com.google.api.services.games.model.GamePlayerToken;
import com.google.api.services.games.model.RecallToken;
// ...
String recallSessionId = ... // recallSessionID from game client
// Application IDs for which you would like to retrieve the recall tokens.
List<String> applicationIds = ...
RetrieveGamesPlayerTokensResponse response =
gamesApiClient
        .recall()
        .gamesPlayerTokens(recallSessionId)
        .setApplicationIds(applicationIds)
        .execute();
for (GamePlayerToken gamePlayerToken : response.getGamePlayerTokens()) {
    // The ID of the application that the token is associated with.
    String applicationId  = gamePlayerToken.getApplicationId();
    // Same string as was written in LinkPersona call.
    RecallToken recallToken = gamePlayerToken.getRecallToken();
    // Decrypt and recover in-game account.
}
Удалить токен отзыва
При необходимости вы также можете удалить токен отзыва с помощью следующего вызова:
import com.google.api.services.games.Games;
import com.google.api.services.games.model.UnlinkPersonaRequest;
import com.google.api.services.games.model.UnlinkPersonaResponse;
// ...
String recallSessionId = ...
String persona = ...
String token = ...
Games gamesApi =
    new Games.Builder(httpTransport, JSON_FACTORY, credential).build();
UnlinkPersonaRequest unlinkPersonaRequest =
  UnlinkPersonaRequest.newBuilder()
    .setSessionId(recallSessionId)
    .setPersona(persona)
    // .setToken(token) - alternatively set token, but not both
    .build();
UnlinkPersonaResponse unlinkPersonaResponse =
  gamesApi.recall().unlinkPersona(unlinkPersonaRequest).execute();
boolean unlinked = unlinkPersonaResponse.isUnlinked();
Включить беспрофильный режим
Вы можете включить ограниченную функциональность Recall API для пользователей, у которых нет профилей PGS, выполнив следующие действия:
-  Включите функцию беспрофильного отзыва для вашего игрового проекта PGS в консоли разработчика Play.  
- Ознакомьтесь с дополнительными условиями, описанными далее в этом разделе.
- Добавьте следующий тег метаданных в манифест вашего приложения :
<meta-data
  android:name="com.google.android.gms.games.PROFILELESS_RECALL_ENABLED"
  android:value="true" />
Дополнительные условия
Помимо того, что вы подчиняетесь Условиям обслуживания игровых сервисов Play , вы соглашаетесь с тем, что если вы используете Recall API для пользователей без профиля PGS, который позволяет обмениваться данными конечного пользователя с Google без наличия у него профиля игровых сервисов Play, вы должны, прежде чем обмениваться такими данными с Google, предоставить конечному пользователю соответствующее уведомление, описывающее следующее:
- Предоставление вами данных Google для включения функции привязки аккаунтов Play Игр.
- Наличие настроек для управления таким обменом, например, через настройки Play Игр.
- Обработка таких данных осуществляется в соответствии с Политикой конфиденциальности Google , а также получение соответствующего согласия конечного пользователя на такой обмен, отвечающего всем применимым правовым требованиям.
