I have been following a tutorial from Geeks for Geeks on how to make a simple note app for Android. I've practically copied to code word-by-word (except for a minor fix in the gradle file as advised from a Stack Overflow post and a comment in the YouTube comment section), yet the app crashes every time I open it even after clearing all the caches and rebuilding the project.
Links:
https://www.geeksforgeeks.org/how-to-build-a-simple-note-android-app-using-mvvm-and-room-database/
https://www.youtube.com/watch?v=D2F5t-phP04
Now, I know the problem with the code stems from the below command line.
viewModel = ViewModelProvider(
this,
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
).get(NoteViewModel::class.java)
Every time I include the above line and launch the app, the app crashes, and my phone cannot open it. Commenting out the above line and the code below it allows the app to be opened without an issue.
(App gradle)
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.example.notepractice"
minSdk 26
targetSdk 32
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
}
packagingOptions {
exclude 'META-INF/atomicfu.kotlin_module'
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
implementation "androidx.activity:activity-ktx:$rootProject.activityVersion"
// Dependencies for working with Architecture components
// You'll probably have to update the version numbers in build.gradle (Project)
implementation 'androidx.fragment:fragment-ktx:1.1.0'
// Room components
implementation "androidx.room:room-ktx:$rootProject.roomVersion"
annotationProcessor "androidx.room:room-compiler:$rootProject.roomVersion"
androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-common-java8:$rootProject.lifecycleVersion"
// Kotlin components
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"
// UI
implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
implementation "com.google.android.material:material:$rootProject.materialVersion"
// Testing
testImplementation "junit:junit:$rootProject.junitVersion"
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"
androidTestImplementation ("androidx.test.espresso:espresso-core:$rootProject.espressoVersion", {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestImplementation "androidx.test.ext:junit:$rootProject.androidxJunitVersion"
}
(Project gradle)
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.5.31"
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle-api:7.2.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id 'com.android.application' version '7.2.0' apply false
id 'com.android.library' version '7.2.0' apply false
id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
}
allprojects {
repositories {
google()
mavenCentral()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
/*
ext {
activityVersion = '1.4.0'
appCompatVersion = '1.4.0'
constraintLayoutVersion = '2.1.2'
coreTestingVersion = '2.1.0'
coroutines = '1.5.2'
lifecycleVersion = '2.4.0'
materialVersion = '1.4.0'
roomVersion = '2.3.0'
// testing
junitVersion = '4.13.2'
espressoVersion = '3.4.0'
androidxJunitVersion = '1.1.3'
}
*/
ext {
activityVersion = '1.2.3'
appCompatVersion = '1.3.0'
constraintLayoutVersion = '2.0.4'
coreTestingVersion = '2.1.0'
coroutines = '1.5.0'
lifecycleVersion = '2.3.1'
materialVersion = '1.3.0'
roomVersion = '2.3.0'
// testing
junitVersion = '4.13.2'
espressoVersion = '3.1.0'
androidxJunitVersion = '1.1.2'
}
(Main Activity)
package com.example.notepractice
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.FloatingActionButton
import java.util.*
class MainActivity : AppCompatActivity(), NoteClickInterface, NoteClickDeleteInterface {
lateinit var viewModel: NoteViewModel
lateinit var notesRV: RecyclerView
lateinit var addFAB: FloatingActionButton
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
notesRV = findViewById(R.id.RVNotes)
addFAB = findViewById(R.id.FABAddNote)
notesRV.layoutManager = LinearLayoutManager(this)
val noteRVAdapter = NoteRVAdapter(this, this, this)
notesRV.adapter = noteRVAdapter
viewModel = ViewModelProvider(
this,
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
).get(NoteViewModel::class.java)
/*
viewModel.allNotes.observe(this, Observer { list ->
list?.let {
noteRVAdapter.updateList(it)
}
})
addFAB.setOnClickListener {
val intent = Intent(this#MainActivity, AddEditNoteActivity::class.java)
startActivity(intent)
this.finish()
}
*/
}
override fun onNoteClick(note: Note) {
val intent = Intent(this#MainActivity, AddEditNoteActivity::class.java)
intent.putExtra("noteType", "Edit")
intent.putExtra("noteTitle", note.noteTitle)
intent.putExtra("noteDescription", note.noteDescription)
intent.putExtra("noteId", note.id)
startActivity(intent)
}
override fun onDeleteIconClick(note: Note) {
viewModel.deleteNote(note)
Toast.makeText(this, "${note.noteTitle} Deleted", Toast.LENGTH_LONG).show()
}
}
(ViewModel)
package com.example.notepractice
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class NoteViewModel(application: Application): AndroidViewModel(application) {
val allNotes: LiveData<List<Note>>
val repository: NoteRepository
init {
val dao = NoteDatabase.getDatabase(application).getNotesDao()
repository = NoteRepository(dao)
allNotes = repository.allNotes
}
fun deleteNote (note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.delete(note)
}
fun updateNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.update(note)
}
fun addNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.insert(note)
}
}
I'd like to end my question post with an actual question, but I am very inexperienced and cannot specify the problem. What would be the correct way to set up a ViewModel in Android with Kotlin?
Try initialising NoteViewModel like this inside your Activity.
private val viewModel: NoteViewModel by lazy {
ViewModelProvider(this).get(NoteViewModel::class.java)
}
Related
The project run with no error on my MacBook intel chip but it gave me E/AndroidRuntime: FATAL EXCEPTION: main on M1 chip I can't find where the problem is.
I suppose there is no error in my code because is already run on other devices and just facing different errors while trying to run it on M1.
the error message:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.memeorshower, PID: 10861
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.memeorshower/com.example.memeorshower.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.memeorshower.viewmodel.ImageTmpViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Thanks in advance
here is my mainActivity code
package com.example.memeorshower
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import com.example.memeorshower.database.texttmp.TextTmp
import com.example.memeorshower.databinding.ActivityMainBinding
import com.example.memeorshower.viewmodel.ImageTmpViewModel
import com.example.memeorshower.viewmodel.TextTmpViewModel
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
lateinit var myImageTmpViewModel: ImageTmpViewModel
lateinit var myTextTmpViewModel: TextTmpViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
myImageTmpViewModel = ViewModelProvider(this).get(ImageTmpViewModel::class.java)
myTextTmpViewModel = ViewModelProvider(this).get(TextTmpViewModel::class.java)
// todo: you have access to both view models, load your data in them.
binding.NewButton.setOnClickListener { makeNewMeme() }
binding.MyProjectButton.setOnClickListener { showMyProjects() }
binding.DatabaseButton.setOnClickListener { showDatabase() }
}
private fun showDatabase() {
val intent = Intent(this, MemeDatabaseActivity::class.java)
startActivity(intent)
}
private fun showMyProjects() {
val intent = Intent(this, MyProjectsActivity::class.java)
startActivity(intent)
}
private fun makeNewMeme() {
val intent = Intent(this, TextTemplateActivity::class.java)
startActivity(intent)
}
}
build.gradle in app folder:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
android {
compileSdkVersion 30
defaultConfig {
applicationId "com.example.memeorshower"
minSdkVersion 14
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'
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
// implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
// Navigation Component
implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
// Room components
implementation "androidx.room:room-runtime:2.2.5"
annotationProcessor "androidx.room:room-compiler:2.2.5"
implementation "androidx.room:room-ktx:2.2.5"
androidTestImplementation "androidx.room:room-testing:2.2.5"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
// Kotlin components
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.72"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5"
implementation 'com.burhanrashid52:photoeditor:1.5.1'
}
build.gradle:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.4.10"
ext.room_version = '2.2.5'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
ImageTmpViewModel class:
class ImageTmpViewModel(application: Application): AndroidViewModel(application) {
private val readAllData: List<ImageTmp>
private val imgDao = AppDatabase.getDatabase(application).imagetmpDao()
init {
readAllData = imgDao.getAll()
}
fun addImage(imgtmp: ImageTmp){
viewModelScope.launch(Dispatchers.IO) {
imgDao.addImage(imgtmp)
}
}
}
ImageTmpDao:
#Dao
interface ImageTmpDao {
#Insert(onConflict = OnConflictStrategy.REPLACE)
fun upsertByReplacement(image: List<ImageTmp>)
#Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun addImage(image: ImageTmp)
#Query("SELECT * FROM image_tmp_table ORDER BY id ASC")
fun getAll(): List<ImageTmp>
#Query("SELECT * FROM image_tmp_table WHERE id = :id ")
fun getByID(id: Int): ImageTmp
#Delete
fun delete(imgtmp: ImageTmp)
}
What is going on with RoomDB and Kotlin coroutines? I am trying, again and again, to use suspend function in Room Dao but every time it shows an error. I even follow the android codelabs example. But it shows an error again. the app doesn't even build if I write suspend in Dao. But if I remove suspend keyword it builds successfully.
It shows the error below:
error: Type of the parameter must be a class annotated with #Entity or a collection/array of it.
kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
My Entity:
import androidx.room.Entity
import androidx.room.PrimaryKey
#Entity(tableName = "vocabulary")
class Vocabulary(
#PrimaryKey(autoGenerate = true)
val vocabularyId: Long,
val word: String,
val meaning: String,
val definition: String,
val example: String,
val partsOfSpeech: String,
val synonyms: String,
val antonyms: String,
val phonetics: String,
val folderId: Long,
val isLearned: Int
)
My Dao:
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
#Dao
interface VocabuilderDao {
#Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertVocab(vocabulary: Vocabulary)
}
My Database class:
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
#Database(entities = [Vocabulary::class], version = 1, exportSchema = false)
public abstract class VocabuilderRoomDb : RoomDatabase(){
abstract fun vocabuilderDao(): VocabuilderDao
companion object{
#Volatile
private var INSTANCE: VocabuilderRoomDb? = null
fun getRoomDatabase(context: Context): VocabuilderRoomDb{
return INSTANCE ?: synchronized(this){
val instance = Room.databaseBuilder(
context.applicationContext,
VocabuilderRoomDb::class.java,
"vocabuilder_roomdb"
).build()
INSTANCE = instance
instance
}
}
}
}
My build.gradle (project level):
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.6.0'
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
ext {
activityVersion = '1.2.3'
appCompatVersion = '1.3.0'
constraintLayoutVersion = '2.0.4'
coreTestingVersion = '2.1.0'
coroutines = '1.5.0'
lifecycleVersion = '2.3.1'
materialVersion = '1.3.0'
roomVersion = '2.3.0'
// testing
junitVersion = '4.13.2'
espressoVersion = '3.1.0'
androidxJunitVersion = '1.1.2'
}
task clean(type: Delete) {
delete rootProject.buildDir
}
My build.gradle(module):
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.domesoft.vocabuilder"
minSdk 21
targetSdk 31
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
}
packagingOptions {
exclude 'META-INF/atomicfu.kotlin_module'
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
implementation "androidx.activity:activity-ktx:$rootProject.activityVersion"
// Dependencies for working with Architecture components
// You'll probably have to update the version numbers in build.gradle (Project)
// Room components
implementation "androidx.room:room-ktx:$rootProject.roomVersion"
kapt "androidx.room:room-compiler:$rootProject.roomVersion"
androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-common-java8:$rootProject.lifecycleVersion"
// Kotlin components
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"
// UI
implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
implementation "com.google.android.material:material:$rootProject.materialVersion"
// Testing
testImplementation "junit:junit:$rootProject.junitVersion"
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"
androidTestImplementation ("androidx.test.espresso:espresso-core:$rootProject.espressoVersion", {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestImplementation "androidx.test.ext:junit:$rootProject.androidxJunitVersion"
}
If you using kotlin version (1.7.0) shoud work with room latest alpha version (2.5.0-alpha02)
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.0"
implementation "androidx.room:room-runtime:2.5.0-alpha02"
implementation "androidx.room:room-ktx:2.5.0-alpha02"
kapt "androidx.room:room-compiler:2.5.0-alpha02"
If you want using room in stable version (2.4.2) should work with kotlin version (1.6.20)
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.20"
implementation "androidx.room:room-runtime:2.4.2"
implementation "androidx.room:room-ktx:2.4.2"
kapt "androidx.room:room-compiler:2.4.2"
I have tried both and they work. this is the reference: issue tracker
Update the Room version to 2.4.0-rc01.
In my case it solved the problem, and it works with Kotlin 1.6.0.
For me, kotlin-gradle-plugin 1.6.0 didn't work:
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0"
but 1.5.31 worked:
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31'
Kotlin 1.6.0 with Room 2.4.0-rc01 worked too.
Thanks Stefano.
I can't access rememberCoroutineScope() and i updated android studio to last version , so how i can solve this problem,
Cannot access class 'kotlinx.coroutines.CoroutineScope'. Check your module classpath for missing or conflicting dependencies
In main activity I have
import androidx.compose.runtime.rememberCoroutineScope
but still not working.
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.example.navigationdrawer_navigationmenu_jetpackcompose"
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
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'
useIR = true
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerVersion '1.5.10'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
implementation 'androidx.activity:activity-compose:1.4.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation("androidx.navigation:navigation-compose:2.4.0-beta02")
}
buildscript {
ext {
compose_version = '1.0.0'
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.3"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.10"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
package com.example.navigationdrawer_navigationmenu_jetpackcompose
import android.os.Bundle
import com.example.navigationdrawer_navigationmenu_jetpackcompose.ui.theme.NavigationDrawerNavigationMenuJetpackComposeTheme
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.navigation.compose.rememberNavController
import androidx.compose.runtime.rememberCoroutineScope
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
NavigationDrawerNavigationMenuJetpackComposeTheme {
NavigationDrawer()
}
}
}
}
#Composable
fun NavigationDrawer() {
val context = LocalContext.current
val navController = rememberNavController()
val scope = rememberCoroutineScope() // error here :
}
i solved this problem jetback compose after update from beta , There are no kotlinx.coroutines so if you want kotlinx.coroutines and use :
import androidx.compose.runtime.rememberCoroutineScope
and
rememberCoroutineScope()
just Add kotlinx-coroutines-android module as a dependency when using kotlinx.coroutines on Android:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0")
I am implementing Room database for storing contacts for the jetpack compose project on Android Studio Bumblebee 2021.1.1 Canary 10. But I am getting an error as shown below
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tana.contactapp, PID: 8843
java.lang.RuntimeException: cannot find implementation for com.tana.contactapp.data.ContactAppDatabase. ContactAppDatabase_Impl does not exist
Here is my app-level Gradle file
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 30
defaultConfig {
applicationId "com.tana.contactapp"
minSdk 22
targetSdk 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
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'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.6.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation "androidx.compose.material:material-icons-core:$compose_version"
implementation "androidx.compose.material:material-icons-extended:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.0'
implementation 'androidx.room:room-ktx:2.3.0'
implementation 'androidx.compose.runtime:runtime-livedata:1.0.2'
implementation 'androidx.navigation:navigation-compose:2.4.0-alpha06'
annotationProcessor 'androidx.room:room-compiler:2.3.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
}
Here is the project-level Gradle file
task clean(type: Delete) {
delete rootProject.buildDir
}
buildscript {
ext {
compose_version = '1.0.2'
}
}
Here is settings.gradle file
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
plugins {
id 'com.android.application' version '7.1.0-alpha10'
id 'com.android.library' version '7.1.0-alpha10'
id 'org.jetbrains.kotlin.android' version '1.5.21'
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "ContactApp"
include ':app'
Here is my Entity File
package com.tana.contactapp.data
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
#Entity(tableName = "contacts")
data class Contact(
#PrimaryKey(autoGenerate = true) val id: Long = 0,
val name: String,
val number: String,
#Ignore val imageDp: ImageVector = Icons.Default.Person
)
Here is my DAO File
package com.tana.contactapp.data
import androidx.lifecycle.LiveData
import androidx.room.*
#Dao
interface ContactAppDao {
#Query("SELECT * FROM contacts")
fun getContacts(): LiveData<List<Contact>>
#Insert
suspend fun addContact(contact: Contact)
#Update
suspend fun updateContact(contact: Contact)
#Delete
suspend fun deleteContact(contact: Contact)
#Query("DELETE FROM contacts")
suspend fun deleteContacts()
}
Here is my Database File
package com.tana.contactapp.data
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
#Database(entities = [Contact::class], version = 1, exportSchema = false)
abstract class ContactAppDatabase : RoomDatabase() {
abstract fun contactsDao(): ContactAppDao
companion object {
private var INSTANCE: ContactAppDatabase? = null
fun getDatabase(context: Context): ContactAppDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
ContactAppDatabase::class.java,
"contact_app_database"
).build()
}
return instance
}
}
}
}
I have tried a lot of solutions from the previous questions similar to this but none seems to work for my case
You need to remove
annotationProcessor 'androidx.room:room-compiler:2.3.0'
and add room compiler using kapt
kapt androidx.room:room-compiler:$room_version
https://developer.android.com/jetpack/androidx/releases/room#kts
and kapt plugin, on top of your root gradle file
apply plugin: "kotlin-kapt"
I solved this by adding id 'org.jetbrains.kotlin.kapt' version '1.5.21' in settings.gradle file plugins section, and then adding id 'org.jetbrains.kotlin.kapt' in app gradle file instead of 'kotlin-kapt'
as I am newbie I couldnt upload images rather I wrote the code required
I was trying to implement firebase sign in activity but on running the app
i am getting app is not responding and app does not opens
My app on running keeps showing "app keeps stopping"
//here is the sign in activity
package com.example.dummymedia
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.ProgressBar
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.tasks.Task
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
#Suppress("DEPRECATION")
class SignInActivity : AppCompatActivity() {
private val RC_SIGN_IN: Int = 123
private lateinit var googleSignInClient:GoogleSignInClient
private lateinit var auth :FirebaseAuth
private val TAG ="SignInActivity Tag"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sign_in)
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleSignInClient = GoogleSignIn.getClient(this, gso)
auth = Firebase.auth
findViewById<Button>(R.id.SignInButton).setOnClickListener {
signIn()
}
}
private fun signIn(){
val signInIntent = googleSignInClient.signInIntent
startActivityForResult(signInIntent, RC_SIGN_IN)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_SIGN_IN) {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
handlesignInresult(task)
}
}
private fun handlesignInresult(completedTask: Task<GoogleSignInAccount>?) {
try {
val account =
completedTask?.getResult(ApiException::class.java)!!
Log.d(TAG,"firebaseAuthWithGoogle:"+account.id)
firebaseAuthWithGoogle(account.idToken!!)
}catch (e:ApiException){
Log.w(TAG,"signInResult:failed code ="+e.statusCode)
}
}
private fun firebaseAuthWithGoogle(idToken: String) {
val credential =GoogleAuthProvider.getCredential(idToken,null)
findViewById<Button>(R.id.SignInButton).visibility = View.GONE
findViewById<ProgressBar>(R.id.progress_Bar).visibility = View.GONE
GlobalScope.launch(Dispatchers.IO) {
val auth = auth.signInWithCredential(credential).await()
val firebaseUser = auth.user
withContext(Dispatchers.Main){
updateUI(firebaseUser)
}
}
}
private fun updateUI(firebaseUser: FirebaseUser?) {
if (firebaseUser!=null){
val mainActivityIntent =Intent(this,MainActivity::class.java)
startActivity(mainActivityIntent)
finish()
}else{
findViewById<Button>(R.id.SignInButton).visibility = View.VISIBLE
findViewById<ProgressBar>(R.id.progress_Bar).visibility = View.GONE
}
}
}
// Androidmanifest.xml
here I moved the launcher to the sign in activity
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dummymedia">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.DummyMedia">
<activity android:name=".SignInActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"/>
</application>
</manifest>
//project level gradle
Specified the versions of dependencies used in app level gradle
buildscript {
ext.kotlin_version = "1.5.10"
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.8'
}
}
allprojects {
repositories {
google()
mavenCentral()
// Warning: this repository is going to shut down soon
}
}
task clean(type: Delete) {
delete rootProject.buildDir
} ext
{
activityVersion = '1.2.3'
appCompatVersion = '1.3.0'
constraintLayoutVersion = '2.0.4'
coreTestingVersion = '2.1.0'
coroutines = '1.4.1'
lifecycleVersion = '2.3.1'
materialVersion = '1.3.0'
roomVersion = '2.3.0'
junitVersion = '4.13.2'
espressoVersion = '3.1.0'
androidxJunitVersion = '1.1.2'
}
//app level gradle
defined the dependencies here for firebase etc
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'com.google.gms.google-services'
id 'kotlin-kapt'
}
android
{
compileSdkVersion 30
defaultConfig {
applicationId "com.example.dummymedia"
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName "1.0"
multiDexEnabled true
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 "androidx.appcompat:appcompat:$rootProject.appCompatVersion"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"
// UI
implementation
"androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
implementation "com.google.android.material:material:$rootProject.materialVersion"
/* coroutines support for firebase operations */
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.1.1'
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:28.1.0')
implementation 'com.google.firebase:firebase-firestore'
implementation 'com.google.firebase:firebase-auth-ktx'
implementation 'com.firebaseui:firebase-ui-firestore:7.1.1'
implementation 'com.google.android.gms:play-services-auth:19.0.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
implementation 'com.google.firebase:firebase-firestore:23.0.1'
// Testing
testImplementation "junit:junit:$rootProject.junitVersion"
androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"
androidTestImplementation ("androidx.test.espresso:espresso-core:$rootProject.espressoVersion", {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestImplementation "androidx.test.ext:junit:$rootProject.androidxJunitVersion"
}