Birçok kullanıcı, yeni bir Android destekli cihaz kurarken kendi kimlik bilgilerini yönetmeye devam ediyor. Bu manuel süreç zorlu 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ı şifrelerini kaydetmeyle ilişkili karmaşıklık veya güvenlik riski olmadan kullanıcı kimlik bilgilerini kaydetmelerini sağlayarak bu sorunu çözmeyi amaçlar.
Block Store API, uygulamanızın daha sonra yeni bir cihazda kullanıcıların kimliğini yeniden doğrulamak için alabileceği verileri depolamasına olanak tanır. Bu sayede, yeni cihazda uygulamanızı ilk kez başlatırken oturum açma ekranını görmeleri gerekmediği için kullanıcılara daha sorunsuz bir deneyim sunulur.
Blok mağazayı kullanmanın avantajları şunlardır:
- Geliştiriciler için şifrelenmiş kimlik bilgisi depolama çözümü. Kimlik bilgileri mümkün olduğunda uçtan uca şifrelenir.
- Kullanıcı adları ve şifreler yerine jetonları kaydeder.
- Oturum açma akışlarındaki zorlukları ortadan kaldırın.
- Kullanıcıları karmaşık şifreleri yönetme yükünden kurtarır.
- Google, kullanıcının kimliğini doğrular.
Başlamadan önce
Uygulamanızı hazırlamak için aşağıdaki bölümlerdeki adımları tamamlayın.
Uygulamanızı yapılandırma
Proje düzeyindeki build.gradle
dosyanızda, Google'ın Maven deposunu hem buildscript
hem de allprojects
bölümünüze ekleyin:
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
Block Store API için Google Play Hizmetleri bağımlılığını modülünüzün Gradle derleme dosyasına ekleyin. Bu dosya genellikle app/build.gradle
olur:
dependencies {
implementation 'com.google.android.gms:play-services-auth-blockstore:16.4.0'
}
İşleyiş şekli
Block Store, geliştiricilerin 16 bayt dizisine kadar kaydetmesine ve geri yüklemesine olanak tanır. Bu, mevcut kullanıcı oturumuyla ilgili önemli bilgileri kaydetmenize olanak tanır ve bu bilgileri istediğiniz şekilde kaydetme esnekliği sunar. Bu veriler uçtan uca şifrelenebilir ve Blok Depolama'yı destekleyen altyapı, Yedekleme ve Geri Yükleme altyapısı üzerine kurulmuştur.
Bu kılavuzda, kullanıcının jetonunu Block Store'a kaydetme kullanım alanı ele alınacaktır. Aşağıdaki adımlarda, Block Store'u kullanan bir uygulamanın nasıl çalışacağı açıklanmaktadır:
- Uygulamanızın kimlik doğrulama akışı sırasında veya sonrasında istediğiniz zaman kullanıcının kimlik doğrulama jetonunu daha sonra almak üzere Block Store'da saklayabilirsiniz.
- Jeton yerel olarak depolanır ve buluta da yedeklenebilir. Mümkün olduğunda uçtan uca şifrelenir.
- Kullanıcı yeni bir 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 cihazdaki Block Store'dan kaydedilmiş jetonu alabilir.
Jetonu kaydetme
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 maksimum 4 KB olan benzersiz bir anahtar/değer çifti kullanarak saklayabilirsiniz. Jetonu depolamak için setBytes()
ve setKey()
işlevlerini StoreBytesData.Builder
örneğinde çağırarak kullanıcının kimlik bilgilerini kaynak cihazda depolayın. Jetonu Block Store'da kaydettikten sonra jeton şifrelenir ve cihazda yerel olarak saklanı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 verilerde varsayılan anahtar BlockstoreClient.DEFAULT_BYTES_DATA_KEY
kullanılı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, kullanıcı yeni bir cihazda geri yükleme akışını tamamladığında Google Play Hizmetleri önce kullanıcıyı doğrular, ardından Block Store verilerinizi alır. Kullanıcı, geri yükleme akışının bir parçası olarak uygulama verilerinizi geri yüklemeyi kabul ettiğinden ek izin gerekmez. Kullanıcı uygulamanızı açtığında retrieveBytes()
işlevini çağırarak Block Store'dan jetonunuzu isteyebilirsiniz. Daha sonra alınan jeton, kullanıcının yeni cihazda oturumunun açık kalması 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<String, BlockstoreData> blockstoreDataMap = result.getBlockstoreDataMap(); for (Map.Entry<String, BlockstoreData> 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ı alma
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 -> { Map<String, BlockstoreData> blockstoreDataMap = result.getBlockstoreDataMap(); for (Map.Entry<String, BlockstoreData> 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) }
Varsayılan anahtarın nasıl alınacağına ilişkin bir örneği aşağıda bulabilirsiniz.
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
BlockStore'dan jeton silmek aşağıdaki nedenlerle gerekli olabilir:
- Kullanıcı, oturumu kapatma kullanıcı işlemlerini gerçekleştirir.
- Jeton iptal edilmiş veya geçersiz.
Jetonları alma işlemine benzer şekilde, silinmesi gereken jetonları, silinmesi gereken anahtarların dizisini ayarlayarak belirtebilirsiniz.
Aşağıdaki örnekte belirli anahtarların nasıl silineceği gösterilmektedir:
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 örnekte, BlockStore'da kayıtlı tüm jetonların nasıl silineceği gösterilmektedir:
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() retrieve bytes, the keyBlockstoreClient.DEFAULT_BYTES_DATA_KEY
can be used in theRetrieveBytesRequest
instance in order to get your saved data
The following example shows how to retrieve the default key.
Java
End-to-end encryption
In order for end-to-end encryption to be made available, the device must be
running Android 9 or higher, and the user must have set a screen lock
(PIN, pattern, or password) for their device. You can verify if encryption will
be available on the device by calling isEndToEndEncryptionAvailable()
.
The following sample shows how to verify if encryption will be available during cloud backup:
client.isEndToEndEncryptionAvailable()
.addOnSuccessListener { result ->
Log.d(TAG, "Will Block Store cloud backup be end-to-end encrypted? $result")
}
Bulut yedeklemeyi etkinleştirme
Bulut yedeklemeyi etkinleştirmek için setShouldBackupToCloud()
yöntemini StoreBytesData
nesnenize ekleyin. setShouldBackupToCloud()
doğru olarak ayarlandığında Block Store, depolanan baytları düzenli olarak buluta yedekler.
Aşağıdaki örnekte, yalnızca bulut yedekleme uçtan uca şifrelendiğinde bulut yedeklemenin 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.")
}
}
Test etme
Geri yükleme akışlarını test etmek için geliştirme sırasında aşağıdaki yöntemleri kullanın.
Aynı cihazda yüklemeyi kaldırma/yeniden yükleme
Kullanıcı Yedekleme hizmetlerini etkinleştirirse (Ayarlar > Google > Yedekleme bölümünden kontrol edilebilir), Block Store verileri uygulamanın kaldırılması/yeniden yüklenmesi sırasında korunur.
Test etmek için şu adımları uygulayabilirsiniz:
- Block Store API'yi test uygulamanıza entegre edin.
- Verilerinizi depolamak için Block Store API'yi çağırmak üzere test uygulamasını kullanın.
- Test uygulamanızı kaldırıp aynı cihaza yeniden yükleyin.
- Verilerinizi almak için Block Store API'yi çağırmak üzere test uygulamasını kullanın.
- Alınan baytların, kaldırmadan önce depolananlarla aynı olduğunu doğrulayın.
Cihazdan cihaza
Çoğu durumda, bu işlem için hedef cihazın fabrika ayarlarına sıfırlanması gerekir. Ardından Android kablosuz geri yükleme akışını veya Google kablosuyla geri yükleme'yi (desteklenen cihazlar için) başlatabilirsiniz.
Buluttan geri yükleme
- Block Store API'yi test uygulamanıza entegre edin. Test uygulamasının Play Store'a gönderilmesi gerekir.
- Kaynak cihazda, verilerinizi depolamak için Block Store API'yi çağırmak üzere test uygulamasını kullanın.
shouldBackUpToCloud
,true
olarak ayarlanmalıdır. - O ve sonraki sürümlerin yüklü olduğu cihazlarda Block Store bulut yedeklemesini manuel olarak tetikleyebilirsiniz:
Ayarlar > Google > Yedekleme'ye gidip "Şimdi Yedekle" düğmesini tıklayın.
- Block Store bulut yedeklemesinin başarılı olduğunu doğrulamak için:
- Yedekleme işlemi tamamlandıktan sonra "CloudSyncBpTkSvc" etiketli günlük satırlarını arayın.
- Şuna benzer satırlar görmelisiniz: "......, CloudSyncBpTkSvc: sync result: SUCCESS, ..., uploaded size: XXX bytes ..."
- Block Store bulut yedeğinden sonra 5 dakikalık bir "soğuma" süresi vardır. Bu 5 dakika içinde "Şimdi Yedekle" düğmesini tıklamak başka bir Block Store bulut yedeğini tetiklemez.
- Block Store bulut yedeklemesinin başarılı olduğunu doğrulamak için:
- Hedef cihazı fabrika ayarlarına sıfırlayın ve buluttan geri yükleme akışını uygulayın. Geri yükleme akışı sırasında test uygulamanızı geri yüklemek için seçin. Buluttan geri yükleme akışları hakkında daha fazla bilgi için Desteklenen buluttan geri yükleme akışları başlıklı makaleyi inceleyin.
- Hedef cihazda, verilerinizi almak için Block Store API'yi çağırmak üzere test uygulamasını kullanın.
- Alınan baytların kaynak cihazda depolananlarla 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ştirilip kullanıcının verilerinin doğru şekilde şifrelenmesi için cihazda PIN, desen veya şifre ile ayarlanmış bir ekran kilidi olmalıdır.
Cihazdan cihaza geri yükleme akışı
Cihazdan cihaza geri yükleme için bir kaynak cihazınız ve bir hedef cihazınız olmalıdır. Bu iki cihaz, veri aktarımı yapacak cihazlardır.
Yedekleme için kaynak cihazlarda Android 6 (API 23) ve sonraki sürümlerin yüklü olması gerekir.
Android 9 (API 29) ve sonraki sürümleri çalıştıran hedef cihazlarda geri yükleme özelliği bulunur.
Cihazlar arası geri yükleme akışı hakkında daha fazla bilgiyi burada bulabilirsiniz.
Bulut Yedekleme ve Geri Yükleme Akışı
Bulut yedekleme ve geri yükleme için kaynak cihaz ve hedef cihaz gerekir.
Yedekleme için kaynak cihazlarda Android 6 (API 23) ve sonraki sürümlerin yüklü olması gerekir.
Hedef cihazlar, satıcılarına göre desteklenir. Pixel cihazlar bu özelliği Android 9 (API 29) sürümünden itibaren kullanabilir. Diğer tüm cihazlarda ise Android 12 (API 31) veya sonraki bir sürüm yüklü olmalıdır.