Android 遊戲登入

如果要存取 Google Play 遊戲服務功能,遊戲必須提供已登入玩家的帳戶。本文件說明如何在遊戲中實作順暢的登入體驗。

Play 遊戲服務第 2 版 SDK 提供許多改善功能,可增加登入遊戲的使用者人數,也可以簡化開發作業:

  • 使用者改善功能:
    • 選取預設帳戶後,使用者不需要有登入提示也可以登入。
    • 使用者不再需要下載 Play 遊戲應用程式,即可使用 Play 遊戲服務登入或建立新帳戶。
    • 使用者現在可以在單一頁面中管理多個遊戲的 Play 遊戲服務帳戶。
  • 開發人員改善功能:
    • 用戶端程式碼不再需要處理登入或登出流程,因為系統會在遊戲開始時自動觸發登入程序,並在 OS 設定中處理帳戶管理。

新用戶端整合

本節說明如何使用 Play 遊戲服務登入第 2 版執行新用戶端整合。

新增依附元件

在應用程式的根目錄層級 build.gradle 檔案中加入 Play 遊戲服務 SDK 依附元件。如果使用的是 Gradle,則可以新增或更新依附元件,如下所示:

dependencies {
 implementation "com.google.android.gms:play-services-games-v2:+"
}

定義專案 ID

如要在應用程式中加入 Play 遊戲服務 SDK 專案 ID,請完成下列步驟:

  1. 在應用程式的 AndroidManifest.xml 檔案中,將下列 <meta-data> 元素和屬性新增至 <application> 元素:

    <manifest>
      <application>
        <meta-data android:name="com.google.android.gms.games.APP_ID"
                   android:value="@string/game_services_project_id"/>
      </application>
    </manifest>
    

    使用遊戲的遊戲服務專案 ID 為值,定義字串資源參考資料 @string/game_services_project_id。遊戲服務專案 ID 會在 Google Play 管理中心「Configuration」(設定) 頁面的遊戲名稱下方顯示。

  2. res/values/strings.xml 檔案中,新增字串資源參考資料,並將專案 ID 設為該值。在 Google Play 管理中心的「Configuration」(設定) 頁面中,專案 ID 會在遊戲名稱下方顯示。例如:

    <!-- res/values/strings.xml -->
    <resources>
      <!-- Replace 0000000000 with your game’s project id. Example value shown above.  -->
      <string translatable="false"  name="game_services_project_id"> 0000000000 </string>
    </resources>
    

初始化 SDK

Application 類別的 onCreate(..) 回呼中初始化 Play 遊戲 SDK。

import com.google.android.gms.games.PlayGamesSdk;

...

@Override
public void onCreate(){
  super.onCreate();
  PlayGamesSdk.initialize(this);
}

取得登入程序結果

遊戲啟動後,一律會嘗試登入使用者。如要驗證使用者,您必須驗證使用者是否已成功登入,然後取得他們的玩家 ID。

如要驗證登入嘗試,請呼叫 GamesSignInClient.isAuthenticated() 並使用 addOnCompleteListener 擷取結果。例如:

GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(getActivity());

gamesSignInClient.isAuthenticated().addOnCompleteListener(isAuthenticatedTask -> {
  boolean isAuthenticated =
    (isAuthenticatedTask.isSuccessful() &&
     isAuthenticatedTask.getResult().isAuthenticated());

  if (isAuthenticated) {
    // Continue with Play Games Services
  } else {
    // Disable your integration with Play Games Services or show a
    // login button to ask  players to sign-in. Clicking it should
    // call GamesSignInClient.signIn().
  }
});

如果使用者不希望在遊戲啟動時登入,可以選擇繼續顯示附有 Play 遊戲圖示的按鈕,然後在使用者按下按鈕時呼叫 GamesSignInClient.signIn() 以嘗試再次登入使用者。

驗證使用者登入之後,就可以擷取玩家 ID 以辨識使用者。例如:

PlayGames.getPlayersClient(activity).getCurrentPlayer().addOnCompleteListener(mTask -> {
    // Get PlayerID with mTask.getResult().getPlayerId()
  }
);

遷移至 Play 遊戲服務登入功能第 2 版

本節說明如何將用戶端程式碼從 Play 遊戲服務第 1 版遷移至第 2 版。

請注意,新版 SDK 包含四項重大變更,可協助提高登入成功率:

  1. 系統會在遊戲啟動時自動登入。除了使用 GoogleSignIn SDK 的 GoogleSignInClient 執行登入作業,也可以使用 GamesSignInClient.isAuthenticated() 擷取嘗試自動登入的結果。
  2. 用戶端工廠類別不再需要傳入 GoogleSignInAccount 物件。無法要求額外的 OAuth 範圍 (系統會自動要求 GAMES_LITE)。
  3. 系統現在會使用 Play 遊戲服務 SDK 內的 GamesSignInClient.requestServerSideAccess() 提供驗證權杖。
  4. 登出方法已經移除,且您不必再使用遊戲中的按鈕登入或登出 Play 遊戲服務。

此外,由於遊戲啟動時會自動登入,因此會出現額外的登入次數。所以建議您參閱「配額管理」,確保遊戲不會超過登入要求配額。

指定新的 SDK Maven 存放區

如果您使用的是 Gradle 建構系統,就可以將依附元件變更為模組 build.gradle 檔案中的 com.google.android.gms:play-services-games-v2:+ 構件。例如:

dependencies {
 implementation "com.google.android.gms:play-services-games-v2:+"
}

初始化 SDK

Application 類別的 onCreate(..) 回呼中初始化 Play 遊戲 SDK。例如:

import com.google.android.gms.games.PlayGamesSdk;

...

@Override
public void onCreate(){
  super.onCreate();
  PlayGamesSdk.initialize(this);
}

移除登入和登出呼叫

如未指定其他範圍,請直接遷移您的使用案例。

  1. 移除使用 GoogleSignIn API 的登入呼叫。遊戲啟動時一律會執行登入。請改為間聽使用 GamesSignInClient.isAuthenticated() 自動登入的嘗試結果。

    GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(getActivity());
    
    gamesSignInClient.isAuthenticated().addOnCompleteListener(isAuthenticatedTask -> {
      boolean isAuthenticated =
        (isAuthenticatedTask.isSuccessful() &&
         isAuthenticatedTask.getResult().isAuthenticated());
    
      if (isAuthenticated) {
        // Continue with Play Games Services
      } else {
        // Disable your integration with Play Games Services or show a
        // login button to ask  players to sign-in. Clicking it should
        // call GamesSignInClient.signIn().
      }
    });
    
  2. 移除所有登出的呼叫,因為帳戶管理功能現在包含在 OS 和 Play 遊戲應用程式的設定中。

  3. 如果玩家成功登入,則從遊戲中移除 Play 遊戲登入按鈕。如果使用者選擇不要在遊戲啟動時登入,則可以選擇繼續顯示有 Play 遊戲圖示的按鈕,並使用 GamesSignInClient.signIn() 觸發登入程序。

  4. 驗證使用者登入後,您可以擷取玩家 ID 以辨識使用者。

    PlayGames.getPlayersClient(activity).getCurrentPlayer().addOnCompleteListener(mTask -> {
        // Get PlayerID with mTask.getResult().getPlayerId()
      }
    );
    
  5. 如果不再使用,則移除 GoogleSignIn API 的依附元件。

更新用戶端類別名稱

建立用戶端時 (例如:LeaderboardsClientAchievementsClient),使用 PlayGames.getFooClient() 而不是 Games.getFooClient()

要求伺服器端存取權

要求伺服器端存取權時,請使用 GamesSignInClient.requestServerSideAccess(),而不是 GoogleSignInAccount.getServerAuthCode()

GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(this);
gamesSignInClient
  .requestServerSideAccess(OAUTH_2_WEB_CLIENT_ID,
                           /*forceRefreshToken=*/ false)
  .addOnCompleteListener( task -> {
    if (task.isSuccessful()) {
      String serverAuthToken = task.getResult();
      // Send authentication code to the backend game server to be
      // exchanged for an access token and used to verify the
      // player via the Play Games Services REST APIs.
    } else {
      // Failed to retrieve authentication code.
    }
});

移除額外範圍

使用 Play 遊戲服務第 2 版時,無法要求取得其他範圍。如果仍需要求額外範圍,建議同時使用 Google 登入 SDK 與 Play 遊戲服務。

從 GoogleApiClient 遷移

如為較舊的現有整合,遊戲可能會依附於 Play 遊戲服務 SDK 的 GoogleApiClient API 變化版本。此設定已於 2017 年年底淘汰,並由「無網路連線」的用戶端取代。如要遷移,可以使用對等的「無網路連線」取代 GoogleApiClient 類別。然後也必須按照上述指南說明,將遊戲從第 1 版遷移至第 2 版。以下是常見類別的對應:

com.google.android.gms.games.achievement.Achievements ->
    com.google.android.gms.games.AchievementsClient

com.google.android.gms.games.leaderboard.Leaderboard ->
    com.google.android.gms.games.LeaderboardsClient

com.google.android.gms.games.snapshot.Snapshots ->
    com.google.android.gms.games.SnapshotsClient

com.google.android.gms.games.stats.PlayerStats ->
    com.google.android.gms.games.PlayerStatsClient

com.google.android.gms.games.Players ->
    com.google.android.gms.games.PlayersClient

com.google.android.gms.games.GamesStatusCodes ->
    com.google.android.gms.games.GamesClientStatusCodes