Birçok kullanıcı, yeni bir Android cihazı kurarken kendi kimlik bilgilerini yönetmeye devam eder. Bu manuel işlem zorlayıcı olabilir ve genellikle kötü bir kullanıcı deneyimine yol açar. Google Play Hizmetleri tarafından desteklenen bir kitaplık olan Block Store API, uygulamaların kullanıcı kimlik bilgilerini kaydetmesiyle ilişkili karmaşıklık veya güvenlik riski olmadan kullanıcı kimlik bilgilerini kaydetmesine olanak tanıyarak bu sorunu çözmeye çalışır.
Block Store API, uygulamanızın yeni bir cihazda kullanıcıların kimliğini yeniden doğrulamak için daha sonra alabileceği verileri depolamasına olanak tanır. Bu sayede kullanıcıların uygulamanızı yeni cihazda ilk kez başlatırken oturum açma ekranı görmesi gerekmediğinden kullanıcılara daha sorunsuz bir deneyim sunabilirsiniz.
Block Store'u kullanmanın avantajları şunlardır:
- Geliştiriciler için şifrelenmiş kimlik bilgisi depolama çözümü. Mümkün olduğunda kimlik bilgileri uçtan uca şifrelenir.
- Kullanıcı adları ve şifreler yerine jetonları kaydedin.
- Oturum açma akışlarındaki sorunları ortadan kaldırın.
- Kullanıcıları karmaşık şifreleri yönetme zahmetinden kurtarın.
- Google, kullanıcının kimliğini doğrular.
Başlamadan önce
Uygulamanızı hazırlamak için aşağıdaki bölümlerde açıklanan adımları tamamlayın.
Uygulamanızı yapılandırma
Proje düzeyindeki build.gradle
dosyanıza hem buildscript
hem de allprojects
bölümlerinize Google'ın Maven deposunu ekleyin:
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
Block Store API'si için Google Play Hizmetleri bağımlılığını modülünüzün Gradle derleme dosyasına ekleyin. Bu dosya genelde app/build.gradle
olur:
dependencies {
implementation 'com.google.android.gms:play-services-auth-blockstore:16.2.0'
}
İşleyiş şekli
Blok Mağazası, geliştiricilerin 16 bayta kadar dizileri kaydetmelerine ve geri yüklemelerine olanak tanır. Bu işlem, geçerli kullanıcı oturumuyla ilgili önemli bilgileri kaydetmenize olanak tanır ve bu bilgileri istediğiniz gibi kaydetme esnekliği sağlar. Bu veriler uçtan uca şifrelenebilir ve Block Store'u destekleyen altyapı, Yedekleme ve Geri Yükleme altyapısının üzerine kuruludur.
Bu kılavuzda, bir kullanıcının jetonunun Block Store'a kaydedilmesiyle ilgili kullanım alanı ele alınmaktadır. Aşağıdaki adımlarda, Block Store'u kullanan bir uygulamanın nasıl çalışacağı özetlenmektedir:
- Uygulamanızın kimlik doğrulama akışı sırasında veya daha sonra herhangi bir zamanda, kullanıcının kimlik doğrulama jetonunu daha sonra almak üzere Block Store'da saklayabilirsiniz.
- Jeton yerel olarak depolanır ve mümkün olduğunda uçtan uca şifrelenerek buluta yedeklenebilir.
- Kullanıcı yeni cihazda geri yükleme akışı başlattığında veriler aktarılır.
- Kullanıcı, geri yükleme akışı sırasında uygulamanızı geri yüklerse uygulamanız yeni cihazda Block Store'dan kaydedilen jetonu alabilir.
Jetonu kaydetme
Bir kullanıcı uygulamanızda oturum açtığında, bu kullanıcı için oluşturduğunuz kimlik doğrulama jetonunu Block Store'a kaydedebilirsiniz. Bu jetonu, giriş başına en fazla 4 KB olan benzersiz bir anahtar çifti değeri kullanarak depolayabilirsiniz.
Jetonu depolamak için bir StoreBytesData.Builder
örneğinde setBytes()
ve setKey()
çağrılarını yaparak kullanıcının kimlik bilgilerini kaynak cihazda depolayın. Jetonu Block Store ile kaydettikten sonra jeton şifrelenir ve cihazda yerel olarak depolanır.
Aşağıdaki örnekte, kimlik doğrulama jetonunun yerel cihaza nasıl kaydedileceği gösterilmektedir:
Java
BlockstoreClient client = Blockstore.getClient(this); byte[] bytes1 = new byte[] { 1, 2, 3, 4 }; // Store one data block. String key1 = "com.example.app.key1"; StoreBytesData storeRequest1 = StoreBytesData.Builder() .setBytes(bytes1) // Call this method to set the key value pair the data should be associated with. .setKeys(Arrays.asList(key1)) .build(); client.storeBytes(storeRequest1) .addOnSuccessListener(result -> Log.d(TAG, "stored " + result + " bytes")) .addOnFailureListener(e -> Log.e(TAG, "Failed to store bytes", e));
Kotlin
val client = Blockstore.getClient(this) val bytes1 = byteArrayOf(1, 2, 3, 4) // Store one data block. val key1 = "com.example.app.key1" val storeRequest1 = StoreBytesData.Builder() .setBytes(bytes1) // Call this method to set the key value with which the data should be associated with. .setKeys(Arrays.asList(key1)) .build() client.storeBytes(storeRequest1) .addOnSuccessListener { result: Int -> Log.d(TAG, "Stored $result bytes") } .addOnFailureListener { e -> Log.e(TAG, "Failed to store bytes", e) }
Varsayılan jetonu kullan
Anahtar olmadan StoreBytes kullanılarak kaydedilen veriler, BlockstoreClient.DEFAULT_BYTES_DATA_KEY varsayılan anahtarını kullanır.
Java
BlockstoreClient client = Blockstore.getClient(this); // The default key BlockstoreClient.DEFAULT_BYTES_DATA_KEY. byte[] bytes = new byte[] { 9, 10 }; StoreBytesData storeRequest = StoreBytesData.Builder() .setBytes(bytes) .build(); client.storeBytes(storeRequest) .addOnSuccessListener(result -> Log.d(TAG, "stored " + result + " bytes")) .addOnFailureListener(e -> Log.e(TAG, "Failed to store bytes", e));
Kotlin
val client = Blockstore.getClient(this); // the default key BlockstoreClient.DEFAULT_BYTES_DATA_KEY. val bytes = byteArrayOf(1, 2, 3, 4) val storeRequest = StoreBytesData.Builder() .setBytes(bytes) .build(); client.storeBytes(storeRequest) .addOnSuccessListener { result: Int -> Log.d(TAG, "stored $result bytes") } .addOnFailureListener { e -> Log.e(TAG, "Failed to store bytes", e) }
Jetonu alma
Daha sonra, bir kullanıcı yeni bir cihazda geri yükleme akışını gerçekleştirdiğinde, Google Play Hizmetleri önce kullanıcıyı doğrular ve ardından Blok Mağazası verilerinizi alır. Kullanıcı, geri yükleme akışının bir parçası olarak uygulama verilerinizi geri yüklemeyi zaten kabul etmiştir. Dolayısıyla ek izin gerekmez. Kullanıcı, uygulamanızı açtığında retrieveBytes()
numarasını arayarak Block Store'dan jetonunuzu isteyebilirsiniz.
Alınan jeton daha sonra kullanıcının yeni cihazda oturumunu açık tutmak için kullanılabilir.
Aşağıdaki örnekte, belirli anahtarlara göre birden fazla jetonun nasıl alınacağı gösterilmektedir.
Java
BlockstoreClient client = Blockstore.getClient(this); // Retrieve data associated with certain keys. String key1 = "com.example.app.key1"; String key2 = "com.example.app.key2"; String key3 = BlockstoreClient.DEFAULT_BYTES_DATA_KEY; // Used to retrieve data stored without a key ListrequestedKeys = Arrays.asList(key1, key2, key3); // Add keys to array RetrieveBytesRequest retrieveRequest = new RetrieveBytesRequest.Builder() .setKeys(requestedKeys) .build(); client.retrieveBytes(retrieveRequest) .addOnSuccessListener( result -> { Map blockstoreDataMap = result.getBlockstoreDataMap(); for (Map.Entry entry : blockstoreDataMap.entrySet()) { Log.d(TAG, String.format( "Retrieved bytes %s associated with key %s.", new String(entry.getValue().getBytes()), entry.getKey())); } }) .addOnFailureListener(e -> Log.e(TAG, "Failed to store bytes", e));
Kotlin
val client = Blockstore.getClient(this) // Retrieve data associated with certain keys. val key1 = "com.example.app.key1" val key2 = "com.example.app.key2" val key3 = BlockstoreClient.DEFAULT_BYTES_DATA_KEY // Used to retrieve data stored without a key val requestedKeys = Arrays.asList(key1, key2, key3) // Add keys to array val retrieveRequest = RetrieveBytesRequest.Builder() .setKeys(requestedKeys) .build() client.retrieveBytes(retrieveRequest) .addOnSuccessListener { result: RetrieveBytesResponse -> val blockstoreDataMap = result.blockstoreDataMap for ((key, value) in blockstoreDataMap) { Log.d(ContentValues.TAG, String.format( "Retrieved bytes %s associated with key %s.", String(value.bytes), key)) } } .addOnFailureListener { e: Exception? -> Log.e(ContentValues.TAG, "Failed to store bytes", e) }
Tüm jetonlar alınıyor.
Aşağıda, BlockStore'a kaydedilen tüm jetonların nasıl alınacağına dair bir örnek verilmiştir.
Java
BlockstoreClient client = Blockstore.getClient(this) // Retrieve all data. RetrieveBytesRequest retrieveRequest = new RetrieveBytesRequest.Builder() .setRetrieveAll(true) .build(); client.retrieveBytes(retrieveRequest) .addOnSuccessListener( result -> { MapblockstoreDataMap = result.getBlockstoreDataMap(); for (Map.Entry entry : blockstoreDataMap.entrySet()) { Log.d(TAG, String.format( "Retrieved bytes %s associated with key %s.", new String(entry.getValue().getBytes()), entry.getKey())); } }) .addOnFailureListener(e -> Log.e(TAG, "Failed to store bytes", e));
Kotlin
val client = Blockstore.getClient(this) val retrieveRequest = RetrieveBytesRequest.Builder() .setRetrieveAll(true) .build() client.retrieveBytes(retrieveRequest) .addOnSuccessListener { result: RetrieveBytesResponse -> val blockstoreDataMap = result.blockstoreDataMap for ((key, value) in blockstoreDataMap) { Log.d(ContentValues.TAG, String.format( "Retrieved bytes %s associated with key %s.", String(value.bytes), key)) } } .addOnFailureListener { e: Exception? -> Log.e(ContentValues.TAG, "Failed to store bytes", e) }
Aşağıda, varsayılan anahtarı almayla ilgili bir örnek verilmiştir.
Java
BlockStoreClient client = Blockstore.getClient(this); RetrieveBytesRequest retrieveRequest = new RetrieveBytesRequest.Builder() .setKeys(Arrays.asList(BlockstoreClient.DEFAULT_BYTES_DATA_KEY)) .build(); client.retrieveBytes(retrieveRequest);
Kotlin
val client = Blockstore.getClient(this) val retrieveRequest = RetrieveBytesRequest.Builder() .setKeys(Arrays.asList(BlockstoreClient.DEFAULT_BYTES_DATA_KEY)) .build() client.retrieveBytes(retrieveRequest)
Jetonları silme
Jetonların BlockStore'dan silinmesi, aşağıdaki nedenlerden dolayı gerekebilir:
- Kullanıcı, oturumu kapatma kullanıcı işlemleri akışı gerçekleştirilir.
- Jeton iptal edilmiş veya geçersiz.
Jetonları almaya benzer şekilde, silme gerektiren bir anahtar dizisi ayarlayarak hangi jetonların silinmesi gerektiğini belirtebilirsiniz.
Aşağıda, belirli anahtarları silmeyle ilgili örnek verilmiştir.
Java
BlockstoreClient client = Blockstore.getClient(this); // Delete data associated with certain keys. String key1 = "com.example.app.key1"; String key2 = "com.example.app.key2"; String key3 = BlockstoreClient.DEFAULT_BYTES_DATA_KEY; // Used to delete data stored without key ListrequestedKeys = Arrays.asList(key1, key2, key3) // Add keys to array DeleteBytesRequest deleteRequest = new DeleteBytesRequest.Builder() .setKeys(requestedKeys) .build(); client.deleteBytes(deleteRequest)
Kotlin
val client = Blockstore.getClient(this) // Retrieve data associated with certain keys. val key1 = "com.example.app.key1" val key2 = "com.example.app.key2" val key3 = BlockstoreClient.DEFAULT_BYTES_DATA_KEY // Used to retrieve data stored without a key val requestedKeys = Arrays.asList(key1, key2, key3) // Add keys to array val retrieveRequest = DeleteBytesRequest.Builder() .setKeys(requestedKeys) .build() client.deleteBytes(retrieveRequest)
Tüm Jetonları Sil
Aşağıdaki örnek, şu anda BlockStore'da kayıtlı olan tüm jetonları siler:
Java
// Delete all data. DeleteBytesRequest deleteAllRequest = new DeleteBytesRequest.Builder() .setDeleteAll(true) .build(); client.deleteBytes(deleteAllRequest) .addOnSuccessListener(result -> Log.d(TAG, "Any data found and deleted? " + result));
Kotlin
val deleteAllRequest = DeleteBytesRequest.Builder() .setDeleteAll(true) .build() client.deleteBytes(deleteAllRequest) .addOnSuccessListener { result: Boolean -> Log.d(TAG, "Any data found and deleted? $result") }
Uçtan uca şifreleme
Uçtan uca şifrelemenin kullanılabilir olması için cihazda Android 9 veya sonraki bir sürüm yüklü olmalı ve kullanıcı, cihazında ekran kilidi (PIN, desen veya şifre) ayarlamış olmalıdır. isEndToEndEncryptionAvailable()
yöntemini çağırarak cihazda şifrelemenin kullanılıp kullanılamayacağını doğrulayabilirsiniz.
Aşağıdaki örnekte, bulut yedeklemesi sırasında şifrelemenin kullanılabilir olup olmayacağını nasıl doğrulayacağınız gösterilmektedir:
client.isEndToEndEncryptionAvailable()
.addOnSuccessListener { result ->
Log.d(TAG, "Will Block Store cloud backup be end-to-end encrypted? $result")
}
Bulut yedeklemeyi etkinleştir
Bulut yedeklemesini etkinleştirmek için StoreBytesData
nesnenize setShouldBackupToCloud()
yöntemini ekleyin. setShouldBackupToCloud()
doğru değerine ayarlandığında Block Store, depolanan baytları düzenli olarak buluta yedekler.
Aşağıdaki örnekte, yalnızca bulut yedeklemesi uçtan uca şifrelendiğinde bulut yedeklemesinin nasıl etkinleştirileceği gösterilmektedir:
val client = Blockstore.getClient(this)
val storeBytesDataBuilder = StoreBytesData.Builder()
.setBytes(/* BYTE_ARRAY */)
client.isEndToEndEncryptionAvailable()
.addOnSuccessListener { isE2EEAvailable ->
if (isE2EEAvailable) {
storeBytesDataBuilder.setShouldBackupToCloud(true)
Log.d(TAG, "E2EE is available, enable backing up bytes to the cloud.")
client.storeBytes(storeBytesDataBuilder.build())
.addOnSuccessListener { result ->
Log.d(TAG, "stored: ${result.getBytesStored()}")
}.addOnFailureListener { e ->
Log.e(TAG, “Failed to store bytes”, e)
}
} else {
Log.d(TAG, "E2EE is not available, only store bytes for D2D restore.")
}
}
Nasıl test edilir?
Geri yükleme akışlarını test etmek için geliştirme sırasında aşağıdaki yöntemleri kullanın.
Aynı cihazı kaldırma/yeniden yükleme
Kullanıcı, Yedekleme hizmetlerini etkinleştirirse (Ayarlar > Google > Yedekleme bölümünden kontrol edilebilir) Engelleme Mağazası verileri, uygulamanın kaldırılması/yeniden yüklenmesi boyunca korunur.
Test etmek için şu adımları uygulayabilirsiniz:
- BlockStore API'yi test uygulamanıza entegre edin.
- Verilerinizi depolamak amacıyla BlockStore API'yi çağırmak için test uygulamasını kullanın.
- Test uygulamanızı kaldırıp aynı cihazda yeniden yükleyin.
- Verilerinizi almak amacıyla BlockStore API'yi çağırmak için test uygulamasını kullanın.
- Alınan baytların, yüklemeyi kaldırmadan önce depolananlarla aynı olduğunu doğrulayın.
Cihazdan cihaza
Çoğu durumda, bu işlem hedef cihazın fabrika ayarlarına sıfırlanmasını gerektirir. Ardından Android kablosuz geri yükleme akışı veya Google kablo geri yükleme (desteklenen cihazlar için) bölümüne girebilirsiniz.
Buluta geri yükleme
- Blockstore API'yi test uygulamanıza entegre edin. Test uygulamasının Play Store'a gönderilmesi gerekir.
- Kaynak cihazda, test uygulamasını kullanarak verilerinizi depolamak için Blockstore API'yi çağırmanız gerekir. Doğru seçeneğine ayarlanmış olması gerekir.
- İşletim sistemi ve üstü cihazlarda bir Block Store bulut yedeklemesini manuel olarak tetikleyebilirsiniz. Bunun için Ayarlar > Google > Yedekle'ye gidip "Şimdi Yedekle" düğmesini tıklayın.
- Block Store bulut yedeklemesinin başarılı olduğunu doğrulamak için şunları yapabilirsiniz:
- Yedekleme tamamlandıktan sonra "CloudSyncBpTkSvc" etiketine sahip günlük satırlarını arayın.
- Şöyle satırlar görebilirsiniz: “......, CloudSyncBpTkSvc: sync sonuç: SUCCESS, ..., uploaded size: XXX bytes ...”
- Block Store bulut yedeklemesinden sonra 5 dakikalık bir "bekleme" süresi vardır. Bu 5 dakika içinde, "Şimdi Yedekle" düğmesi tıklandığında başka bir Block Store bulut yedeklemesi tetiklenmez.
- Block Store bulut yedeklemesinin başarılı olduğunu doğrulamak için şunları yapabilirsiniz:
- Hedef cihazı fabrika ayarlarına sıfırlayın ve bulut geri yükleme akışından geçin. Geri yükleme akışı sırasında test uygulamanızı geri yüklemeyi seçin. Bulut geri yükleme akışları hakkında daha fazla bilgi edinmek için Desteklenen bulut geri yükleme akışları bölümüne bakın.
- Verilerinizi almak amacıyla Blockstore API'yi çağırmak için hedef cihazda test uygulamasını kullanın.
- Alınan baytların, kaynak cihazda depolananla aynı olduğunu doğrulayın.
Cihaz Gereksinimleri
Uçtan Uca Şifreleme
- Uçtan Uca şifreleme, Android 9 (API 29) ve sonraki sürümleri çalıştıran cihazlarda desteklenir.
- Uçtan uca şifrelemenin etkinleştirilmesi ve kullanıcı verilerinin doğru şekilde şifrelenmesi için cihazda PIN, desen veya şifreyle ayarlanmış bir ekran kilidi olması gerekir.
Cihazdan Cihaza Geri Yükleme Akışı
Cihazlardan cihaza geri yükleme için bir kaynak ve hedef cihaz gereklidir. Bunlar veri aktaran iki cihaz olacaktır.
Kaynak cihazların yedekleme için Android 6 (API 23) ve sonraki sürümleri çalıştırıyor olması gerekir.
Geri yükleme imkanına sahip olmak için Android 9 (API 29) ve sonraki sürümleri çalıştıran cihazları hedefleyin.
Cihazdan cihaza geri yükleme akışıyla ilgili daha fazla bilgiyi burada bulabilirsiniz.
Bulut Yedekleme ve Geri Yükleme Akışı
Bulutta yedekleme ve geri yükleme için bir kaynak cihaz ve hedef cihaz gerekir.
Kaynak cihazların yedekleme için Android 6 (API 23) ve sonraki sürümleri çalıştırıyor olması gerekir.
Hedef cihazlar, tedarikçi firmalara göre desteklenir. Pixel cihazlar bu özelliği Android 9 (API 29) ve diğer tüm cihazların Android 12 (API 31) veya sonraki bir sürümünü çalıştırmalıdır.