Search code examples
androidbackupblockstore

Block store not storing data on Android 13


I have added storing and fetching data from Block store in a sample activity. When I call the method to store the data, and then afterwards read it the code works perfectly on all devices. However when I uninstall the app and then install it again on the same device, and then try to read the data it works perfectly on Android 9, 10, 11, 12 but not on Android 13 . I get an empty result list.

Tests done on Pixel 7 and Samsung S21 with Android 13

Does anyone know what I need to do to make it work on Android 13?

attempted step: adding allowBackup:true in the AndroidManifest.xml

Here is the activity:

class TestBlocksActivity : AppCompatActivity() {

    lateinit var binding: ActivityTestBlockBinding

    private val blockstoreClient by lazy { Blockstore.getClient(applicationContext) }

    private val tokenKey = "key.token.stage"
    private val tokenValue = "token.test"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityTestBlockBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.deleteTokenButton.setOnClickListener {
            deleteBlockstoreData()
        }

        binding.storeTokenButton.setOnClickListener {
            storeBlockstoreData()
        }

        binding.loadTokenButton.setOnClickListener {
            getBlockstoreData()
        }
    }

    private fun storeBlockstoreData() {
        val tokenRequest = StoreBytesData.Builder()
            .setShouldBackupToCloud(true)
            .setBytes(tokenValue.toByteArray()) // Call this method to set the key value with which the data should be associated with.
            .setKey(tokenKey)
            .build()
        blockstoreClient.storeBytes(tokenRequest)
            .addOnSuccessListener {
                binding.lastActionText.text = """Token stored: $tokenValue """
                binding.storedDataText.text = "Unkown - Load to check"
                Timber.tag("BLOCKSTORE_TEST").d("""Stored token: {"$tokenKey", "$tokenValue"}""")
            }
            .addOnFailureListener { e ->
                binding.lastActionText.text = "Exception while storing key"
                Timber.tag("BLOCKSTORE_TEST").e(e)
            }
    }

    private fun getBlockstoreData() {

        val retrieveRequest = RetrieveBytesRequest.Builder()
            .setRetrieveAll(true)
            .build()

        blockstoreClient.retrieveBytes(retrieveRequest)
            .addOnSuccessListener { result ->
                if (result.blockstoreDataMap.isEmpty()) {
                    binding.lastActionText.text = "retrieving token: no token found"
                    Timber.tag("BLOCKSTORE_TEST").d("Retreiving token: no token found")
                }
                result.blockstoreDataMap.forEach { (key, value) ->
                    val valueString = String(value.bytes)
                    if (key == tokenKey) {
                        binding.lastActionText.text = "Retrieved token: $valueString"
                        binding.storedDataText.text = valueString
                    }
                    Timber.tag("BLOCKSTORE_TEST").d("""Retrieved token: {"$key", "$valueString"}""")
                }
            }
            .addOnFailureListener {
                binding.lastActionText.text = "Exception while retreiving key"
                Timber.tag("BLOCKSTORE_TEST").e(it)
            }
    }

    private fun deleteBlockstoreData() {
        val deleteBytesRequest = DeleteBytesRequest.Builder()
            .setDeleteAll(true)
            .build()
        blockstoreClient.deleteBytes(deleteBytesRequest)
            .addOnSuccessListener { success ->
                binding.lastActionText.text = if (success) "Deleted key: $tokenKey"
                else "Could not delete key"
                if (success) binding.storedDataText.text = "no value"
                Timber.tag("BLOCKSTORE_TEST").d("${binding.lastActionText.text}")
            }
            .addOnFailureListener {
                binding.lastActionText.text = "Exception while deleting key"
                Timber.tag("BLOCKSTORE_TEST").e(it)
            }
    }

}

activity_test_block.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="24dp">

        <TextView
            android:id="@+id/stored_data_label"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:textSize="20dp"
            android:textStyle="bold"
            android:text="Loaded token:"/>

        <TextView
            android:id="@+id/stored_data_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="start"
            android:textSize="20dp"
            android:text="no token value loaded yet"
            app:layout_constraintTop_toBottomOf="@+id/stored_data_label"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            />

        <TextView
            android:layout_marginTop="20dp"
            android:id="@+id/last_action_label"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@+id/stored_data_text"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:textSize="20dp"
            android:textStyle="bold"
            android:text="Last action:"/>

        <TextView
            android:id="@+id/last_action_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="start"
            android:textSize="20dp"
            android:text="no token value loaded yet"
            app:layout_constraintTop_toBottomOf="@+id/last_action_label"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            />


        <com.google.android.material.button.MaterialButton
            android:id="@+id/load_token_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/last_action_text"
            android:layout_marginTop="40dp"
            android:textAllCaps="false"
            android:textSize="20dp"
            android:text="Load token"/>

        <com.google.android.material.button.MaterialButton
            android:id="@+id/store_token_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/load_token_button"
            android:layout_marginTop="20dp"
            android:textAllCaps="false"
            android:textSize="20dp"
            android:text="Store token"/>


        <com.google.android.material.button.MaterialButton
            android:id="@+id/delete_token_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/store_token_button"
            android:textAllCaps="false"
            android:layout_marginTop="20dp"
            android:textSize="20dp"
            android:text="Delete token"/>



    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

Solution

  • I have solved it. On Android 13 Backup by Google One needs to be turned on.