Bu kılavuzda,
Snapshot API'si Google Play Games Hizmetleri tarafından sağlanıyor. API'leri
com.google.android.gms.games.snapshot
ve com.google.android.gms.games
paketleri dahildir.
Başlamadan önce
Henüz yapmadıysanız Kayıtlı oyunlarla ilgili kavramlar.
- Kayıtlı oyunlar desteğini etkinleştirdiğinizden emin olun. Google Play Console'da kontrol edebilirsiniz.
- Kaydedilen oyunlar kod örneğini şurada indirip inceleyin: Android örnekleri sayfası.
- Şu bölümde açıklanan öneriler hakkında bilgi edinin: Kalite Kontrol Listesi.
Anlık görüntü istemcisini alma
Snapshot API'sini kullanmaya başlamak için oyununuzun önce bir
SnapshotsClient
nesnesini tanımlayın. Bunu,
Games.getSnapshotsClient()
yöntemini kullandığınızdan ve
etkinliği ve mevcut oyuncu için GoogleSignInAccount
. Nasıl yapıldığını öğrenmek için
oynatıcı hesap bilgilerini almak için
Android Games'de oturum açın.
Drive kapsamını belirtme
Snapshot API, kaydedilmiş oyunların depolama alanı için Google Drive API'yi kullanır. Alıcı:
uygulamanız gerekiyorsa
Drive.SCOPE_APPFOLDER
kapsam dışı kalır.
Bu işlemin nasıl yapılacağına dair bir
onResume()
yöntemi olarak da kullanabilirsiniz:
private GoogleSignInClient mGoogleSignInClient; @Override protected void onResume() { super.onResume(); signInSilently(); } private void signInSilently() { GoogleSignInOptions signInOption = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) // Add the APPFOLDER scope for Snapshot support. .requestScopes(Drive.SCOPE_APPFOLDER) .build(); GoogleSignInClient signInClient = GoogleSignIn.getClient(this, signInOption); signInClient.silentSignIn().addOnCompleteListener(this, new OnCompleteListener<GoogleSignInAccount>() { @Override public void onComplete(@NonNull Task<GoogleSignInAccount> task) { if (task.isSuccessful()) { onConnected(task.getResult()); } else { // Player will need to sign-in explicitly using via UI } } }); }
Kaydedilmiş oyunlar gösteriliyor
Oyununuzun oyunculara ekran görüntüleri sağladığı her yerde Snapshot API'sini kaydedilen ilerlemeyi kaydedebilir veya geri yükleyebilirsiniz. Oyununuzda bu tür bir belirtilen kaydetme/geri yükleme seçeneği sunan veya oyuncuların kaydetmelerine ya da geri yüklemelerine takip edebilirsiniz.
Oyuncular oyununuzda kaydet/geri yükle seçeneğini belirlediğinde oyununuz otomatik olarak isteğe bağlı olarak, oyunculardan kaydedilmiş yeni bir oyun için bilgi girmelerini isteyen yüklemek veya geri yüklemek üzere mevcut bir kaydedilmiş oyunu seçmek için kullanılabilir.
Snapshot API, geliştirme sürecinizi basitleştirmek için varsayılan kaydedilmiş oyunlar seçimi kullanıcısı sağlar. hemen kullanabileceğiniz yeni bir arayüz (UI) sağlar. Kaydedilmiş oyunlar seçim arayüzü, oyuncuların şunları yapmasına olanak tanır: kaydedilmiş yeni bir oyun oluşturabilir, kaydedilmiş mevcut oyunlarla ilgili ayrıntıları görüntüleyebilir ve daha önce kaydedilmiş oyunları yükleyebilirsiniz.
Varsayılan Kaydedilmiş Oyunlar kullanıcı arayüzünü başlatmak için:
SnapshotsClient.getSelectSnapshotIntent()
numaralı telefonu arayarak Varsayılanı başlatmak içinIntent
Kaydedilen oyunlar seçim kullanıcı arayüzü.startActivityForResult()
numaralı telefonu arayın ve bunuIntent
iletebilirim. Arama başarılı olursa oyunda, oyun seçimi kullanıcı arayüzüyle birlikte belirlediğiniz seçeneklerle değiştirin.
Aşağıda, varsayılan kaydedilmiş oyunlar seçimi kullanıcı arayüzünün nasıl başlatılacağına ilişkin bir örnek verilmiştir:
private static final int RC_SAVED_GAMES = 9009; 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); } }); }
Oyuncu yeni bir kaydedilmiş oyun oluşturmayı veya mevcut bir kayıtlı oyunu yüklemeyi seçerse
kullanıcı arayüzü, Google Play Games hizmetlerine bir istek gönderir. İstek başarılı olursa
Google Play oyun hizmetleri, kayıtlı oyunu oluşturmak veya geri yüklemek için
onActivityResult()
geri arama. Oyununuz, istek sırasında herhangi bir hata oluşup oluşmadığını kontrol etmek için bu geri çağırmayı geçersiz kılabilir.
Aşağıdaki kod snippet'i,
onActivityResult()
:
private String mCurrentSaveName = "snapshotTemp"; /** * This callback will be triggered after you call startActivityForResult from the * showSavedGamesUI method. */ @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 // ... } } }
Kaydedilmiş oyunlar yazma
Kaydedilmiş bir oyunun içeriğini depolamak için:
SnapshotsClient.open()
üzerinden eşzamansız olarak bir anlık görüntü açın. Ardından,Snapshot
nesnesini alın. görevin sonucundanSnapshotsClient.DataOrConflict.getData()
numaralı telefonu çağırarak.SnapshotsClient.SnapshotConflict
aracılığıylaSnapshotContents
örneği alın.- Oynatıcının verilerini bayt biçiminde depolamak için
SnapshotContents.writeBytes()
öğesini çağırın. - Tüm değişiklikleriniz yazıldıktan sonra
Değişikliklerinizi Google'ın sunucularına göndermek için
SnapshotsClient.commitAndClose()
. Yöntem çağrısında, oyun, isteğe bağlı olarak Google Play Games hizmetlerine bunu nasıl yapacaklarını bu kayıtlı oyunu oyunculara sunun. Bu bilgilerSnapshotMetaDataChange
ile gösterilir. (oyununuzunSnapshotMetadataChange.Builder
kullanarak oluşturduğu nesne)
Aşağıdaki snippet, oyununuzun kaydedilmiş bir oyunda değişiklikleri nasıl uygulayabileceğini gösterir:
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); }
Uygulamanız şunu aradığında oynatıcının cihazı bir ağa bağlı değilse
SnapshotsClient.commitAndClose()
, Google Play Games hizmetleri kaydedilen oyun verilerini şurada yerel olarak depolar:
için geçerlidir. Cihaz yeniden bağlandığında Google Play Games Hizmetleri, yerel olarak önbelleğe alınmış kaydedilmiş oyunu senkronize eder
Google sunucularında yapılan değişikliklerdir.
Kaydedilmiş oyunlar yükleniyor
Oturumu açık olan oyuncu için kaydedilmiş oyunları almak için:
SnapshotsClient.open()
üzerinden eşzamansız olarak bir anlık görüntü açın. Ardından,Snapshot
nesnesini alın. görevin sonucundanSnapshotsClient.DataOrConflict.getData()
numaralı telefonu çağırarak. Alternatif olarak oyun, belirli bir anlık görüntüyü kaydedilmiş oyunlar seçimi kullanıcı arayüzü aracılığıyla da alabilir (bkz. Kaydedilmiş Oyunları Görüntüleme.SnapshotsClient.SnapshotConflict
üzerindenSnapshotContents
örneğini alın.- Anlık görüntünün içeriğini okumak için
SnapshotContents.readFully()
komutunu çağırın.
Aşağıdaki snippet'te, belirli bir kayıtlı oyunu nasıl yükleyebileceğiniz gösterilmektedir:
Task<byte[]> loadSnapshot() { // Display a progress dialog // ... // Get the SnapshotsClient from the signed in account. SnapshotsClient snapshotsClient = Games.getSnapshotsClient(this, GoogleSignIn.getLastSignedInAccount(this)); // In the case of a conflict, the most recently modified version of this snapshot will be used. int conflictResolutionPolicy = SnapshotsClient.RESOLUTION_POLICY_MOST_RECENTLY_MODIFIED; // Open the saved game using its name. return snapshotsClient.open(mCurrentSaveName, true, conflictResolutionPolicy) .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); } return null; } }).addOnCompleteListener(new OnCompleteListener<byte[]>() { @Override public void onComplete(@NonNull Task<byte[]> task) { // Dismiss progress dialog and reflect the changes in the UI when complete. // ... } }); }
Kaydedilen oyun çakışmalarını yönetme
Oyununuzda Snapshot API'sini kullanırken birden fazla aynı kayıtlı oyunda okuma ve yazma işlemleri yapmanızı sağlar. Bir kullanıcının Cihazın ağ bağlantısı geçici olarak kesiliyor ve daha sonra yeniden bağlanıyor. Bu durum, Kaydedilmiş oyun, bir oyuncunun yerel cihazında depolanan veri çakışmalarına neden olur Google'ın sunucularında depolanan uzak sürümle senkronize değil.
Snapshot API, hem kayıtlı olan ve okuma zamanında kaydedilen çakışan kayıtlı oyun kümeleriyle tutarlı bir çözüm sunar. doğru bir teklif verme stratejisidir.
Google Play Games Hizmetleri bir veri çakışması algıladığında
SnapshotsClient.DataOrConflict.isConflict()
yöntemi true
değerini döndürür. Bu etkinlikte,
SnapshotsClient.SnapshotConflict
sınıfı, kaydedilen oyunun iki sürümünü sağlar:
- Sunucu sürümü: Google Play Games hizmetleri tarafından doğru olduğu bilinen en güncel sürüm Oynatıcının cihazı için ve
- Yerel sürüm: Oynatıcının cihazlarından birinde algılanan değiştirilmiş bir sürüm: veya meta veriyle çelişen durumlar olabilir. Bu sürüm, kaydetmeye çalıştığınız sürümle aynı olmayabilir.
Oyununuz, aşağıdakilerden birini seçerek çatışmanın nasıl çözüleceğine karar vermelidir: veya kaydedilmiş iki oyun sürümünün verilerini birleştirerek kullanabilirsiniz.
Kaydedilen oyun çakışmalarını tespit etmek ve çözmek için:
SnapshotsClient.open()
numaralı telefonu arayın. Görev sonucu birSnapshotsClient.DataOrConflict
sınıfı içeriyor.SnapshotsClient.DataOrConflict.isConflict()
yöntemini çağırın. Sonuç doğruysa çözmek için atılacak bir kaç adım var.- Geri almak için
SnapshotsClient.DataOrConflict.getConflict()
numaralı telefonu arayınSnaphotsClient.snapshotConflict
örneği. - Benzersiz bir şekilde görüntülenen çakışma kimliğini almak için
SnapshotsClient.SnapshotConflict.getConflictId()
algılanan çakışmayı tanımlar. Oyununuzun çakışma çözüm isteği gönderebilmesi için bu değer gereklidir daha sonra. - Yerel sürümü öğrenmek için
SnapshotsClient.SnapshotConflict.getConflictingSnapshot()
numaralı telefonu arayın. - Sunucu sürümünü öğrenmek için
SnapshotsClient.SnapshotConflict.getSnapshot()
yöntemini çağırın. - Kaydedilmiş oyun çakışmasını çözmek için sunucuya
ve
SnapshotsClient.resolveConflict()
yöntemine ileteceksiniz.
Aşağıdaki snippet, oyununuzun kayıtlı oyun çakışmalarını en son değiştirilen kaydedilmiş oyunu son sürüm olarak seçmek:
private static final int MAX_SNAPSHOT_RESOLVE_RETRIES = 10; TaskS<napshot >processSnapshotOpenResult(SnapshotsClient.DataOrConflictS<napshot >result, final int retryCount) { if (!result.isConflict()) { // There was no conflict, so return the result of the source. TaskCompletionSourceS<napshot >source = new TaskCompletionSource(<>); source.setResult(result.getData()); return source.getTask(); } // There was a conflict. Try resolving it by selecting the newest of the conflicting snapshots. // This is the same as using RESOLUTION_POLICY_MOST_RECENTLY_MODIFIED as a conflict resolution // policy, but we are implementing it as an example of a manual resolution. // One option is to present a UI to the user to choose which snapshot to resolve. SnapshotsClient.SnapshotConflict conflict = result.getConflict(); Snapshot snapshot = conflict.getSnapshot(); Snapshot conflictSnapshot = conflict.getConflictingSnapshot(); // Resolve between conflicts by selecting the newest of the conflicting snapshots. Snapshot resolvedSnapshot = snapshot; if (snapshot.getMetadata().getLastModifiedTimestamp() < conflictSnapshot.getMetadata().getLastModifiedTimestamp()) { resolvedSnapshot = conflictSnapshot; } return Games.getSnapshotsClient(theActivity, GoogleSignIn.getLastSignedInAccount(this)) .resolveConflict(conflict.getConflictId(), resolvedSnapshot) .continueWithTask( new Continuation < SnapshotsClient.DataOrConflictS<napshot,> TaskS<napshot(>>) { @Override public TaskS<napshot >then( @NonNull TaskS<napshotsClient.DataOrConflictS<napshot >>task) throws Exception { // Resolving the conflict may cause another conflict, // so recurse and try another resolution. if (retryCount <MAX_SNAPSHOT_RESOLVE_RETRIES) { return processSnapshotOpenResult(task.getResult(), retryCount + 1); } else { throw new Exception(C"ould not resolve snapshot conflicts)"; } } }); }
Kaydedilmiş oyunları çakışma çözümü için değiştirme
Birden fazla kayıtlı oyundaki verileri birleştirmek veya mevcut bir Snapshot
oyununda değişiklik yapmak istiyorsanız
sunucuya çözümlenmiş son sürüm olarak kaydetmek için şu adımları izleyin:
SnapshotsClient.open()
numaralı telefonu arayın .- Yeni bir kod almak için
SnapshotsClient.SnapshotConflict.getResolutionSnapshotsContent()
numaralı telefonu arayınSnapshotContents
nesne olarak tanımlar. SnapshotsClient.SnapshotConflict.getConflictingSnapshot()
alanındaki verileri birleştir veSnapshotsClient.SnapshotConflict.getSnapshot()
konumundanSnapshotContents
nesnesine önceki adım.- Meta verilerde değişiklik olursa isteğe bağlı olarak bir
SnapshotMetadataChange
örneği oluşturun. alanları. SnapshotsClient.resolveConflict()
numaralı telefonu arayın. Yöntem çağrınızda İlk bağımsız değişken olarakSnapshotsClient.SnapshotConflict.getConflictId()
ve İkinci olarak daha önce değiştirdiğinizSnapshotMetadataChange
veSnapshotContents
nesneleri ve üçüncü bağımsız değişkenleri kullanıyoruz.SnapshotsClient.resolveConflict()
çağrısı başarılı olursa API,Snapshot
öğesini depolar nesneyi sunucuya gönderir ve yerel cihazınızda Anlık Görüntü nesnesini açmayı dener.- Çakışma olması durumunda
SnapshotsClient.DataOrConflict.isConflict()
,true
değerini döndürür. Burada oyununuzun 2. adıma geri dönmesi ve anlık görüntüyü değiştirmek için çözüldüğünden emin olmalısınız. - Çakışma yoksa
SnapshotsClient.DataOrConflict.isConflict()
,false
değerini döndürür veSnapshot
nesnesi, oyununuzda değişiklik yapılabilir.
- Çakışma olması durumunda