diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index b268ef3..41aa2e6 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -4,6 +4,14 @@
+
+
+
+
+
+
+
+
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9fb7385..1f5c261 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -43,6 +43,7 @@ dependencies {
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.navigation.fragment.ktx)
implementation(libs.androidx.navigation.ui.ktx)
+ implementation(libs.firebase.crashlytics.buildtools)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 243c2f8..2ac5f2d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,6 +3,11 @@
xmlns:tools="http://schemas.android.com/tools">
+
+
+
+
+
+
+
+
@@ -23,10 +38,8 @@
android:theme="@style/Theme.BarcodeScannerForEmployees">
-
-
\ No newline at end of file
diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/AbstractProductView.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/AbstractProductView.kt
index db8f058..4961472 100644
--- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/AbstractProductView.kt
+++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/AbstractProductView.kt
@@ -1,9 +1,14 @@
package org.foxarmy.barcodescannerforemployees
import android.content.Context
+import android.graphics.Bitmap
+import android.graphics.BitmapFactory
+import android.util.Log
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
+import android.widget.Toast
+import java.io.File
/**
* TODO: document your custom view class.
@@ -16,10 +21,21 @@ class AbstractProductView: LinearLayout {
constructor(context: Context, productImageFile: String, productName: String, netWeight: Double, category: Int) : super(context) {
-// this.layerType =
-// setLayerType()
this.orientation = LinearLayout.VERTICAL
-// productImage.set
+
+ val imageFile = File(File(context.filesDir, "pictures"), productImageFile)
+ val image: ByteArray = imageFile.readBytes()
+
+ if (image.isEmpty()) {
+ Toast.makeText(context, image.size.toString(), Toast.LENGTH_LONG).show()
+ }
+ try {
+ Log.d("org.foxarmy.barcodescannerforemployees", "[ХУЙ]" + imageFile.absolutePath)
+ val bitmap: Bitmap = BitmapFactory.decodeFile(imageFile.absolutePath)
+ } catch (e:Exception) {
+ Log.d("org.foxarmy.barcodescannerforemployees", "[ХУЙ] " + e)
+ }
+// productImage.setImageBitmap(bitmap)
productNameField.setText(productName)
netWeightField.setText(netWeight.toString())
diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/AddProductFragment.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/AddProductFragment.kt
index cec75ec..b91c33e 100644
--- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/AddProductFragment.kt
+++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/AddProductFragment.kt
@@ -1,24 +1,20 @@
package org.foxarmy.barcodescannerforemployees
//import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
-import android.app.Activity
-import android.content.Intent
-import android.graphics.Bitmap
+import android.os.Build
import android.os.Bundle
-import android.provider.MediaStore
+import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
+import androidx.annotation.RequiresApi
+import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
-import com.google.mlkit.vision.barcode.common.Barcode
-import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
-import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
+import com.google.firebase.components.BuildConfig
import org.foxarmy.barcodescannerforemployees.databinding.AddProductFragmentBinding
import java.io.File
-import java.io.FileOutputStream
-import java.nio.ByteBuffer
import java.security.MessageDigest
@@ -29,74 +25,126 @@ fun String.md5(): String {
return digest.toHexString()
}
-/**
- * A simple [Fragment] subclass as the default destination in the navigation.
- */
-
class AddProductFragment : Fragment() {
private var _binding: AddProductFragmentBinding? = null
-
- // This property is only valid between onCreateView and
- // onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
-
_binding = AddProductFragmentBinding.inflate(inflater, container, false)
return binding.root
-
}
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- super.onActivityResult(requestCode, resultCode, data)
- when (requestCode) {
- 200 -> {
- if (resultCode == Activity.RESULT_OK && data != null) {
- val picture = (data.extras?.get("data") as Bitmap)
- binding.imageView.setImageBitmap(picture)
- val picturesPath = context?.filesDir
- val dir = File(picturesPath, "pictures")
- dir.mkdirs()
- val filename = picture.toString().md5()
- val file = File(dir, filename)
- FileOutputStream(file).use {
- val b = ByteBuffer.allocate(picture.byteCount)
- picture.copyPixelsToBuffer(b)
- it.write(b.array())
- }
- }
+ val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean ->
+ if (success) {
+ Log.i("QWERTYUIOP", "Done")
+ } else {
+ Log.e("QWERTYUIOP", "Xuinya")
+ }
+ }
+
+ fun getPicture () {
+ val imageFile = File(requireContext().filesDir, "image.png")
+ val imageUri = FileProvider.getUriForFile(requireActivity(), BuildConfig.APPLICATION_ID + "." + requireActivity().localClassName + ".provider", imageFile)
+ takePicture.launch(imageUri)
+ }
+
+ val requestPermissionLauncher =
+ registerForActivityResult(
+ ActivityResultContracts.RequestPermission()
+ ) { isGranted: Boolean ->
+ if (isGranted) {
+ Toast.makeText(requireContext(), "Granted", Toast.LENGTH_LONG).show()
+// getFuckingPicture()
+ } else {
+ Toast.makeText(requireContext(), "I need permission in order to take a picture", Toast.LENGTH_LONG).show()
}
}
- }
-
- val requestPermissionLauncher = registerForActivityResult(
- ActivityResultContracts.RequestPermission()
- ) { isGranted ->
- if (isGranted) {
- val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
- startActivityForResult(cameraIntent, 200)
- } else {
- Toast.makeText(
- requireContext(),
- "I need permission for camera in order to take a picture!",
- Toast.LENGTH_LONG
- ).show()
- }
- }
+ @RequiresApi(Build.VERSION_CODES.R)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- binding.saveButton.setOnClickListener {
+ binding.takePictureButton.setOnClickListener {
+// requestPermissionLauncher.launch(android.Manifest.permission.CAMERA)
+ try {
+ getPicture()
+ } catch (e:Exception) {
+ Log.e("QWERTYUIOP", e.message.toString())
+ }
+
+// try {
+// when{
+// ContextCompat.checkSelfPermission(requireContext(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED -> {
+// getFuckingPicture()
+// } else -> {
+//// requestPermissionLauncher.launch(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
+//// ActivityCompat.requestPermissions(requireActivity(), arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), 200)
+//
+// Log.e("QWERTYUIOP", "хуй соси губой тряси")
+// }
+// }
+//
+// } catch (e:Exception) {
+// Log.e("QWERTYUIOP", e.message.toString())
+// }
+ }
+/*
+ binding.saveButton.setOnClickListener {
+ val productName = binding.productName.text.toString()
+ val netWeight = binding.netWeight.text
+ if (picture == null) {
+ Toast.makeText(context, "Please, make a picture of a product!", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+ if (productName == "") {
+ Toast.makeText(context, "Please, write a name of a product!", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+ if (netWeight.toString() == "" || netWeight.toString().toDoubleOrNull() == null) {
+ Toast.makeText(context, "Please, write a valid net weight of a product!", Toast.LENGTH_SHORT).show()
+ }
+
+ val appFiles = context?.filesDir
+ val picturesDir = File(appFiles, "pictures")
+ picturesDir.mkdirs()
+ val imageFilename = picture.toString().md5() + ".png"
+ val imageFile = File(picturesDir, imageFilename)
+ val stream = FileOutputStream(imageFile)
+ picture!!.compress(Bitmap.CompressFormat.PNG, 100, stream)
+
+ stream.use {
+ val buffer = ByteBuffer.allocate(picture!!.byteCount)
+ picture!!.copyPixelsToBuffer(buffer)
+ it.write(buffer.array())
+ }
+
+ val db = DBStorageController(requireContext()).writableDatabase
+
+ val values = ContentValues().apply {
+ put(ProductContract.ProductEntry.PRODUCT_NAME, productName)
+ put(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, netWeight.toString())
+ put(ProductContract.ProductEntry.IMAGE_FILENAME, imageFilename)
+ }
+
+ db.insert(ProductContract.ProductEntry.TABLE_NAME, null, values)
}
binding.takePictureButton.setOnClickListener {
+
requestPermissionLauncher.launch(android.Manifest.permission.CAMERA)
+
+// val imageUri: Uri = Uri.fromFile(File(File(context?.filesDir, "pictures"), "test.jpg"))
+// val imageUri = Uri.parse("pictures/test.jpg")
+// val picturesDir = File(context?.filesDir, "pictures")
+// picturesDir.mkdirs()
+// val uri = Uri.fromFile(File(picturesDir, "test.jpg"))
+// Log.d("", uri.toString())
+// takePicture.launch(uri)
}
binding.scanButton.setOnClickListener {
@@ -109,6 +157,8 @@ class AddProductFragment : Fragment() {
scanner.startScan()
.addOnSuccessListener { barcode ->
binding.productName.setText(barcode.rawValue)
+
+// val url = URL()
}
.addOnFailureListener { e ->
Toast.makeText(
@@ -118,6 +168,7 @@ class AddProductFragment : Fragment() {
).show()
}
}
+ */
}
override fun onDestroyView() {
diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/DBStorageController.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/DBStorageController.kt
index 45ca8ad..d502d02 100644
--- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/DBStorageController.kt
+++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/DBStorageController.kt
@@ -6,7 +6,7 @@ import android.database.sqlite.SQLiteOpenHelper
import android.provider.BaseColumns
object ProductContract {
- object ProductEntry :BaseColumns {
+ object ProductEntry : BaseColumns {
const val TABLE_NAME = "products"
const val PRODUCT_NAME = "name"
const val PRODUCT_NET_WEIGHT = "net_weight"
@@ -14,17 +14,43 @@ object ProductContract {
}
}
-const val SQL_CREATE_ENTRIES =
+object ShelfContract {
+ object ShelfEntry : BaseColumns {
+ const val TABLE_NAME = "shelf"
+ const val PRODUCT_ID = "product_id"
+ const val EXPIRE_DATE = "expire_date"
+ }
+}
+
+object CategoriesContract {
+ object CategoryEntry : BaseColumns {
+ const val TABLE_NAME = "categories"
+ const val CATEGORY_NAME = "category_name"
+ }
+}
+
+const val SQL_CREATE_PRODUCT_TABLE =
"CREATE TABLE ${ProductContract.ProductEntry.TABLE_NAME} (" +
"${BaseColumns._ID} INTEGER PRIMARY KEY," +
"${ProductContract.ProductEntry.PRODUCT_NAME} TEXT," +
- "${ProductContract.ProductEntry.PRODUCT_NET_WEIGHT} TEXT" +
+ "${ProductContract.ProductEntry.PRODUCT_NET_WEIGHT} REAL," +
"${ProductContract.ProductEntry.IMAGE_FILENAME} TEXT)"
-class DBStorageController(context: Context) : SQLiteOpenHelper (context, DATABASE_NAME, null, DATABASE_VERSION) {
+const val SQL_CREATE_SHELF_TABLE =
+ "CREATE TABLE ${ShelfContract.ShelfEntry.TABLE_NAME} (" +
+ "${ShelfContract.ShelfEntry.PRODUCT_ID} INTEGER," +
+ "${ShelfContract.ShelfEntry.EXPIRE_DATE} DATE)"
+
+const val SQL_CREATE_CATEGORIES_TABLE =
+ "CREATE TABLE ${CategoriesContract.CategoryEntry.TABLE_NAME} (" +
+ "${CategoriesContract.CategoryEntry.CATEGORY_NAME} TEXT)"
+
+class DBStorageController(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
- db.execSQL(SQL_CREATE_ENTRIES)
+ db.execSQL(SQL_CREATE_PRODUCT_TABLE)
+ db.execSQL(SQL_CREATE_SHELF_TABLE)
+ db.execSQL(SQL_CREATE_CATEGORIES_TABLE)
}
override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
@@ -34,6 +60,6 @@ class DBStorageController(context: Context) : SQLiteOpenHelper (context, DATABAS
companion object {
// If you change the database schema, you must increment the database version.
const val DATABASE_VERSION = 1
- const val DATABASE_NAME = "FeedReader.db"
+ const val DATABASE_NAME = "database.db"
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/MainActivity.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/MainActivity.kt
index 529d6dd..ed73c27 100644
--- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/MainActivity.kt
+++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/MainActivity.kt
@@ -19,33 +19,6 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
val dbHelper = DBStorageController(applicationContext)
-// val db = dbHelper.writableDatabase
-//
-// val values = ContentValues().apply {
-// put(ProductContract.ProductEntry.PRODUCT_NAME, "Имя продукта")
-// put(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, "0г")
-// put(ProductContract.ProductEntry.IMAGE_FILENAME, "image.png")
-// }
-//
-// val netRowId = db?.insert(ProductContract.ProductEntry.TABLE_NAME, null, values)
-
-// val db2 = dbHelper.readableDatabase
-//
-// val projection = arrayOf(BaseColumns._ID, ProductContract.ProductEntry.PRODUCT_NAME, ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, ProductContract.ProductEntry.IMAGE_FILENAME)
-//
-// val selection = "${ProductContract.ProductEntry.PRODUCT_NAME} = ?"
-// val selectionArgs = arrayOf("Имя продукта")
-//
-// val cursor = db2.query(
-// ProductContract.ProductEntry.TABLE_NAME,
-// null,
-// selection,
-// selectionArgs,
-// null,
-// null,
-// null
-// )
-
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
@@ -56,24 +29,16 @@ class MainActivity : AppCompatActivity() {
setupActionBarWithNavController(navController, appBarConfiguration)
binding.addProductFab.setOnClickListener { view ->
-// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
-// .setAction("Action", null)
-// .setAnchorView(R.id.add_product_fab).show()
-// Toast.makeText(applicationContext, "Test", Toast.LENGTH_SHORT).show()
navController.navigate(R.id.AddProductFragment)
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
- // Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_settings -> true
else -> super.onOptionsItemSelected(item)
diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/ProductContract.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/ProductContract.kt
deleted file mode 100644
index e840d00..0000000
--- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/ProductContract.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.foxarmy.barcodescannerforemployees
-
-import android.provider.BaseColumns
-
-//object ProductContract {
-// object ProductEntry :BaseColumns {
-// const val TABLE_NAME = "products"
-// const val PRODUCT_NAME = "name"
-// const val PRODUCT_NET_WEIGHT = "net_weight"
-// const val IMAGE_FILENAME = "image_filename"
-// }
-//}
\ No newline at end of file
diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/StorageFragment.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/StorageFragment.kt
index c8f6efd..c4d33d2 100644
--- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/StorageFragment.kt
+++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/StorageFragment.kt
@@ -1,6 +1,7 @@
package org.foxarmy.barcodescannerforemployees
import android.os.Bundle
+import android.provider.BaseColumns
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -29,14 +30,32 @@ class StorageFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- getView()?.findViewById(R.id.storageLayout)?.addView(
- AbstractProductView(
- requireContext(),
- productImageFile = "test1",
- productName = "test2",
- netWeight = 1.1,
- category = 1
- )
- )
+ val db = DBStorageController(requireContext()).readableDatabase
+ val projection = arrayOf(BaseColumns._ID, ProductContract.ProductEntry.PRODUCT_NAME, ProductContract.ProductEntry.PRODUCT_NET_WEIGHT, ProductContract.ProductEntry.IMAGE_FILENAME)
+
+ val selection = "${ProductContract.ProductEntry.PRODUCT_NAME} = ?"
+ val selectionArgs = arrayOf("test")
+
+ val cursor = db.query(ProductContract.ProductEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, null)
+
+ with (cursor) {
+ while(moveToNext()) {
+ val productName = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NAME))
+ val netWeight = getDouble(getColumnIndexOrThrow(ProductContract.ProductEntry.PRODUCT_NET_WEIGHT))
+ val pictureFilename = getString(getColumnIndexOrThrow(ProductContract.ProductEntry.IMAGE_FILENAME))
+
+ getView()?.findViewById(R.id.storageLayout)?.addView(
+ AbstractProductView(
+ requireContext(),
+ productImageFile = pictureFilename,
+ productName = productName,
+ netWeight = netWeight,
+ category = 1
+ )
+ )
+ }
+ }
+
+
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/foxarmy/barcodescannerforemployees/shelfContract.kt b/app/src/main/java/org/foxarmy/barcodescannerforemployees/shelfContract.kt
index dd6c0e7..307afc7 100644
--- a/app/src/main/java/org/foxarmy/barcodescannerforemployees/shelfContract.kt
+++ b/app/src/main/java/org/foxarmy/barcodescannerforemployees/shelfContract.kt
@@ -2,10 +2,3 @@ package org.foxarmy.barcodescannerforemployees
import android.provider.BaseColumns
-object ShelfContract {
- object ShelfEntry : BaseColumns {
- const val TABLE_NAME = "shelf"
- const val PRODUCT_ID = "product_id"
- const val EXPIRE_DATE = "expire_date"
- }
-}
\ No newline at end of file
diff --git a/app/src/main/res/layout/add_product_fragment.xml b/app/src/main/res/layout/add_product_fragment.xml
index 7744486..70e4c9f 100644
--- a/app/src/main/res/layout/add_product_fragment.xml
+++ b/app/src/main/res/layout/add_product_fragment.xml
@@ -16,7 +16,7 @@
android:layout_height="50dp"
android:text="@string/scan_label"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@+id/editTextText"
+ app:layout_constraintTop_toBottomOf="@+id/netWeight"
android:layout_marginTop="25dp"/>
@@ -44,7 +44,7 @@
android:layout_height="50dp"
android:inputType="text"
android:ems="10"
- android:id="@+id/editTextText"
+ android:id="@+id/netWeight"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
@@ -55,13 +55,13 @@
android:text="@string/saveButton"
android:layout_width="100dp"
android:layout_height="50dp" android:id="@+id/saveButton"
- app:layout_constraintTop_toBottomOf="@+id/editTextText"
+ app:layout_constraintTop_toBottomOf="@+id/netWeight"
android:layout_marginTop="25dp" app:layout_constraintEnd_toEndOf="parent"/>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 91d1171..3e0901f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -7,11 +7,9 @@
Scan
Previous
Product name
- Net weight
+ Net weight (g)
Save
Take picture
-
- Hello blank fragment
Product name
Product type
Image of a product
diff --git a/app/src/main/res/xml/file_path.xml b/app/src/main/res/xml/file_path.xml
new file mode 100644
index 0000000..f0dc009
--- /dev/null
+++ b/app/src/main/res/xml/file_path.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 850f59c..982cc60 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -12,6 +12,7 @@ material = "1.12.0"
constraintlayout = "2.1.4"
navigationFragmentKtx = "2.8.0"
navigationUiKtx = "2.8.0"
+firebaseCrashlyticsBuildtools = "3.0.2"
[libraries]
androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "cameraView" }
@@ -25,6 +26,7 @@ material = { group = "com.google.android.material", name = "material", version.r
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigationFragmentKtx" }
androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigationUiKtx" }
+firebase-crashlytics-buildtools = { group = "com.google.firebase", name = "firebase-crashlytics-buildtools", version.ref = "firebaseCrashlyticsBuildtools" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }