Saved Games Snapshot Initialization (null Object Reference)
Solution 1:
The Snapshot API is very specific in how you must do things. The following is the high-level procedure for Snapshot save:
- Open the snapshot
- Resolve conflicts
- Save
The following code is from the Google Play Games Snapshot sample which shows you how to use Snapshots cross-platform across Android and iOS.
First, you must open the snapshot and resolve conflicts on open.
/**
* Prepares saving Snapshot to the user's synchronized storage, conditionally resolves errors,
* and stores the Snapshot.
*/
void saveSnapshot() {
AsyncTask<Void, Void, Snapshots.OpenSnapshotResult> task =
new AsyncTask<Void, Void, Snapshots.OpenSnapshotResult>() {
@Override
protected Snapshots.OpenSnapshotResult doInBackground(Void... params) {
Snapshots.OpenSnapshotResult result = Games.Snapshots.open(getApiClient(),
currentSaveName, true).await();
return result;
}
@Override
protected void onPostExecute(Snapshots.OpenSnapshotResult result) {
Snapshot toWrite = processSnapshotOpenResult(result, 0);
Log.i(TAG, writeSnapshot(toWrite));
}
};
task.execute();
}
Next, you must handle conflict resolution:
/**
* Conflict resolution for when Snapshots are opened.
* @param result The open snapshot result to resolve on open.
* @return The opened Snapshot on success; otherwise, returns null.
*/
Snapshot processSnapshotOpenResult(Snapshots.OpenSnapshotResult result, int retryCount){
Snapshot mResolvedSnapshot = null;
retryCount++;
int status = result.getStatus().getStatusCode();
Log.i(TAG, "Save Result status: " + status);
if (status == GamesStatusCodes.STATUS_OK) {
return result.getSnapshot();
} else if (status == GamesStatusCodes.STATUS_SNAPSHOT_CONTENTS_UNAVAILABLE) {
return result.getSnapshot();
} else if (status == GamesStatusCodes.STATUS_SNAPSHOT_CONFLICT){
Snapshot snapshot = result.getSnapshot();
Snapshot conflictSnapshot = result.getConflictingSnapshot();
// Resolve between conflicts by selecting the newest of the conflicting snapshots.
mResolvedSnapshot = snapshot;
if (snapshot.getMetadata().getLastModifiedTimestamp() <
conflictSnapshot.getMetadata().getLastModifiedTimestamp()){
mResolvedSnapshot = conflictSnapshot;
}
Snapshots.OpenSnapshotResult resolveResult = Games.Snapshots.resolveConflict(
getApiClient(), result.getConflictId(), mResolvedSnapshot)
.await();
if (retryCount < MAX_SNAPSHOT_RESOLVE_RETRIES){
return processSnapshotOpenResult(resolveResult, retryCount);
}else{
String message = "Could not resolve snapshot conflicts";
Log.e(TAG, message);
Toast.makeText(getBaseContext(), message, Toast.LENGTH_LONG);
}
}
// Fail, return null.
return null;
}
The following code is how this is done in the Google Play Games Snapshots sample app:
/**
* Generates metadata, takes a screenshot, and performs the write operation for saving a
* snapshot.
*/
private String writeSnapshot(Snapshot snapshot){
// Set the data payload for the snapshot.
snapshot.writeBytes(mSaveGame.toBytes());
// Save the snapshot.
SnapshotMetadataChange metadataChange = new SnapshotMetadataChange.Builder()
.setCoverImage(getScreenShot())
.setDescription("Modified data at: " + Calendar.getInstance().getTime())
.build();
Games.Snapshots.commitAndClose(getApiClient(), snapshot, metadataChange);
return snapshot.toString();
}
Solution 2:
I think, instead of creating Snapshot object explicitly. It should get generated in onActivityResult. So you need to handle it in onActivityResult. Then your writeBytes() will perform further operations.
Check documentation, In that loadFromSnapshot() contains
Snapshot snapshot = result.getSnapshot();
So I think, you are getting null/false response on your onActivityResult. If not then follow same steps given in loadFromSnapshot() documentation.
Post a Comment for "Saved Games Snapshot Initialization (null Object Reference)"