The lore
I have this data class UserSettingsModel, that I have moved to, because of a need to store some appSettings: Map<String, AppSettingsModel>. This is for an app that reads off user-specified notifications from user-specified apps.
Those data classes are defined thusly:
UserSettingsModel
package com.mikewarren.speakify.data
data class UserSettingsModel(
val useDarkTheme: Boolean,
val selectedTTSVoice: String,
val appSettings: Map<String, AppSettingsModel>,
)
AppSettingsModel
package com.mikewarren.speakify.data
data class AppSettingsModel(
val appName: String,
val announcerVoice: String?, // Nullable if no voice is selected
val notificationSources: List<String> = emptyList()
)
Ok, what's the problem?
I created this app/src/main/proto/app_settings.proto, originally defined to be:
protobuf
syntax = "proto3";
option java_package = "com.mikewarren.speakify.data";
option java_multiple_files = true;
message AppSettingsModel {
string app_name = 1;
string announcer_voice = 2;
repeated string notification_sources = 3;
}
message UserSettingsModel {
bool use_dark_theme = 1;
string selected_tts_voice = 2;
map<string, AppSettingsModel> app_settings = 3;
}
built the project, tried to use the stuff, but faced some confusion immediately. After asking the AI, it turns out that Proto generates its own data model classes, separate from yours, with their own methods. So I changed my app/src/main/proto/app_settings.proto:
protobuf
syntax = "proto3";
option java_package = "com.mikewarren.speakify.data";
option java_multiple_files = true;
message AppSettings {
string app_name = 1;
string announcer_voice = 2;
repeated string notification_sources = 3;
}
message UserSettings {
bool use_dark_theme = 4;
string selected_tts_voice = 5;
map<string, AppSettings> app_settings = 6;
}
tried to rebuild, but still didn't see any generated UserSettings or AppSettings classes!
Here's my app's build.gradle:
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
id "kotlin-kapt"
id 'com.google.dagger.hilt.android' // Add this line
}
final int androidSdkVersion = 35
android {
namespace 'com.mikewarren.speakify'
compileSdk androidSdkVersion
defaultConfig {
applicationId "com.mikewarren.speakify"
minSdk 24
targetSdk androidSdkVersion
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_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
}
buildFeatures {
compose true
}
}
dependencies {
implementation("com.google.dagger:hilt-android:2.51.1")
implementation libs.androidx.media3.common.ktx
kapt("com.google.dagger:hilt-compiler:2.51.1")
// If using Hilt with Compose Navigation:
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")
implementation("com.google.protobuf:protobuf-javalite:3.18.0") // or latest version
// Add this line:
implementation("com.google.protobuf:protoc:3.17.2") // Use the same version as in your protobuf extension
implementation("androidx.datastore:datastore:1.1.4")
implementation libs.androidx.core.ktx
implementation libs.androidx.lifecycle.runtime.ktx
implementation libs.androidx.activity.compose
implementation platform(libs.androidx.compose.bom)
implementation libs.androidx.ui
implementation libs.androidx.ui.graphics
implementation libs.androidx.ui.tooling.preview
implementation libs.androidx.material3
implementation libs.androidx.navigation.runtime.ktx
implementation libs.androidx.navigation.compose
implementation libs.androidx.espresso.core
// https://mvnrepository.com/artifact/androidx.datastore/datastore-preferences
implementation "androidx.datastore:datastore-preferences:1.1.4"
implementation libs.androidx.datastore.core.android
implementation libs.androidx.datastore.preferences.core.jvm
testImplementation libs.junit
androidTestImplementation libs.androidx.junit
androidTestImplementation libs.androidx.espresso.core
androidTestImplementation platform(libs.androidx.compose.bom)
androidTestImplementation libs.androidx.ui.test.junit4
debugImplementation libs.androidx.ui.tooling
debugImplementation libs.androidx.ui.test.manifest
runtimeOnly libs.androidx.lifecycle
}
and the root-level one, for good measure:
buildscript {
dependencies {
classpath "com.android.tools.build:gradle:8.9.1"
classpath "com.google.dagger:hilt-android-gradle-plugin:2.51.1" // Add this line with the correct version
classpath 'com.google.protobuf:protobuf-javalite:4.30.2'
}
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.compose) apply false
}
classpath, which is likely NOT what you want, and animplementationwith a lower version)?Serializableinstead