3

We have a simple trivia game which is currently using Room database to store all the data including users progress. We now want to integrate Google play game services to store the progress on cloud so user can have their progress when the device is changed or game is reinstalled.

Currently we have game categories and level details in xml file which is then parsed and data are stored in Room database on first run of app.

We have checked the documents of game services and we are aware that there is this method to save the game.

private Task<SnapshotMetadata> writeSnapshot(Snapshot snapshot,
                                         byte[] data, Bitmap coverImage, String desc) {

  // Set the data payload for the snapshot
  snapshot.getSnapshotContents().writeBytes(data);

  // Create the change operation
  SnapshotMetadataChange metadataChange = new SnapshotMetadataChange.Builder()
      .setCoverImage(coverImage)
      .setDescription(desc)
      .build();

  SnapshotsClient snapshotsClient =
      Games.getSnapshotsClient(this, GoogleSignIn.getLastSignedInAccount(this));

  // Commit the operation
  return snapshotsClient.commitAndClose(snapshot, metadataChange);
}

But the issue is, this method takes bytes to write the snapshot and we have data in Room database, can we pass the data from Room db or we have to change the local database?

1 Answers1

1

As the question is written, it is entirely unclear what byte[] data even is. Use SnapshotsClient with SnapshotMetadata (as the documentation shows, there are further properties to set). String can easily be converted to byte[]. You'd need some kind of a model of a SaveGame, to begin with - which may be a Room @Entity; then String & GSON can provide byte[] getters/setters:

@Entity(tableName = "savegames")
public class SaveGame {

    @PrimaryKey
    public int id;
    ...

    /** return a byte-array representation (this is probably what you're asking for). */
    public byte[] toByteArray() {
        return new Gson().toJson(this).getBytes();
    }

    /** TODO: initialize instance of {@link SaveGame} from a byte-array representation - so that it will work both ways. */
    public void fromByteArray(byte[] bytes) {
        SaveGame data = new Gson().fromJson(new String(bytes, StandardCharsets.UTF_8), SaveGame.class);
        ...
    }
}

Or pass byte[] into the constructor:

@Entity(tableName = "savegames")
public class SaveGame {

    @PrimaryKey
    public int id;
    ...

    public SaveGame() {}

    @Ignore
    public SaveGame(byte[] bytes) {
        SaveGame data = new Gson().fromJson(new String(bytes, StandardCharsets.UTF_8), SaveGame.class);
        ...
    }
    ...
}

Alike this it's no problem to load a SaveGame, either from Room or from SnapshotsClient payload. And even when not using Room, one still would need methods to encode/decode the snapshot's payload - no matter the save-game parameters or the format. Instead one could just define a byte[] where every digit may represent another one save-game parameter; it may depend how complex the payload to save and restore may be.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216