Can't import androidx.datastore.dataStore (trying to recreate Google Codelab Example)

Viewed 1606

Problem:

I'm trying to recreate this codelab tutorial project https://developer.android.com/codelabs/android-proto-datastore, but Android Studio can't import androidx.datastore.dataStore

Steps:

  1. create new Kotlin project with an empty Acivity

  2. modify gradle file

  3. Switch to Android Studio's Project view

  4. create a folder named proto inside of app/src/main

  5. create and modify file user_prefs.proto inside of app/src/main/proto

  6. Build -> Clean Project -> rebuild project

  7. Create a serializer class called UserPreferencesSerializer

  8. Trying to add the following Code to the empty MainActivity.kt

    private const val DATA_STORE_FILE_NAME = "user_prefs.pb"

    private val Context.userPreferencesStore: DataStore by dataStore( fileName = DATA_STORE_FILE_NAME, serializer = UserPreferencesSerializer )

After this step Android Studio marks dataStore and shows the warning "Unresolved reference: dataStore" I'm also unable to import androidx.datastore.dataStore, but I can't find a missing import in my gradle file. Please, can someone tell me how I can resolve this problem?

Code:

build.gradle

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id "com.google.protobuf" version "0.8.12"
}



android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.example.test"
        minSdkVersion 28
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    
    implementation  "androidx.datastore:datastore-core:1.0.0-alpha08"
    implementation  "com.google.protobuf:protobuf-javalite:3.11.0"

}

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:3.10.0"
    }

    // Generates the java Protobuf-lite code for the Protobufs in this project. See
    // https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
    // for more information.
    generateProtoTasks {
        all().each { task ->
            task.builtins {
                java {
                    option 'lite'
                }
            }
        }
    }
}

user_prefs.proto

syntax = "proto3";

option java_package = "com.example.test";
option java_multiple_files = true;

message UserPreferences {
  // filter for showing / hiding completed tasks
  bool show_completed = 1;
}

UserPreferencesSerializer

package com.example.test

import androidx.datastore.core.CorruptionException
import androidx.datastore.core.Serializer
import com.google.protobuf.InvalidProtocolBufferException
import java.io.InputStream
import java.io.OutputStream

object UserPreferencesSerializer : Serializer<UserPreferences> {
    override val defaultValue: UserPreferences = UserPreferences.getDefaultInstance()
    override suspend fun readFrom(input: InputStream): UserPreferences {
        try {
            return UserPreferences.parseFrom(input)
        } catch (exception: InvalidProtocolBufferException) {
            throw CorruptionException("Cannot read proto.", exception)
        }
    }

    override suspend fun writeTo(t: UserPreferences, output: OutputStream) = t.writeTo(output)
}

MainActivity.kt

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.datastore.core.DataStore


private const val DATA_STORE_FILE_NAME = "user_prefs.pb"
private val Context.userPreferencesStore: DataStore<UserPreferences> by dataStore(
    fileName = DATA_STORE_FILE_NAME,
    serializer = UserPreferencesSerializer
)


class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}
4 Answers

I also had this problem while working on a project.

I found that I was using datastore-core and needed datastore-preferences. So I changed my dependency declaration from:

implementation 'androidx.datastore:datastore-core:1.0.0-alpha08'

to:

implementation 'androidx.datastore:datastore-preferences:1.0.0'

Possibly there was a breaking change between alpha08 and the 1.0.0 release.

The dataStore delegate is part of the androidx.datastore:datastore library.

Add the dependency to your modudle's build.gradle file. Replace $dataStoreVersion with the version of data store which you use, e.g. 1.0.0:

implementation  "androidx.datastore:datastore:$dataStoreVersion"

You can find the available versions here in Google's Maven repository.

After adding this dependency, you can use by dataStore by adding the following import to your class:

import androidx.datastore.dataStore

In Android documentation:

val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")

This line should be at the top of your code. See DataStore documenation

After a lot of searching, The problem is simple. Make sure Gradle is not in offline mode.

Also, ensure that you use this dependency.

implementation "androidx.datastore:datastore-preferences:$dataStoreVersion"
Related