如何静默下载 Google Play 游戏服务保存的游戏快照数据?

Posted

技术标签:

【中文标题】如何静默下载 Google Play 游戏服务保存的游戏快照数据?【英文标题】:How to download a Google Play Games Services Saved Games Snapshot's Data, silently? 【发布时间】:2019-03-08 16:38:53 【问题描述】:

我正在尝试在我的 android 应用中将 Google 的游戏存档功能与 Google Play 游戏服务一起使用。谷歌提供sample code how to do so:

private static final int RC_SAVED_GAMES = 9009;
private String mCurrentSaveName = "snapshotTemp";

private void showSavedGamesUI() 
  SnapshotsClient snapshotsClient =
      Games.getSnapshotsClient(this, GoogleSignIn.getLastSignedInAccount(this));
  int maxNumberOfSavedGamesToShow = 5;

  Task<Intent> intentTask = snapshotsClient.getSelectSnapshotIntent(
      "See My Saves", true, true, maxNumberOfSavedGamesToShow);

  intentTask.addOnSuccessListener(new OnSuccessListener<Intent>() 
    @Override
    public void onSuccess(Intent intent) 
      startActivityForResult(intent, RC_SAVED_GAMES);
    
  );


@Override
protected void onActivityResult(int requestCode, int resultCode,
                                Intent intent) 
  if (intent != null) 
    if (intent.hasExtra(SnapshotsClient.EXTRA_SNAPSHOT_METADATA)) 
      // Load a snapshot.
      SnapshotMetadata snapshotMetadata =
          intent.getParcelableExtra(SnapshotsClient.EXTRA_SNAPSHOT_METADATA);
      mCurrentSaveName = snapshotMetadata.getUniqueName();

      // Load the game data from the Snapshot
      // ...
     else if (intent.hasExtra(SnapshotsClient.EXTRA_SNAPSHOT_NEW)) 
      // Create a new snapshot named with a unique string
      String unique = new BigInteger(281, new Random()).toString(13);
      mCurrentSaveName = "snapshotTemp-" + unique;

      // Create the new snapshot
      // ...
    
  

显然,Google 希望您使用他们提供的意图让用户决定要加载哪个已保存的游戏或是否应创建新的保存游戏。

另一方面,我想为用户做这个决定。但是,我无法找到返回快照列表和加载快照数据的方法。

由于我的游戏不需要为每位用户维护多个已保存的游戏,因此我对获取无意图的快照列表不太感兴趣(不过,这将是一个有趣的解决方案),而更喜欢加载基于快照的在保存的游戏名称上,默默地。

如何在不显示意图的情况下加载快照?

【问题讨论】:

你检查过这个 SO 相关的post 吗?那里有一个示例代码。 @jess 谢谢。该答案使用了一个已弃用的解决方案,但它最终帮助我找到了正确的解决方案。请检查我的答案。 酷!很高兴它可以帮助您找到更好的解决方案:) 【参考方案1】:

jess 的评论使我找到了一个现在已弃用的解决方案。然而,发布答案的人指出,Google 提供的 CollectAllTheStars 示例应用程序中也有一个可行的解决方案。我很想检查这个示例应用程序,以了解 Google 团队是否已更改代码以适应新方式。让我开心的是,该示例应用程序中的 cmets 仍在描述旧的已弃用方式,但代码已因我的运气而更改。

检查代码给了我一些想法,所以我想出了这个解决方案:

String serializedSavedGameData;
public void downloadSavedGameData(final String name) 
    if(snapshotsClient != null) 
        snapshotsClient.open(name, true, SnapshotsClient.RESOLUTION_POLICY_MOST_RECENTLY_MODIFIED).addOnFailureListener(new OnFailureListener() 
            @Override
            public void onFailure(@NonNull Exception e) 
                Log.e(TAG, "Error while opening snapshot: ", e);
            
        ).continueWith(new Continuation<SnapshotsClient.DataOrConflict<Snapshot>, byte[]>() 
            @Override
            public byte[] then(@NonNull Task<SnapshotsClient.DataOrConflict<Snapshot>> task) throws Exception 
                Snapshot snapshot = task.getResult().getData();
                // Opening the snapshot was a success and any conflicts have been resolved.
                try 
                    // Extract the raw data from the snapshot.
                    return snapshot.getSnapshotContents().readFully();
                 catch (IOException e) 
                    Log.e(TAG, "Error while reading snapshot: ", e);
                 catch (NullPointerException e) 
                    Log.e(TAG, "Error while reading snapshot: ", e);
                
                return null;
            
        ).addOnCompleteListener(new OnCompleteListener<byte[]>() 
            @Override
            public void onComplete(@NonNull Task<byte[]> task) 
                if(task.isSuccessful()) 
                    byte[] data = task.getResult();
                    try 
                        serializedSavedGameData = new String(data, "UTF-16BE");
                     catch (UnsupportedEncodingException e) 
                        Log.d(TAG, "Failed to deserialize save game data: " + e.getMessage());
                    
                 else 
                    Exception ex = task.getException();
                    Log.d(TAG, "Failed to load saved game data: " + (ex != null ? ex.getMessage() : "UNKNOWN"));
                
            
        );
    

我实施了一个简单的解决策略(以最新保存的游戏冲突为例),但我没有时间对所有不同的情况(如冲突)进行硬测试,但到目前为止它通过了我的简单测试。

希望任何人都能从中获利。

【讨论】:

以上是关于如何静默下载 Google Play 游戏服务保存的游戏快照数据?的主要内容,如果未能解决你的问题,请参考以下文章

用户退出 Google Play 服务后保存游戏的最佳做法?

Google play 游戏服务 : 保存游戏,创建新快照

Google Play 游戏服务:编写保存的游戏

获取对快照的引用。 Google Play 游戏服务保存的游戏

是否可以在 google play 游戏服务上保存关卡?

从 Google Play 游戏服务获取用户分数?