├── .gitignore ├── .idea ├── .gitignore ├── appInsightsSettings.xml ├── compiler.xml ├── deploymentTargetDropDown.xml ├── deploymentTargetSelector.xml ├── gradle.xml ├── kotlinc.xml ├── material_theme_project_new.xml ├── migrations.xml ├── misc.xml ├── other.xml ├── render.experimental.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle.kts ├── google-services.json ├── proguard-rules.pro ├── release │ └── app-release.aab └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── valenpatel │ │ └── notes │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── valenpatel │ │ │ └── notes │ │ │ ├── adapter │ │ │ ├── ColorAdapter.kt │ │ │ └── MyRecyclerAdapter.kt │ │ │ ├── authenticaton │ │ │ ├── Add_Password.kt │ │ │ ├── Biometric_Authentication_Activity.kt │ │ │ ├── Code_Verification_Activity.kt │ │ │ ├── Login_Activity.kt │ │ │ └── PasswordAuthenticationActivity.kt │ │ │ ├── fcm │ │ │ └── MyFirebaseMessagingService.kt │ │ │ ├── model │ │ │ ├── ColorItem.kt │ │ │ ├── DataClass.kt │ │ │ └── UserInfo.kt │ │ │ ├── preferences │ │ │ └── SharedPreference.kt │ │ │ └── views │ │ │ ├── activity │ │ │ ├── Accounts_Activity.kt │ │ │ ├── Notifications_Activity.kt │ │ │ ├── Show_Image_Activity.kt │ │ │ └── SplashScreenActivity.kt │ │ │ ├── crud │ │ │ ├── Create_Update_Data_Activity.kt │ │ │ └── Main_Retrieve_All_Notes_Activity.kt │ │ │ ├── fragments │ │ │ ├── AddResource_Fragment.kt │ │ │ ├── Color_Fragment.kt │ │ │ ├── More_Fragment.kt │ │ │ └── UserInfo_Fragment.kt │ │ │ └── notUsing │ │ │ ├── Add_Notes_Activity.kt │ │ │ ├── Retriving_All_Data_Related_To_Notes_Activity.kt │ │ │ ├── Update_Data_Activity.kt │ │ │ └── UserName_Activity.kt │ └── res │ │ ├── drawable │ │ ├── backward.xml │ │ ├── baseline_account_circle_24.xml │ │ ├── baseline_add_24.xml │ │ ├── baseline_add_box_24.xml │ │ ├── baseline_all_inbox_24.xml │ │ ├── baseline_arrow_back_24.xml │ │ ├── baseline_calendar_month_24.xml │ │ ├── baseline_calendar_month_24_black.xml │ │ ├── baseline_call_24.xml │ │ ├── baseline_check_24.xml │ │ ├── baseline_close_24.xml │ │ ├── baseline_close_24_white.xml │ │ ├── baseline_color_lens_24.xml │ │ ├── baseline_content_copy_24.xml │ │ ├── baseline_dashboard_24.xml │ │ ├── baseline_delete_24.xml │ │ ├── baseline_delete_24_white.xml │ │ ├── baseline_feedback_24.xml │ │ ├── baseline_grid_view_24.xml │ │ ├── baseline_help_24.xml │ │ ├── baseline_image_24.xml │ │ ├── baseline_image_24_black.xml │ │ ├── baseline_keyboard_arrow_right_24.xml │ │ ├── baseline_menu_24.xml │ │ ├── baseline_mode_edit_outline_24.xml │ │ ├── baseline_more_vert_24.xml │ │ ├── baseline_notifications_24.xml │ │ ├── baseline_password_24.xml │ │ ├── baseline_person_24.xml │ │ ├── baseline_phone_android_24.xml │ │ ├── baseline_photo_camera_24.xml │ │ ├── baseline_power_settings_new_24.xml │ │ ├── baseline_privacy_tip_24.xml │ │ ├── baseline_save_24.xml │ │ ├── baseline_settings_24.xml │ │ ├── baseline_share_24.xml │ │ ├── baseline_share_24_white.xml │ │ ├── baseline_text_snippet_24.xml │ │ ├── baseline_view_stream_24.xml │ │ ├── border_radius_background.xml │ │ ├── border_radius_background_content.xml │ │ ├── border_radius_background_content_main.xml │ │ ├── border_radius_background_content_round.xml │ │ ├── border_radius_background_white.xml │ │ ├── button_bg_theme.xml │ │ ├── circle_background.xml │ │ ├── circular_ring.xml │ │ ├── color_item_border.xml │ │ ├── color_item_selected_border.xml │ │ ├── edit.xml │ │ ├── editt.xml │ │ ├── edittext_border.xml │ │ ├── grid.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── image_background_radius.xml │ │ ├── image_round_bg.xml │ │ ├── search.xml │ │ ├── search_bg.xml │ │ ├── search_black.xml │ │ ├── share.xml │ │ ├── top_radius_bg.xml │ │ ├── top_radius_bg_color_fragment.xml │ │ ├── view_bg.xml │ │ ├── view_main_top_bg.xml │ │ ├── viewrow.xml │ │ └── white_bg_alertdialog_radiud.xml │ │ ├── font │ │ ├── lato.xml │ │ ├── lato_bold.xml │ │ ├── lato_thin.xml │ │ └── nunito_semibold.xml │ │ ├── layout │ │ ├── activity_accounts.xml │ │ ├── activity_add_password.xml │ │ ├── activity_biometric_authentication.xml │ │ ├── activity_code_verification.xml │ │ ├── activity_login.xml │ │ ├── activity_main.xml │ │ ├── activity_notifications.xml │ │ ├── activity_password_authentication.xml │ │ ├── activity_retriving_all_data_related_to_notes.xml │ │ ├── activity_show_image.xml │ │ ├── activity_splash_screen.xml │ │ ├── activity_update_data.xml │ │ ├── activity_user_name.xml │ │ ├── alertdialog_account_deletation_code.xml │ │ ├── all_notes_activity.xml │ │ ├── code_verification_dialog.xml │ │ ├── create_update_data_activity.xml │ │ ├── fragment_add_resource.xml │ │ ├── fragment_color.xml │ │ ├── fragment_more.xml │ │ ├── fragment_user_info.xml │ │ ├── main_nav_layout.xml │ │ ├── note_content_recycler.xml │ │ └── select_color_from_list_layout.xml │ │ ├── menu │ │ └── bottom_nav_menu.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ ├── ic_launcher_monochrome.png │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ ├── ic_launcher_monochrome.png │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ ├── ic_launcher_monochrome.png │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ ├── ic_launcher_monochrome.png │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.png │ │ ├── ic_launcher_foreground.png │ │ ├── ic_launcher_monochrome.png │ │ └── ic_launcher_round.webp │ │ ├── raw │ │ ├── aaanimation.json │ │ ├── adminlottie.json │ │ ├── aimation.json │ │ ├── bbanimation.json │ │ ├── empty.json │ │ ├── emptylottiefile.json │ │ ├── fire.json │ │ ├── heylottie.json │ │ ├── loginlottie.json │ │ ├── nodatafound.json │ │ └── noteslottie.json │ │ ├── values-night │ │ └── themes.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── font_certs.xml │ │ ├── preloaded_fonts.xml │ │ ├── strings.xml │ │ ├── styles.xml │ │ └── themes.xml │ │ └── xml │ │ ├── backup_rules.xml │ │ └── data_extraction_rules.xml │ └── test │ └── java │ └── com │ └── valenpatel │ └── notes │ └── ExampleUnitTest.kt ├── build.gradle.kts ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/appInsightsSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 39 | 40 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/deploymentTargetSelector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16 | 17 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/material_theme_project_new.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/migrations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/render.experimental.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Notes App in kotlin

2 | # Notes App 3 | 4 | A simple and intuitive Notes App built using Android (Kotlin) that allows users to create, update, delete, and organize their personal notes. The app provides a seamless user experience with Firebase integration for authentication and real-time data storage. 5 | 6 | ## Features 7 | 8 | - **Create Notes:** Add new notes with a title, content, and optional image. 9 | - **Update Notes:** Edit existing notes with changes reflected in real-time. 10 | - **Delete Notes:** Remove notes individually or bulk delete notes. 11 | - **Color-Coded Notes:** Customize the background color of notes for easy organization. 12 | - **Search Functionality:** Easily search for notes based on titles or content. 13 | - **Phone Authentication:** Secure user login and registration using Firebase phone authentication. 14 | - **Data Sync:** Notes are synced across devices using Firebase Realtime Database. 15 | - **Share Notes 16 | 17 | ## Tech Stack 18 | 19 | - **Language:** Kotlin 20 | - **Database:** Firebase Realtime Database 21 | - **Authentication:** Firebase Phone Authentication 22 | - **UI Components:** Material Design (RecyclerView, Bottom Sheets, TextInputLayout) 23 | - **Libraries:** 24 | - Firebase Realtime Database 25 | - Firebase Authentication 26 | - Glide (for image loading) 27 | 28 | 29 | 30 | https://github.com/user-attachments/assets/17bc4997-0dca-4fdb-9757-29d7054348f6 31 | 32 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.application") 3 | id("org.jetbrains.kotlin.android") 4 | id("com.google.gms.google-services") 5 | } 6 | 7 | android { 8 | namespace = "com.valenpatel.notes" 9 | compileSdk = 34 10 | 11 | defaultConfig { 12 | applicationId = "com.valenpatel.notes" 13 | minSdk = 24 14 | targetSdk = 34 15 | versionCode = 5 16 | versionName = "1.5.2" 17 | 18 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 19 | } 20 | 21 | buildTypes { 22 | release { 23 | isMinifyEnabled = false 24 | proguardFiles( 25 | getDefaultProguardFile("proguard-android-optimize.txt"), 26 | "proguard-rules.pro" 27 | ) 28 | } 29 | } 30 | compileOptions { 31 | sourceCompatibility = JavaVersion.VERSION_1_8 32 | targetCompatibility = JavaVersion.VERSION_1_8 33 | } 34 | kotlinOptions { 35 | jvmTarget = "1.8" 36 | } 37 | buildFeatures { 38 | viewBinding = true 39 | } 40 | } 41 | 42 | dependencies { 43 | 44 | implementation("androidx.core:core-ktx:1.13.1") 45 | implementation("androidx.appcompat:appcompat:1.7.0") 46 | implementation("com.google.android.material:material:1.12.0") 47 | implementation("androidx.constraintlayout:constraintlayout:2.1.4") 48 | implementation("com.google.firebase:firebase-storage:21.0.0") 49 | implementation("com.google.firebase:firebase-messaging:24.0.0") 50 | implementation("androidx.activity:activity-ktx:1.9.1") 51 | implementation("androidx.recyclerview:recyclerview:1.3.2") 52 | implementation("androidx.activity:activity:1.9.1") 53 | testImplementation("junit:junit:4.13.2") 54 | androidTestImplementation("androidx.test.ext:junit:1.2.1") 55 | androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") 56 | 57 | //Firebase Dependency 58 | implementation(platform("com.google.firebase:firebase-bom:33.1.2")) 59 | implementation("com.google.firebase:firebase-analytics") 60 | implementation("com.google.firebase:firebase-auth-ktx") 61 | implementation("com.google.firebase:firebase-database") 62 | //FCM 63 | implementation("com.google.firebase:firebase-messaging:24.0.0") 64 | 65 | //LottieFiles 66 | implementation("com.airbnb.android:lottie:6.0.1") 67 | 68 | //COUNTRY CODE PICKER 69 | implementation("com.hbb20:ccp:2.5.0") 70 | 71 | // //PIN VIEW 72 | implementation("io.github.chaosleung:pinview:1.4.4") 73 | 74 | //GLide Dependency 75 | implementation("com.github.bumptech.glide:glide:4.16.0") 76 | //ImageZommInOut 77 | implementation("com.github.MikeOrtiz:TouchImageView:1.4.1") // last SupportLib version 78 | 79 | //LOTTIEFILES 80 | implementation("com.airbnb.android:lottie:6.0.1") 81 | 82 | implementation("androidx.recyclerview:recyclerview:1.3.2") 83 | 84 | implementation("com.google.android.material:material:1.12.0") 85 | 86 | 87 | implementation("androidx.coordinatorlayout:coordinatorlayout:1.2.0") 88 | 89 | 90 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1") 91 | implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4") 92 | implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.8.4") 93 | 94 | } -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "438399053876", 4 | "firebase_url": "https://notes-22392-default-rtdb.firebaseio.com", 5 | "project_id": "notes-22392", 6 | "storage_bucket": "notes-22392.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:438399053876:android:0d496afa6ed0501a81da61", 12 | "android_client_info": { 13 | "package_name": "com.valenpatel.notes" 14 | } 15 | }, 16 | "oauth_client": [], 17 | "api_key": [ 18 | { 19 | "current_key": "AIzaSyDvnaz7HzHECIF3iRxwqt7iEkNm-n-2PiM" 20 | } 21 | ], 22 | "services": { 23 | "appinvite_service": { 24 | "other_platform_oauth_client": [] 25 | } 26 | } 27 | } 28 | ], 29 | "configuration_version": "1" 30 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/release/app-release.aab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laidbackvalen/Biometric_FirebasePhoneAuthentication-Notes-App/8cd771460f4eb41e550e28a82eb17c14478091b3/app/release/app-release.aab -------------------------------------------------------------------------------- /app/src/androidTest/java/com/valenpatel/notes/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.valenpatel.notes 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.example.notes", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 29 | 32 | 35 | 38 | 41 | 45 | 48 | 52 | 55 | 58 | 61 | 64 | 67 | 70 | 73 | 76 | 79 | 82 | 85 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 97 | 98 | 99 | 100 | 101 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /app/src/main/java/com/valenpatel/notes/adapter/ColorAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.valenpatel.notes.adapter 2 | 3 | 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.cardview.widget.CardView 8 | import androidx.recyclerview.widget.RecyclerView 9 | import com.valenpatel.notes.R 10 | import com.valenpatel.notes.model.ColorItem 11 | import com.valenpatel.notes.views.fragments.Color_Fragment 12 | 13 | class ColorAdapter( 14 | private val colors: List, 15 | private val listener: Color_Fragment.OnColorSelectedListener 16 | ) : RecyclerView.Adapter() { 17 | 18 | inner class ColorViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 19 | private val colorView: CardView = itemView.findViewById(R.id.colorListCard) 20 | 21 | fun bind(colorItem: ColorItem) { 22 | colorView.setCardBackgroundColor(colorItem.color) 23 | itemView.setOnClickListener { 24 | listener.onColorSelected(colorItem.color) 25 | } 26 | } 27 | } 28 | 29 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ColorViewHolder { 30 | val view = LayoutInflater.from(parent.context).inflate(R.layout.select_color_from_list_layout, parent, false) 31 | return ColorViewHolder(view) 32 | } 33 | 34 | override fun onBindViewHolder(holder: ColorViewHolder, position: Int) { 35 | holder.bind(colors[position]) 36 | } 37 | 38 | override fun getItemCount(): Int = colors.size 39 | } 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/valenpatel/notes/authenticaton/Add_Password.kt: -------------------------------------------------------------------------------- 1 | package com.valenpatel.notes.authenticaton 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import androidx.activity.enableEdgeToEdge 6 | import androidx.appcompat.app.AppCompatActivity 7 | import androidx.core.view.ViewCompat 8 | import androidx.core.view.WindowInsetsCompat 9 | import com.valenpatel.notes.R 10 | import com.valenpatel.notes.databinding.ActivityAddPasswordBinding 11 | import com.valenpatel.paisefy.preferences.SharedPreference 12 | 13 | class Add_Password : AppCompatActivity() { 14 | private lateinit var binding: ActivityAddPasswordBinding 15 | override fun onCreate(savedInstanceState: Bundle?) { 16 | super.onCreate(savedInstanceState) 17 | enableEdgeToEdge() 18 | binding = ActivityAddPasswordBinding.inflate(layoutInflater) 19 | setContentView(binding.root) 20 | ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> 21 | val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) 22 | v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) 23 | insets 24 | } 25 | 26 | val preference = SharedPreference(context = applicationContext) 27 | if (preference.getPassword() != null) { 28 | startActivity(Intent(this, PasswordAuthenticationActivity::class.java)) 29 | } 30 | 31 | binding.submitButton.setOnClickListener { 32 | val pass = binding.passwordAdd.text 33 | if (pass.toString().isEmpty()) { 34 | binding.passwordAdd.error = "Enter Password" 35 | return@setOnClickListener 36 | }else { 37 | val preference = 38 | SharedPreference(context = applicationContext).setPassword(pass.toString()) 39 | startActivity(Intent(this, PasswordAuthenticationActivity::class.java)) 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/valenpatel/notes/authenticaton/Biometric_Authentication_Activity.kt: -------------------------------------------------------------------------------- 1 | package com.valenpatel.notes.authenticaton 2 | 3 | import android.app.KeyguardManager 4 | import android.content.Context 5 | import android.content.DialogInterface 6 | import android.content.Intent 7 | import android.content.SharedPreferences 8 | import android.content.pm.PackageManager 9 | import android.hardware.biometrics.BiometricPrompt 10 | import android.os.Build 11 | import androidx.appcompat.app.AppCompatActivity 12 | import android.os.Bundle 13 | import android.os.CancellationSignal 14 | import android.widget.TextView 15 | import android.widget.Toast 16 | import androidx.annotation.RequiresApi 17 | import androidx.core.app.ActivityCompat 18 | import com.valenpatel.notes.R 19 | import com.valenpatel.notes.views.crud.Main_Retrieve_All_Notes_Activity 20 | import com.google.firebase.auth.FirebaseAuth 21 | 22 | class Biometric_Authentication_Activity : AppCompatActivity() { 23 | 24 | private var cancellationSignal: CancellationSignal? = null 25 | private val sharedPreferences: SharedPreferences by lazy { 26 | getSharedPreferences("MyPrefs", Context.MODE_PRIVATE) 27 | } 28 | 29 | private val authenticationCallback: BiometricPrompt.AuthenticationCallback 30 | get() = @RequiresApi(Build.VERSION_CODES.P) 31 | object : BiometricPrompt.AuthenticationCallback() { 32 | override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) { 33 | super.onAuthenticationError(errorCode, errString) 34 | notifyUser("Authentication Error: $errString") 35 | } 36 | 37 | override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult?) { 38 | super.onAuthenticationSucceeded(result) 39 | if (FirebaseAuth.getInstance().currentUser != null) { 40 | startActivity(Intent(baseContext, Main_Retrieve_All_Notes_Activity::class.java)) 41 | notifyUser("Authentication Succeeded") 42 | finish() 43 | } else { 44 | startActivity(Intent(baseContext, Login_Activity::class.java)) 45 | } 46 | } 47 | } 48 | 49 | @RequiresApi(Build.VERSION_CODES.P) 50 | override fun onCreate(savedInstanceState: Bundle?) { 51 | super.onCreate(savedInstanceState) 52 | setContentView(R.layout.activity_biometric_authentication) 53 | 54 | findViewById(R.id.loginWithPasswordTextView).setOnClickListener { 55 | handlePasswordLogin() 56 | } 57 | 58 | checkBiometricSupport() 59 | 60 | val biometricPrompt = BiometricPrompt.Builder(this) 61 | .setTitle("Login with Biometric") 62 | .setSubtitle("") 63 | .setDescription("") 64 | .setNegativeButton( 65 | "Cancel", 66 | this.mainExecutor, 67 | DialogInterface.OnClickListener { dialog, which -> 68 | notifyUser("Authentication Cancelled") 69 | handlePasswordLogin() 70 | }).build() 71 | 72 | biometricPrompt.authenticate(getCancellationSignal(), mainExecutor, authenticationCallback) 73 | } 74 | 75 | private fun getCancellationSignal(): CancellationSignal { 76 | cancellationSignal = CancellationSignal() 77 | cancellationSignal?.setOnCancelListener { 78 | notifyUser("Authentication was Cancelled by the user") 79 | handlePasswordLogin() 80 | } 81 | return cancellationSignal as CancellationSignal 82 | } 83 | 84 | @RequiresApi(Build.VERSION_CODES.M) 85 | private fun checkBiometricSupport(): Boolean { 86 | val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager 87 | if (!keyguardManager.isDeviceSecure) { 88 | notifyUser("Fingerprint authentication has not been enabled in settings") 89 | return false 90 | } 91 | if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.USE_BIOMETRIC) != PackageManager.PERMISSION_GRANTED) { 92 | notifyUser("Fingerprint Authentication Permission is not enabled") 93 | return false 94 | } 95 | return if (packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) { 96 | true 97 | } else { 98 | notifyUser("Fingerprint feature is not supported") 99 | false 100 | } 101 | } 102 | 103 | private fun notifyUser(message: String) { 104 | Toast.makeText(this, message, Toast.LENGTH_SHORT).show() 105 | } 106 | 107 | private fun handlePasswordLogin() { 108 | val password = sharedPreferences.getString("password_key", null) 109 | if (password != null) { 110 | startActivity(Intent(this, PasswordAuthenticationActivity::class.java)) 111 | } else { 112 | startActivity(Intent(this, Add_Password::class.java)) 113 | } 114 | finish() 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /app/src/main/java/com/valenpatel/notes/authenticaton/Code_Verification_Activity.kt: -------------------------------------------------------------------------------- 1 | package com.valenpatel.notes.authenticaton 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.widget.Button 6 | import android.widget.TextView 7 | import android.widget.Toast 8 | import androidx.appcompat.app.AppCompatActivity 9 | import com.chaos.view.PinView 10 | import com.valenpatel.notes.R 11 | import com.valenpatel.notes.views.crud.Main_Retrieve_All_Notes_Activity 12 | import com.google.firebase.auth.FirebaseAuth 13 | import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException 14 | import com.google.firebase.auth.PhoneAuthCredential 15 | import com.google.firebase.auth.PhoneAuthProvider 16 | 17 | class Code_Verification_Activity : AppCompatActivity() { 18 | 19 | // get reference of the firebase auth 20 | lateinit var auth: FirebaseAuth 21 | var timeOutSeconds = 60L 22 | override fun onCreate(savedInstanceState: Bundle?) { 23 | super.onCreate(savedInstanceState) 24 | setContentView(R.layout.activity_code_verification) 25 | 26 | window.statusBarColor = getColor(R.color.black) 27 | //LINKING WITH XML 28 | //Getting value of phone number using intent coming from GenerateOTPActivity 29 | 30 | auth=FirebaseAuth.getInstance() 31 | // startResendTimer() 32 | // get storedVerificationId from the intent 33 | val storedVerificationId= intent.getStringExtra("storedVerificationId") 34 | val number= intent.getStringExtra("number") 35 | 36 | findViewById(R.id.numberRetrieved).setText(number) 37 | 38 | // fill otp and call the on click on button 39 | findViewById