initial commit: upload project
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
6
.idea/compiler.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="21" />
|
||||
</component>
|
||||
</project>
|
10
.idea/deploymentTargetDropDown.xml
generated
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetDropDown">
|
||||
<value>
|
||||
<entry key="app">
|
||||
<State />
|
||||
</entry>
|
||||
</value>
|
||||
</component>
|
||||
</project>
|
18
.idea/deploymentTargetSelector.xml
generated
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetSelector">
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2024-07-20T06:36:39.946968600Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\rizky\.android\avd\Pixel_7_API_33.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
21
.idea/gradle.xml
generated
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="$PROJECT_DIR$/../../../../../../../../gradle/gradle-8.3" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveExternalAnnotations" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="AndroidDomInspection" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
6
.idea/kotlinc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="1.9.0" />
|
||||
</component>
|
||||
</project>
|
10
.idea/migrations.xml
generated
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectMigrations">
|
||||
<option name="MigrateToGradleLocalJavaHome">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
9
.idea/misc.xml
generated
Normal file
@ -0,0 +1,9 @@
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
17
.idea/runConfigurations.xml
generated
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
1
app/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
72
app/build.gradle.kts
Normal file
@ -0,0 +1,72 @@
|
||||
plugins {
|
||||
alias(libs.plugins.androidApplication)
|
||||
alias(libs.plugins.jetbrainsKotlinAndroid)
|
||||
id("kotlin-parcelize")
|
||||
id("com.google.devtools.ksp") version "1.9.0-1.0.11"
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.example.palmguardapp"
|
||||
compileSdk = 34
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.example.palmguardapp"
|
||||
minSdk = 24
|
||||
targetSdk = 34
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
buildConfigField("String", "BASE_URL", "\"https://www.teamteaguard.com/\"")
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
mlModelBinding = true
|
||||
buildConfig = true
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.github.yalantis:ucrop:2.2.9")
|
||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
|
||||
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
|
||||
implementation("androidx.datastore:datastore-preferences:1.0.0")
|
||||
implementation("com.google.android.material:material:1.11.0")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
|
||||
implementation("androidx.fragment:fragment-ktx:1.3.6")
|
||||
implementation("androidx.core:core-splashscreen:1.0.1")
|
||||
implementation("de.hdodenhof:circleimageview:3.1.0")
|
||||
implementation(libs.room.runtime)
|
||||
implementation(libs.room.ktx)
|
||||
implementation(libs.androidx.scenecore)
|
||||
ksp(libs.room.compiler)
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.material)
|
||||
implementation(libs.androidx.activity)
|
||||
implementation(libs.androidx.constraintlayout)
|
||||
implementation(libs.tensorflow.lite.support)
|
||||
implementation(libs.tensorflow.lite.metadata)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
}
|
21
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
@ -0,0 +1,24 @@
|
||||
package com.example.palmguardapp
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.example.teaguard", appContext.packageName)
|
||||
}
|
||||
}
|
54
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="28" />
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@drawable/splash_screen_ic"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@drawable/splash_screen_ic"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.TeaGuard"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".ui.errorDetection.ErrorDetectionActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.listDisease.DiseaseDetailActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.MainActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.diagnose.DiagnoseDetailActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.SplashScreenActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.yalantis.ucrop.UCropActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,20 @@
|
||||
package com.example.palmguardapp.data.local.entity
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Entity
|
||||
@Parcelize
|
||||
data class DiseaseDiagnose(
|
||||
@PrimaryKey()
|
||||
val id: String = "",
|
||||
val diseaseName: String,
|
||||
val diseaseExplanation: String,
|
||||
val diseaseRecommendation: String,
|
||||
val detailExplanation: String,
|
||||
val detailPrevention: String,
|
||||
val detailRecommendation: String,
|
||||
val date: String
|
||||
) : Parcelable
|
@ -0,0 +1,19 @@
|
||||
package com.example.palmguardapp.data.local.entity
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Entity
|
||||
@Parcelize
|
||||
data class HistoryDiagnose(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
val id: Int = 0,
|
||||
val name: String,
|
||||
val imageUri: String,
|
||||
val diagnosis: String,
|
||||
val recommendation: String,
|
||||
val confidence: String,
|
||||
val date: String
|
||||
) : Parcelable
|
@ -0,0 +1,134 @@
|
||||
package com.example.palmguardapp.data.local.room
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.example.palmguardapp.data.local.entity.DiseaseDiagnose
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Database(entities = [DiseaseDiagnose::class], version = 1)
|
||||
abstract class DiseaseDatabase : RoomDatabase() {
|
||||
abstract fun diseaseDiagnoseDao(): DiseaseDiagnoseDao
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var INSTANCE : DiseaseDatabase? = null
|
||||
|
||||
@JvmStatic
|
||||
fun getDatabase(context : Context) : DiseaseDatabase {
|
||||
if (INSTANCE == null) {
|
||||
synchronized(DiseaseDatabase::class.java) {
|
||||
INSTANCE = Room.databaseBuilder(context.applicationContext,
|
||||
DiseaseDatabase::class.java, "disease_diagnose_database")
|
||||
.addCallback(DatabaseCallback())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
return INSTANCE as DiseaseDatabase
|
||||
}
|
||||
}
|
||||
|
||||
private class DatabaseCallback : RoomDatabase.Callback() {
|
||||
override fun onCreate(db: SupportSQLiteDatabase) {
|
||||
super.onCreate(db)
|
||||
INSTANCE?.let { diseaseDatabase ->
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
populateDatabase(diseaseDatabase.diseaseDiagnoseDao())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun populateDatabase(dao: DiseaseDiagnoseDao) {
|
||||
val diseaseData = listOf(
|
||||
DiseaseDiagnose(
|
||||
id = "D-001",
|
||||
diseaseName = "Brown Spots",
|
||||
diseaseExplanation = "Brown spots adalah penyakit yang menyerang daun tanaman kelapa sawit, ditandai dengan munculnya bercak-bercak coklat yang dapat menyebar dengan cepat. Penyakit ini disebabkan oleh jamur Helminthosporium, yang berkembang biak di lingkungan dengan kelembaban tinggi dan sirkulasi udara yang buruk.",
|
||||
diseaseRecommendation = "Untuk mengatasi penyakit brown spots, diperlukan tindakan yang cepat dan tepat agar tidak menyebar ke seluruh bagian tanaman atau ke tanaman lain di sekitarnya. Salah satu langkah utama yang dapat dilakukan adalah menyemprotkan fungisida berbasis tembaga secara berkala, karena tembaga memiliki sifat fungisida yang efektif dalam menghambat pertumbuhan jamur penyebab penyakit ini.",
|
||||
detailExplanation = "Brown spots adalah penyakit yang umum ditemukan pada tanaman kelapa sawit dan disebabkan oleh jamur Helminthosporium. Jamur ini menyerang bagian daun dan menimbulkan bercak-bercak coklat yang dapat menyebar dengan cepat, terutama di lingkungan yang lembab. Jika tidak segera ditangani, infeksi dapat menyebabkan daun mengering, menurunkan efisiensi fotosintesis, dan pada akhirnya menghambat pertumbuhan tanaman. Penyakit ini sering muncul pada musim hujan atau di daerah dengan tingkat kelembaban yang tinggi.",
|
||||
detailPrevention = "Pencegahan penyakit brown spots dapat dilakukan dengan berbagai cara. Salah satu metode efektif adalah dengan memberikan pupuk yang mengandung tembaga, karena tembaga memiliki sifat fungisida alami yang dapat membantu mengurangi risiko infeksi jamur. Selain itu, penting untuk menjaga kebersihan lahan dengan memastikan sirkulasi udara yang baik di sekitar tanaman, sehingga kelembaban tidak terlalu tinggi. Pemangkasan daun yang terlalu lebat juga diperlukan agar sinar matahari dapat mencapai seluruh bagian tanaman dan mengurangi kemungkinan jamur berkembang. Penggunaan varietas kelapa sawit yang lebih tahan terhadap penyakit juga dapat menjadi strategi jangka panjang dalam mengurangi risiko infeksi.",
|
||||
detailRecommendation = "Jika tanaman sudah terinfeksi brown spots, tindakan cepat perlu dilakukan untuk mencegah penyebaran penyakit ke tanaman lain. Salah satu cara yang direkomendasikan adalah menyemprotkan fungisida berbasis tembaga secara berkala, karena tembaga efektif dalam menghambat pertumbuhan jamur penyebab penyakit ini. Penyemprotan harus dilakukan pada pagi atau sore hari untuk memastikan fungisida dapat bekerja secara optimal tanpa cepat menguap akibat sinar matahari. Selain itu, pastikan dosis yang digunakan sesuai dengan anjuran agar tidak merusak tanaman. Jika infeksi sudah parah, pemangkasan daun yang terdampak dapat membantu mengurangi penyebaran spora jamur ke bagian tanaman yang masih sehat.",
|
||||
date = "2025-02-10"
|
||||
),
|
||||
DiseaseDiagnose(
|
||||
id = "D-002",
|
||||
diseaseName = "Healthy",
|
||||
diseaseExplanation = "Tanaman dalam kondisi sehat tanpa menunjukkan gejala penyakit atau gangguan pertumbuhan. Semua bagian tanaman, mulai dari daun, batang, hingga akar, berkembang dengan baik dan berfungsi secara optimal. Warna daun hijau segar menandakan tanaman mendapatkan nutrisi yang cukup, sementara batang yang kokoh menunjukkan sistem perakaran yang sehat. Tidak ada tanda-tanda infeksi jamur, bakteri, atau serangan hama yang dapat mengganggu pertumbuhan.",
|
||||
diseaseRecommendation = "Untuk menjaga kondisi tanaman tetap sehat, penting untuk terus melanjutkan pola perawatan yang telah dilakukan. Pastikan tanaman mendapatkan nutrisi yang cukup melalui pemupukan yang seimbang dan sesuai dengan kebutuhannya. Selain itu, lakukan pemantauan secara rutin untuk memastikan tidak ada tanda-tanda awal penyakit atau serangan hama yang berpotensi merusak tanaman. Perhatikan juga faktor lingkungan seperti kelembaban, sirkulasi udara, dan intensitas cahaya, karena keseimbangan faktor-faktor ini sangat berpengaruh terhadap kesehatan tanaman dalam jangka panjang.",
|
||||
detailExplanation = "Tanaman ini berada dalam kondisi optimal tanpa adanya gejala penyakit atau gangguan pertumbuhan. Daun tampak hijau segar, batang kuat, serta sistem perakaran berkembang dengan baik. Tidak ditemukan bercak, layu, atau tanda-tanda serangan hama dan penyakit. Lingkungan tumbuh yang sehat dengan kadar air, nutrisi, dan pencahayaan yang cukup mendukung pertumbuhan tanaman secara maksimal. Tanaman yang sehat juga menunjukkan tingkat fotosintesis yang baik, sehingga mampu menghasilkan energi yang cukup untuk pertumbuhan dan perkembangan.",
|
||||
detailPrevention = "Untuk menjaga tanaman tetap sehat, penting untuk memastikan kondisi lingkungan tumbuh yang optimal. Faktor utama yang harus diperhatikan adalah ketersediaan air yang cukup tanpa menyebabkan kelebihan kelembaban, karena kondisi yang terlalu lembab dapat memicu pertumbuhan jamur dan bakteri patogen. Selain itu, penggunaan pupuk yang seimbang sesuai dengan kebutuhan tanaman sangat dianjurkan untuk mendukung pertumbuhan yang kuat. Pengendalian hama secara berkala juga diperlukan, baik dengan cara alami maupun menggunakan pestisida ramah lingkungan jika diperlukan. Rotasi tanaman dan sanitasi lahan dapat membantu mencegah munculnya hama dan penyakit yang dapat mengganggu kesehatan tanaman.",
|
||||
detailRecommendation = "Untuk mempertahankan kondisi tanaman yang sehat, lakukan perawatan secara rutin dengan memastikan tanaman mendapatkan nutrisi yang cukup melalui pemupukan yang tepat. Pastikan tanaman mendapatkan sinar matahari yang cukup dan memiliki sistem drainase yang baik agar tidak terjadi genangan air yang dapat merusak akar. Selain itu, lakukan pemantauan berkala terhadap kemungkinan munculnya gejala penyakit atau serangan hama agar dapat segera diatasi jika ditemukan tanda-tanda awal gangguan. Dengan menjaga keseimbangan antara faktor lingkungan, nutrisi, dan perlindungan tanaman, kondisi sehat ini dapat dipertahankan dalam jangka panjang.",
|
||||
date = "2025-02-10"
|
||||
),
|
||||
DiseaseDiagnose(
|
||||
id = "D-003",
|
||||
diseaseName = "Brown Spots",
|
||||
diseaseExplanation = "Brown spots adalah penyakit yang menyerang daun tanaman kelapa sawit, ditandai dengan munculnya bercak-bercak coklat yang dapat menyebar dengan cepat. Penyakit ini disebabkan oleh jamur Helminthosporium, yang berkembang biak di lingkungan dengan kelembaban tinggi dan sirkulasi udara yang buruk.",
|
||||
diseaseRecommendation = "Untuk mengatasi penyakit brown spots, diperlukan tindakan yang cepat dan tepat agar tidak menyebar ke seluruh bagian tanaman atau ke tanaman lain di sekitarnya. Salah satu langkah utama yang dapat dilakukan adalah menyemprotkan fungisida berbasis tembaga secara berkala, karena tembaga memiliki sifat fungisida yang efektif dalam menghambat pertumbuhan jamur penyebab penyakit ini.",
|
||||
detailExplanation = "Brown spots adalah penyakit yang umum ditemukan pada tanaman kelapa sawit dan disebabkan oleh jamur Helminthosporium. Jamur ini menyerang bagian daun dan menimbulkan bercak-bercak coklat yang dapat menyebar dengan cepat, terutama di lingkungan yang lembab. Jika tidak segera ditangani, infeksi dapat menyebabkan daun mengering, menurunkan efisiensi fotosintesis, dan pada akhirnya menghambat pertumbuhan tanaman. Penyakit ini sering muncul pada musim hujan atau di daerah dengan tingkat kelembaban yang tinggi.",
|
||||
detailPrevention = "Pencegahan penyakit brown spots dapat dilakukan dengan berbagai cara. Salah satu metode efektif adalah dengan memberikan pupuk yang mengandung tembaga, karena tembaga memiliki sifat fungisida alami yang dapat membantu mengurangi risiko infeksi jamur. Selain itu, penting untuk menjaga kebersihan lahan dengan memastikan sirkulasi udara yang baik di sekitar tanaman, sehingga kelembaban tidak terlalu tinggi. Pemangkasan daun yang terlalu lebat juga diperlukan agar sinar matahari dapat mencapai seluruh bagian tanaman dan mengurangi kemungkinan jamur berkembang. Penggunaan varietas kelapa sawit yang lebih tahan terhadap penyakit juga dapat menjadi strategi jangka panjang dalam mengurangi risiko infeksi.",
|
||||
detailRecommendation = "Jika tanaman sudah terinfeksi brown spots, tindakan cepat perlu dilakukan untuk mencegah penyebaran penyakit ke tanaman lain. Salah satu cara yang direkomendasikan adalah menyemprotkan fungisida berbasis tembaga secara berkala, karena tembaga efektif dalam menghambat pertumbuhan jamur penyebab penyakit ini. Penyemprotan harus dilakukan pada pagi atau sore hari untuk memastikan fungisida dapat bekerja secara optimal tanpa cepat menguap akibat sinar matahari. Selain itu, pastikan dosis yang digunakan sesuai dengan anjuran agar tidak merusak tanaman. Jika infeksi sudah parah, pemangkasan daun yang terdampak dapat membantu mengurangi penyebaran spora jamur ke bagian tanaman yang masih sehat.",
|
||||
date = "2025-02-10"
|
||||
),
|
||||
DiseaseDiagnose(
|
||||
id = "D-004",
|
||||
diseaseName = "Healthy",
|
||||
diseaseExplanation = "Tanaman dalam kondisi sehat tanpa menunjukkan gejala penyakit atau gangguan pertumbuhan. Semua bagian tanaman, mulai dari daun, batang, hingga akar, berkembang dengan baik dan berfungsi secara optimal. Warna daun hijau segar menandakan tanaman mendapatkan nutrisi yang cukup, sementara batang yang kokoh menunjukkan sistem perakaran yang sehat. Tidak ada tanda-tanda infeksi jamur, bakteri, atau serangan hama yang dapat mengganggu pertumbuhan.",
|
||||
diseaseRecommendation = "Untuk menjaga kondisi tanaman tetap sehat, penting untuk terus melanjutkan pola perawatan yang telah dilakukan. Pastikan tanaman mendapatkan nutrisi yang cukup melalui pemupukan yang seimbang dan sesuai dengan kebutuhannya. Selain itu, lakukan pemantauan secara rutin untuk memastikan tidak ada tanda-tanda awal penyakit atau serangan hama yang berpotensi merusak tanaman. Perhatikan juga faktor lingkungan seperti kelembaban, sirkulasi udara, dan intensitas cahaya, karena keseimbangan faktor-faktor ini sangat berpengaruh terhadap kesehatan tanaman dalam jangka panjang.",
|
||||
detailExplanation = "Tanaman ini berada dalam kondisi optimal tanpa adanya gejala penyakit atau gangguan pertumbuhan. Daun tampak hijau segar, batang kuat, serta sistem perakaran berkembang dengan baik. Tidak ditemukan bercak, layu, atau tanda-tanda serangan hama dan penyakit. Lingkungan tumbuh yang sehat dengan kadar air, nutrisi, dan pencahayaan yang cukup mendukung pertumbuhan tanaman secara maksimal. Tanaman yang sehat juga menunjukkan tingkat fotosintesis yang baik, sehingga mampu menghasilkan energi yang cukup untuk pertumbuhan dan perkembangan.",
|
||||
detailPrevention = "Untuk menjaga tanaman tetap sehat, penting untuk memastikan kondisi lingkungan tumbuh yang optimal. Faktor utama yang harus diperhatikan adalah ketersediaan air yang cukup tanpa menyebabkan kelebihan kelembaban, karena kondisi yang terlalu lembab dapat memicu pertumbuhan jamur dan bakteri patogen. Selain itu, penggunaan pupuk yang seimbang sesuai dengan kebutuhan tanaman sangat dianjurkan untuk mendukung pertumbuhan yang kuat. Pengendalian hama secara berkala juga diperlukan, baik dengan cara alami maupun menggunakan pestisida ramah lingkungan jika diperlukan. Rotasi tanaman dan sanitasi lahan dapat membantu mencegah munculnya hama dan penyakit yang dapat mengganggu kesehatan tanaman.",
|
||||
detailRecommendation = "Untuk mempertahankan kondisi tanaman yang sehat, lakukan perawatan secara rutin dengan memastikan tanaman mendapatkan nutrisi yang cukup melalui pemupukan yang tepat. Pastikan tanaman mendapatkan sinar matahari yang cukup dan memiliki sistem drainase yang baik agar tidak terjadi genangan air yang dapat merusak akar. Selain itu, lakukan pemantauan berkala terhadap kemungkinan munculnya gejala penyakit atau serangan hama agar dapat segera diatasi jika ditemukan tanda-tanda awal gangguan. Dengan menjaga keseimbangan antara faktor lingkungan, nutrisi, dan perlindungan tanaman, kondisi sehat ini dapat dipertahankan dalam jangka panjang.",
|
||||
date = "2025-02-10"
|
||||
),
|
||||
DiseaseDiagnose(
|
||||
id = "D-005",
|
||||
diseaseName = "Brown Spots",
|
||||
diseaseExplanation = "Brown spots adalah penyakit yang menyerang daun tanaman kelapa sawit, ditandai dengan munculnya bercak-bercak coklat yang dapat menyebar dengan cepat. Penyakit ini disebabkan oleh jamur Helminthosporium, yang berkembang biak di lingkungan dengan kelembaban tinggi dan sirkulasi udara yang buruk.",
|
||||
diseaseRecommendation = "Untuk mengatasi penyakit brown spots, diperlukan tindakan yang cepat dan tepat agar tidak menyebar ke seluruh bagian tanaman atau ke tanaman lain di sekitarnya. Salah satu langkah utama yang dapat dilakukan adalah menyemprotkan fungisida berbasis tembaga secara berkala, karena tembaga memiliki sifat fungisida yang efektif dalam menghambat pertumbuhan jamur penyebab penyakit ini.",
|
||||
detailExplanation = "Brown spots adalah penyakit yang umum ditemukan pada tanaman kelapa sawit dan disebabkan oleh jamur Helminthosporium. Jamur ini menyerang bagian daun dan menimbulkan bercak-bercak coklat yang dapat menyebar dengan cepat, terutama di lingkungan yang lembab. Jika tidak segera ditangani, infeksi dapat menyebabkan daun mengering, menurunkan efisiensi fotosintesis, dan pada akhirnya menghambat pertumbuhan tanaman. Penyakit ini sering muncul pada musim hujan atau di daerah dengan tingkat kelembaban yang tinggi.",
|
||||
detailPrevention = "Pencegahan penyakit brown spots dapat dilakukan dengan berbagai cara. Salah satu metode efektif adalah dengan memberikan pupuk yang mengandung tembaga, karena tembaga memiliki sifat fungisida alami yang dapat membantu mengurangi risiko infeksi jamur. Selain itu, penting untuk menjaga kebersihan lahan dengan memastikan sirkulasi udara yang baik di sekitar tanaman, sehingga kelembaban tidak terlalu tinggi. Pemangkasan daun yang terlalu lebat juga diperlukan agar sinar matahari dapat mencapai seluruh bagian tanaman dan mengurangi kemungkinan jamur berkembang. Penggunaan varietas kelapa sawit yang lebih tahan terhadap penyakit juga dapat menjadi strategi jangka panjang dalam mengurangi risiko infeksi.",
|
||||
detailRecommendation = "Jika tanaman sudah terinfeksi brown spots, tindakan cepat perlu dilakukan untuk mencegah penyebaran penyakit ke tanaman lain. Salah satu cara yang direkomendasikan adalah menyemprotkan fungisida berbasis tembaga secara berkala, karena tembaga efektif dalam menghambat pertumbuhan jamur penyebab penyakit ini. Penyemprotan harus dilakukan pada pagi atau sore hari untuk memastikan fungisida dapat bekerja secara optimal tanpa cepat menguap akibat sinar matahari. Selain itu, pastikan dosis yang digunakan sesuai dengan anjuran agar tidak merusak tanaman. Jika infeksi sudah parah, pemangkasan daun yang terdampak dapat membantu mengurangi penyebaran spora jamur ke bagian tanaman yang masih sehat.",
|
||||
date = "2025-02-10"
|
||||
),
|
||||
DiseaseDiagnose(
|
||||
id = "D-006",
|
||||
diseaseName = "Healthy",
|
||||
diseaseExplanation = "Tanaman dalam kondisi sehat tanpa menunjukkan gejala penyakit atau gangguan pertumbuhan. Semua bagian tanaman, mulai dari daun, batang, hingga akar, berkembang dengan baik dan berfungsi secara optimal. Warna daun hijau segar menandakan tanaman mendapatkan nutrisi yang cukup, sementara batang yang kokoh menunjukkan sistem perakaran yang sehat. Tidak ada tanda-tanda infeksi jamur, bakteri, atau serangan hama yang dapat mengganggu pertumbuhan.",
|
||||
diseaseRecommendation = "Untuk menjaga kondisi tanaman tetap sehat, penting untuk terus melanjutkan pola perawatan yang telah dilakukan. Pastikan tanaman mendapatkan nutrisi yang cukup melalui pemupukan yang seimbang dan sesuai dengan kebutuhannya. Selain itu, lakukan pemantauan secara rutin untuk memastikan tidak ada tanda-tanda awal penyakit atau serangan hama yang berpotensi merusak tanaman. Perhatikan juga faktor lingkungan seperti kelembaban, sirkulasi udara, dan intensitas cahaya, karena keseimbangan faktor-faktor ini sangat berpengaruh terhadap kesehatan tanaman dalam jangka panjang.",
|
||||
detailExplanation = "Tanaman ini berada dalam kondisi optimal tanpa adanya gejala penyakit atau gangguan pertumbuhan. Daun tampak hijau segar, batang kuat, serta sistem perakaran berkembang dengan baik. Tidak ditemukan bercak, layu, atau tanda-tanda serangan hama dan penyakit. Lingkungan tumbuh yang sehat dengan kadar air, nutrisi, dan pencahayaan yang cukup mendukung pertumbuhan tanaman secara maksimal. Tanaman yang sehat juga menunjukkan tingkat fotosintesis yang baik, sehingga mampu menghasilkan energi yang cukup untuk pertumbuhan dan perkembangan.",
|
||||
detailPrevention = "Untuk menjaga tanaman tetap sehat, penting untuk memastikan kondisi lingkungan tumbuh yang optimal. Faktor utama yang harus diperhatikan adalah ketersediaan air yang cukup tanpa menyebabkan kelebihan kelembaban, karena kondisi yang terlalu lembab dapat memicu pertumbuhan jamur dan bakteri patogen. Selain itu, penggunaan pupuk yang seimbang sesuai dengan kebutuhan tanaman sangat dianjurkan untuk mendukung pertumbuhan yang kuat. Pengendalian hama secara berkala juga diperlukan, baik dengan cara alami maupun menggunakan pestisida ramah lingkungan jika diperlukan. Rotasi tanaman dan sanitasi lahan dapat membantu mencegah munculnya hama dan penyakit yang dapat mengganggu kesehatan tanaman.",
|
||||
detailRecommendation = "Untuk mempertahankan kondisi tanaman yang sehat, lakukan perawatan secara rutin dengan memastikan tanaman mendapatkan nutrisi yang cukup melalui pemupukan yang tepat. Pastikan tanaman mendapatkan sinar matahari yang cukup dan memiliki sistem drainase yang baik agar tidak terjadi genangan air yang dapat merusak akar. Selain itu, lakukan pemantauan berkala terhadap kemungkinan munculnya gejala penyakit atau serangan hama agar dapat segera diatasi jika ditemukan tanda-tanda awal gangguan. Dengan menjaga keseimbangan antara faktor lingkungan, nutrisi, dan perlindungan tanaman, kondisi sehat ini dapat dipertahankan dalam jangka panjang.",
|
||||
date = "2025-02-10"
|
||||
),
|
||||
DiseaseDiagnose(
|
||||
id = "D-007",
|
||||
diseaseName = "Brown Spots",
|
||||
diseaseExplanation = "Brown spots adalah penyakit yang menyerang daun tanaman kelapa sawit, ditandai dengan munculnya bercak-bercak coklat yang dapat menyebar dengan cepat. Penyakit ini disebabkan oleh jamur Helminthosporium, yang berkembang biak di lingkungan dengan kelembaban tinggi dan sirkulasi udara yang buruk.",
|
||||
diseaseRecommendation = "Untuk mengatasi penyakit brown spots, diperlukan tindakan yang cepat dan tepat agar tidak menyebar ke seluruh bagian tanaman atau ke tanaman lain di sekitarnya. Salah satu langkah utama yang dapat dilakukan adalah menyemprotkan fungisida berbasis tembaga secara berkala, karena tembaga memiliki sifat fungisida yang efektif dalam menghambat pertumbuhan jamur penyebab penyakit ini.",
|
||||
detailExplanation = "Brown spots adalah penyakit yang umum ditemukan pada tanaman kelapa sawit dan disebabkan oleh jamur Helminthosporium. Jamur ini menyerang bagian daun dan menimbulkan bercak-bercak coklat yang dapat menyebar dengan cepat, terutama di lingkungan yang lembab. Jika tidak segera ditangani, infeksi dapat menyebabkan daun mengering, menurunkan efisiensi fotosintesis, dan pada akhirnya menghambat pertumbuhan tanaman. Penyakit ini sering muncul pada musim hujan atau di daerah dengan tingkat kelembaban yang tinggi.",
|
||||
detailPrevention = "Pencegahan penyakit brown spots dapat dilakukan dengan berbagai cara. Salah satu metode efektif adalah dengan memberikan pupuk yang mengandung tembaga, karena tembaga memiliki sifat fungisida alami yang dapat membantu mengurangi risiko infeksi jamur. Selain itu, penting untuk menjaga kebersihan lahan dengan memastikan sirkulasi udara yang baik di sekitar tanaman, sehingga kelembaban tidak terlalu tinggi. Pemangkasan daun yang terlalu lebat juga diperlukan agar sinar matahari dapat mencapai seluruh bagian tanaman dan mengurangi kemungkinan jamur berkembang. Penggunaan varietas kelapa sawit yang lebih tahan terhadap penyakit juga dapat menjadi strategi jangka panjang dalam mengurangi risiko infeksi.",
|
||||
detailRecommendation = "Jika tanaman sudah terinfeksi brown spots, tindakan cepat perlu dilakukan untuk mencegah penyebaran penyakit ke tanaman lain. Salah satu cara yang direkomendasikan adalah menyemprotkan fungisida berbasis tembaga secara berkala, karena tembaga efektif dalam menghambat pertumbuhan jamur penyebab penyakit ini. Penyemprotan harus dilakukan pada pagi atau sore hari untuk memastikan fungisida dapat bekerja secara optimal tanpa cepat menguap akibat sinar matahari. Selain itu, pastikan dosis yang digunakan sesuai dengan anjuran agar tidak merusak tanaman. Jika infeksi sudah parah, pemangkasan daun yang terdampak dapat membantu mengurangi penyebaran spora jamur ke bagian tanaman yang masih sehat.",
|
||||
date = "2025-02-10"
|
||||
),
|
||||
DiseaseDiagnose(
|
||||
id = "D-008",
|
||||
diseaseName = "Healthy",
|
||||
diseaseExplanation = "Tanaman dalam kondisi sehat tanpa menunjukkan gejala penyakit atau gangguan pertumbuhan. Semua bagian tanaman, mulai dari daun, batang, hingga akar, berkembang dengan baik dan berfungsi secara optimal. Warna daun hijau segar menandakan tanaman mendapatkan nutrisi yang cukup, sementara batang yang kokoh menunjukkan sistem perakaran yang sehat. Tidak ada tanda-tanda infeksi jamur, bakteri, atau serangan hama yang dapat mengganggu pertumbuhan.",
|
||||
diseaseRecommendation = "Untuk menjaga kondisi tanaman tetap sehat, penting untuk terus melanjutkan pola perawatan yang telah dilakukan. Pastikan tanaman mendapatkan nutrisi yang cukup melalui pemupukan yang seimbang dan sesuai dengan kebutuhannya. Selain itu, lakukan pemantauan secara rutin untuk memastikan tidak ada tanda-tanda awal penyakit atau serangan hama yang berpotensi merusak tanaman. Perhatikan juga faktor lingkungan seperti kelembaban, sirkulasi udara, dan intensitas cahaya, karena keseimbangan faktor-faktor ini sangat berpengaruh terhadap kesehatan tanaman dalam jangka panjang.",
|
||||
detailExplanation = "Tanaman ini berada dalam kondisi optimal tanpa adanya gejala penyakit atau gangguan pertumbuhan. Daun tampak hijau segar, batang kuat, serta sistem perakaran berkembang dengan baik. Tidak ditemukan bercak, layu, atau tanda-tanda serangan hama dan penyakit. Lingkungan tumbuh yang sehat dengan kadar air, nutrisi, dan pencahayaan yang cukup mendukung pertumbuhan tanaman secara maksimal. Tanaman yang sehat juga menunjukkan tingkat fotosintesis yang baik, sehingga mampu menghasilkan energi yang cukup untuk pertumbuhan dan perkembangan.",
|
||||
detailPrevention = "Untuk menjaga tanaman tetap sehat, penting untuk memastikan kondisi lingkungan tumbuh yang optimal. Faktor utama yang harus diperhatikan adalah ketersediaan air yang cukup tanpa menyebabkan kelebihan kelembaban, karena kondisi yang terlalu lembab dapat memicu pertumbuhan jamur dan bakteri patogen. Selain itu, penggunaan pupuk yang seimbang sesuai dengan kebutuhan tanaman sangat dianjurkan untuk mendukung pertumbuhan yang kuat. Pengendalian hama secara berkala juga diperlukan, baik dengan cara alami maupun menggunakan pestisida ramah lingkungan jika diperlukan. Rotasi tanaman dan sanitasi lahan dapat membantu mencegah munculnya hama dan penyakit yang dapat mengganggu kesehatan tanaman.",
|
||||
detailRecommendation = "Untuk mempertahankan kondisi tanaman yang sehat, lakukan perawatan secara rutin dengan memastikan tanaman mendapatkan nutrisi yang cukup melalui pemupukan yang tepat. Pastikan tanaman mendapatkan sinar matahari yang cukup dan memiliki sistem drainase yang baik agar tidak terjadi genangan air yang dapat merusak akar. Selain itu, lakukan pemantauan berkala terhadap kemungkinan munculnya gejala penyakit atau serangan hama agar dapat segera diatasi jika ditemukan tanda-tanda awal gangguan. Dengan menjaga keseimbangan antara faktor lingkungan, nutrisi, dan perlindungan tanaman, kondisi sehat ini dapat dipertahankan dalam jangka panjang.",
|
||||
date = "2025-02-10"
|
||||
),
|
||||
|
||||
)
|
||||
diseaseData.forEach{ dao.insert(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.example.palmguardapp.data.local.room
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Update
|
||||
import com.example.palmguardapp.data.local.entity.DiseaseDiagnose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface DiseaseDiagnoseDao {
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
suspend fun insert(diseaseDiagnose: DiseaseDiagnose)
|
||||
|
||||
@Update
|
||||
suspend fun update(diseaseDiagnose: DiseaseDiagnose)
|
||||
|
||||
@Delete
|
||||
suspend fun delete(diseaseDiagnose: DiseaseDiagnose)
|
||||
|
||||
@Query("SELECT * FROM diseasediagnose")
|
||||
fun getAllDisease(): Flow<List<DiseaseDiagnose>>
|
||||
|
||||
@Query("SELECT * FROM diseasediagnose WHERE id = :id")
|
||||
fun getDiseaseById(id: String): Flow<DiseaseDiagnose>
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.example.palmguardapp.data.local.room
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import com.example.palmguardapp.data.local.entity.HistoryDiagnose
|
||||
|
||||
@Database(entities = [HistoryDiagnose::class], version = 1)
|
||||
abstract class HistoryDatabase : RoomDatabase() {
|
||||
abstract fun historyDao(): HistoryDiagnoseDao
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var INSTANCE : HistoryDatabase? = null
|
||||
|
||||
@JvmStatic
|
||||
fun getDatabase(context : Context) : HistoryDatabase {
|
||||
if (INSTANCE == null) {
|
||||
synchronized(HistoryDatabase::class.java) {
|
||||
INSTANCE = Room.databaseBuilder(context.applicationContext,
|
||||
HistoryDatabase::class.java, "history_diagnose_database")
|
||||
.build()
|
||||
}
|
||||
}
|
||||
return INSTANCE as HistoryDatabase
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.example.palmguardapp.data.local.room
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Update
|
||||
import com.example.palmguardapp.data.local.entity.HistoryDiagnose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface HistoryDiagnoseDao {
|
||||
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||
suspend fun insert(historyDiagnose: HistoryDiagnose)
|
||||
|
||||
@Update
|
||||
suspend fun update(historyDiagnose: HistoryDiagnose)
|
||||
|
||||
@Delete
|
||||
suspend fun delete(historyDiagnose: HistoryDiagnose)
|
||||
|
||||
@Query("SELECT * FROM historydiagnose ORDER BY id DESC")
|
||||
fun getAllHistory(): Flow<List<HistoryDiagnose>>
|
||||
|
||||
@Query("SELECT * FROM historydiagnose ORDER BY id DESC LIMIT 1")
|
||||
fun getLastHistory(): Flow<HistoryDiagnose>
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package com.example.palmguardapp.data.repository
|
||||
|
||||
import com.example.palmguardapp.data.local.entity.DiseaseDiagnose
|
||||
import com.example.palmguardapp.data.local.room.DiseaseDiagnoseDao
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
//class DiseaseRepository private constructor(
|
||||
// private val apiService: ApiService
|
||||
//) {
|
||||
//
|
||||
// suspend fun getDiseaseById(id: String): Flow<Result<DiseaseByIdResponse>> = flow {
|
||||
// emit(Result.Loading)
|
||||
// val response = apiService.getDiseaseById(id)
|
||||
// emit(Result.Success(response))
|
||||
// }.catch { e ->
|
||||
// emit(Result.Error(e.message.toString()))
|
||||
// }
|
||||
//
|
||||
// suspend fun getAllDiseaseDetail(): Flow<Result<DiseaseDetailResponse>> = flow {
|
||||
// emit(Result.Loading)
|
||||
// val response = apiService.getAllDiseaseDetail()
|
||||
// emit(Result.Success(response))
|
||||
// }.catch { e ->
|
||||
// emit(Result.Error(e.message.toString()))
|
||||
// }
|
||||
//
|
||||
// suspend fun getDiseaseDetailById(id: String): Flow<Result<DiseaseDetailByIdResponse>> = flow {
|
||||
// emit(Result.Loading)
|
||||
// val response = apiService.getDiseaseDetailById(id)
|
||||
// emit(Result.Success(response))
|
||||
// }.catch { e ->
|
||||
// emit(Result.Error(e.message.toString()))
|
||||
// }
|
||||
//
|
||||
// companion object {
|
||||
// @Volatile
|
||||
// private var instance: DiseaseRepository? = null
|
||||
//
|
||||
// fun getInstance(apiService: ApiService): DiseaseRepository =
|
||||
// instance ?: synchronized(this) {
|
||||
// instance ?: DiseaseRepository(apiService).also { instance = it }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
class DiseaseRepository private constructor(
|
||||
private val diseaseDiagnoseDao: DiseaseDiagnoseDao
|
||||
) {
|
||||
suspend fun insert(diseaseDiagnose: DiseaseDiagnose) {
|
||||
diseaseDiagnoseDao.insert(diseaseDiagnose)
|
||||
}
|
||||
|
||||
suspend fun update(diseaseDiagnose: DiseaseDiagnose) {
|
||||
diseaseDiagnoseDao.update(diseaseDiagnose)
|
||||
}
|
||||
|
||||
suspend fun delete(diseaseDiagnose: DiseaseDiagnose) {
|
||||
diseaseDiagnoseDao.delete(diseaseDiagnose)
|
||||
}
|
||||
|
||||
fun getAllDisease(): Flow<List<DiseaseDiagnose>> = diseaseDiagnoseDao.getAllDisease()
|
||||
|
||||
fun getDiseaseById(id: String): Flow<DiseaseDiagnose> = diseaseDiagnoseDao.getDiseaseById(id)
|
||||
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var instance: DiseaseRepository? = null
|
||||
|
||||
fun getInstance(diseaseDiagnoseDao: DiseaseDiagnoseDao): DiseaseRepository =
|
||||
instance ?: synchronized(this) {
|
||||
instance ?: DiseaseRepository(diseaseDiagnoseDao).also { instance = it }
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.example.palmguardapp.data.repository
|
||||
|
||||
import com.example.palmguardapp.data.local.entity.HistoryDiagnose
|
||||
import com.example.palmguardapp.data.local.room.HistoryDiagnoseDao
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class HistoryDiagnoseRepository private constructor(
|
||||
private val historyDiagnoseDao: HistoryDiagnoseDao
|
||||
) {
|
||||
|
||||
fun getAllHistory(): Flow<List<HistoryDiagnose>> = historyDiagnoseDao.getAllHistory()
|
||||
|
||||
suspend fun insert(historyDiagnose: HistoryDiagnose) {
|
||||
historyDiagnoseDao.insert(historyDiagnose)
|
||||
}
|
||||
|
||||
suspend fun update(historyDiagnose: HistoryDiagnose) {
|
||||
historyDiagnoseDao.update(historyDiagnose)
|
||||
}
|
||||
|
||||
suspend fun delete(historyDiagnose: HistoryDiagnose) {
|
||||
historyDiagnoseDao.delete(historyDiagnose)
|
||||
}
|
||||
|
||||
fun getLastHistory() : Flow<HistoryDiagnose> = historyDiagnoseDao.getLastHistory()
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var instance: HistoryDiagnoseRepository? = null
|
||||
|
||||
fun getInstance(historyDiagnoseDao: HistoryDiagnoseDao): HistoryDiagnoseRepository =
|
||||
instance ?: synchronized(this) {
|
||||
instance ?: HistoryDiagnoseRepository(historyDiagnoseDao).also { instance = it }
|
||||
}
|
||||
}
|
||||
}
|
23
app/src/main/java/com/example/palmguardapp/di/Injection.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package com.example.palmguardapp.di
|
||||
|
||||
import android.content.Context
|
||||
import com.example.palmguardapp.data.local.room.DiseaseDatabase
|
||||
import com.example.palmguardapp.data.local.room.HistoryDatabase
|
||||
import com.example.palmguardapp.data.repository.DiseaseRepository
|
||||
import com.example.palmguardapp.data.repository.HistoryDiagnoseRepository
|
||||
|
||||
object Injection {
|
||||
fun provideDiagnoseRepository(context : Context) : HistoryDiagnoseRepository {
|
||||
val database = HistoryDatabase.getDatabase(context)
|
||||
val dao = database.historyDao()
|
||||
|
||||
return HistoryDiagnoseRepository.getInstance(dao)
|
||||
}
|
||||
|
||||
fun provideDiseaseRepository(context: Context): DiseaseRepository {
|
||||
val database = DiseaseDatabase.getDatabase(context)
|
||||
val dao = database.diseaseDiagnoseDao()
|
||||
|
||||
return DiseaseRepository.getInstance(dao)
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.example.palmguardapp.foundation.adapter
|
||||
|
||||
import android.net.Uri
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.example.palmguardapp.data.local.entity.HistoryDiagnose
|
||||
import com.example.palmguardapp.databinding.ItemResultBinding
|
||||
|
||||
class HistoryDiagnoseAdapter : ListAdapter<HistoryDiagnose, HistoryDiagnoseAdapter.ViewHolder>(DIFF_CALLBACK) {
|
||||
|
||||
private lateinit var onItemClickCallback: OnItemClickCallback
|
||||
|
||||
companion object {
|
||||
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<HistoryDiagnose>() {
|
||||
override fun areItemsTheSame(oldItem: HistoryDiagnose, newItem: HistoryDiagnose): Boolean {
|
||||
return oldItem.id == newItem.id
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: HistoryDiagnose, newItem: HistoryDiagnose): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = ItemResultBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return ViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val history = getItem(position)
|
||||
holder.bind(history)
|
||||
holder.itemView.setOnClickListener {
|
||||
onItemClickCallback.onItemClicked(history)
|
||||
}
|
||||
}
|
||||
|
||||
inner class ViewHolder(private val binding: ItemResultBinding) : RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(historyDiagnose: HistoryDiagnose) {
|
||||
binding.apply {
|
||||
binding.imgResultDiagnosis.setImageURI(Uri.parse(historyDiagnose.imageUri))
|
||||
titleResultDiagnosis.text = historyDiagnose.name
|
||||
val date = historyDiagnose.date.replace("-", " ")
|
||||
dateResultDiagnosis.text = date
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface OnItemClickCallback {
|
||||
fun onItemClicked(data: HistoryDiagnose)
|
||||
}
|
||||
|
||||
fun setOnItemClickCallback(onItemClickCallback: OnItemClickCallback) {
|
||||
this.onItemClickCallback = onItemClickCallback
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.example.palmguardapp.foundation.adapter
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.example.palmguardapp.data.local.entity.HistoryDiagnose
|
||||
import com.example.palmguardapp.ui.diagnose.DiagnoseFragment
|
||||
import com.example.palmguardapp.ui.diagnose.RecommendationFragment
|
||||
|
||||
class VPAdapter(
|
||||
fa: FragmentActivity,
|
||||
private val historyDiagnose: HistoryDiagnose
|
||||
): FragmentStateAdapter(fa) {
|
||||
override fun getItemCount(): Int {
|
||||
return 2
|
||||
}
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return when(position) {
|
||||
0 -> DiagnoseFragment.newInstance(historyDiagnose.diagnosis)
|
||||
1 -> RecommendationFragment.newInstance(historyDiagnose.recommendation)
|
||||
else -> DiagnoseFragment()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.util.Log
|
||||
import com.example.palmguardapp.ml.Model
|
||||
import org.tensorflow.lite.DataType
|
||||
import org.tensorflow.lite.support.image.ImageProcessor
|
||||
import org.tensorflow.lite.support.image.TensorImage
|
||||
import org.tensorflow.lite.support.image.ops.ResizeOp
|
||||
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer
|
||||
|
||||
|
||||
class ImageClassifier(private val context: Context) {
|
||||
|
||||
private val imageSize = 224
|
||||
private val classes = arrayOf("Brown Spots", "Healthy")
|
||||
|
||||
private val imageProcessor = ImageProcessor.Builder()
|
||||
.add(ResizeOp(imageSize, imageSize, ResizeOp.ResizeMethod.BILINEAR))
|
||||
.build()
|
||||
|
||||
fun classifyImage(image: Bitmap): Pair<String, Float>? {
|
||||
val model = Model.newInstance(context)
|
||||
|
||||
val tensorImage = TensorImage(DataType.FLOAT32)
|
||||
tensorImage.load(image)
|
||||
val processedImage = imageProcessor.process(tensorImage)
|
||||
|
||||
val inputFeature0 = TensorBuffer.createFixedSize(intArrayOf(1, imageSize, imageSize, 3), DataType.FLOAT32)
|
||||
inputFeature0.loadBuffer(processedImage.buffer)
|
||||
|
||||
val outputs = model.process(inputFeature0)
|
||||
val outputFeature0 = outputs.outputFeature0AsTensorBuffer
|
||||
|
||||
val confidences = outputFeature0.floatArray
|
||||
for (i in confidences.indices) {
|
||||
Log.d("ImageClassifier", "Class $i (${classes[i]}): ${confidences[i]}")
|
||||
}
|
||||
|
||||
val maxPos = confidences.indices.maxByOrNull { confidences[it] } ?: -1
|
||||
val maxConfidence = confidences[maxPos]
|
||||
|
||||
model.close()
|
||||
|
||||
return if (maxPos >= 0 && maxConfidence > THRESHOLD_CONFIDENCE) {
|
||||
Pair(classes[maxPos], maxConfidence)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val THRESHOLD_CONFIDENCE = 0.5f
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,126 @@
|
||||
package com.example.palmguardapp.foundation.utils
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Matrix
|
||||
import android.media.ExifInterface
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import androidx.core.content.FileProvider
|
||||
import com.example.palmguardapp.BuildConfig
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import java.util.UUID
|
||||
|
||||
private const val FILENAME_FORMAT = "yyyyMMdd_HHmmssSSS"
|
||||
private val timeStamp: String = SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(Date())
|
||||
private val uniqueID: String = UUID.randomUUID().toString()
|
||||
|
||||
fun getImageUri(context: Context): Uri {
|
||||
var uri: Uri? = null
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
val contentValues = ContentValues().apply {
|
||||
put(MediaStore.MediaColumns.DISPLAY_NAME, "$timeStamp.jpg")
|
||||
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
|
||||
put(MediaStore.MediaColumns.RELATIVE_PATH, "Pictures/MyCamera/")
|
||||
}
|
||||
uri = context.contentResolver.insert(
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||
contentValues
|
||||
)
|
||||
}
|
||||
return uri ?: getImageUriForPreQ(context)
|
||||
}
|
||||
|
||||
private fun getImageUriForPreQ(context: Context): Uri {
|
||||
val filesDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
|
||||
val imageFile = File(filesDir, "/MyCamera/$timeStamp.jpg")
|
||||
if (imageFile.parentFile?.exists() == false) imageFile.parentFile?.mkdir()
|
||||
return FileProvider.getUriForFile(
|
||||
context,
|
||||
"${BuildConfig.APPLICATION_ID}.fileprovider",
|
||||
imageFile
|
||||
)
|
||||
}
|
||||
fun createCustomTempFile(context: Context): File {
|
||||
val filesDir = context.externalCacheDir
|
||||
return File.createTempFile(timeStamp, ".jpg", filesDir)
|
||||
}
|
||||
|
||||
fun uriToFile(imageUri : Uri, context: Context): File {
|
||||
val myFile = createCustomTempFile(context)
|
||||
val inputStream = context.contentResolver.openInputStream(imageUri) as InputStream
|
||||
val outputStream = FileOutputStream(myFile)
|
||||
val buffer = ByteArray(1024)
|
||||
var length: Int
|
||||
while (inputStream.read(buffer).also { length = it } > 0) outputStream.write(buffer, 0, length)
|
||||
outputStream.close()
|
||||
inputStream.close()
|
||||
return myFile
|
||||
}
|
||||
|
||||
private const val MAXIMAL_SIZE = 1000000
|
||||
|
||||
fun File.reduceFileImage(): File {
|
||||
val file = this
|
||||
val bitmap = BitmapFactory.decodeFile(file.path).getRotatedBitmap(file)
|
||||
var compressQuality = 100
|
||||
var streamLength: Int
|
||||
do {
|
||||
val bmpStream = ByteArrayOutputStream()
|
||||
bitmap?.compress(Bitmap.CompressFormat.JPEG, compressQuality, bmpStream)
|
||||
val bmpPicByteArray = bmpStream.toByteArray()
|
||||
streamLength = bmpPicByteArray.size
|
||||
compressQuality -= 5
|
||||
} while (streamLength > MAXIMAL_SIZE)
|
||||
bitmap?.compress(Bitmap.CompressFormat.JPEG, compressQuality, FileOutputStream(file))
|
||||
return file
|
||||
}
|
||||
@TargetApi(Build.VERSION_CODES.Q)
|
||||
fun Bitmap.getRotatedBitmap(file: File): Bitmap? {
|
||||
val orientation = ExifInterface(file).getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED
|
||||
)
|
||||
return when (orientation) {
|
||||
ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage(this, 90F)
|
||||
ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(this, 180F)
|
||||
ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(this, 270F)
|
||||
ExifInterface.ORIENTATION_NORMAL -> this
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
fun rotateImage(source: Bitmap, angle: Float): Bitmap? {
|
||||
val matrix = Matrix()
|
||||
matrix.postRotate(angle)
|
||||
return Bitmap.createBitmap(
|
||||
source, 0, 0, source.width, source.height, matrix, true
|
||||
)
|
||||
}
|
||||
|
||||
fun saveImageToLocalStorage(context: Context, image: Bitmap): Uri {
|
||||
val timeStamp = SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(Date())
|
||||
val uniqueID = UUID.randomUUID().toString()
|
||||
val filename = "${timeStamp}_${uniqueID}.jpg"
|
||||
val filesDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
|
||||
val imageFile = File(filesDir, filename)
|
||||
|
||||
val fos = FileOutputStream(imageFile)
|
||||
image.compress(Bitmap.CompressFormat.JPEG, 100, fos)
|
||||
fos.flush()
|
||||
fos.close()
|
||||
|
||||
val reducedFile = imageFile.reduceFileImage()
|
||||
|
||||
return Uri.fromFile(reducedFile)
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.example.palmguardapp.foundation.utils
|
||||
|
||||
sealed class Result<out R> private constructor() {
|
||||
data class Success<out T>(val data: T) : Result<T>()
|
||||
data class Error(val error: String) : Result<Nothing>()
|
||||
object Loading : Result<Nothing>()
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package com.example.palmguardapp.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.example.palmguardapp.R
|
||||
import com.example.palmguardapp.databinding.ActivityMainBinding
|
||||
import com.example.palmguardapp.ui.detection.DetectionFragment
|
||||
import com.example.palmguardapp.ui.home.HomeFragment
|
||||
import com.example.palmguardapp.ui.listDisease.DiseaseDetailActivity
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
replaceFragment(HomeFragment())
|
||||
|
||||
binding.bottomNavigationView.setOnItemSelectedListener { item ->
|
||||
when(item.itemId) {
|
||||
R.id.home -> {
|
||||
replaceFragment(HomeFragment())
|
||||
true
|
||||
}
|
||||
R.id.detection -> {
|
||||
replaceFragment(DetectionFragment())
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun replaceFragment(fragment: Fragment) {
|
||||
val fragmentManager = supportFragmentManager
|
||||
val fragmentTransaction = fragmentManager.beginTransaction()
|
||||
fragmentTransaction.replace(R.id.frame_layout, fragment)
|
||||
fragmentTransaction.commit()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.example.palmguardapp.ui
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.example.palmguardapp.R
|
||||
|
||||
class SplashScreenActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContentView(R.layout.activity_splash_screen)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
finish()
|
||||
}, 1500)
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.example.palmguardapp.ui
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.example.palmguardapp.data.repository.DiseaseRepository
|
||||
import com.example.palmguardapp.data.repository.HistoryDiagnoseRepository
|
||||
import com.example.palmguardapp.di.Injection
|
||||
import com.example.palmguardapp.ui.detection.DetectionViewModel
|
||||
import com.example.palmguardapp.ui.home.HomeViewModel
|
||||
import com.example.palmguardapp.ui.listDisease.DiseaseViewModel
|
||||
|
||||
class ViewModelFactory private constructor(
|
||||
private val historyDiagnoseRepository: HistoryDiagnoseRepository,
|
||||
private val diseaseRepository: DiseaseRepository
|
||||
) : ViewModelProvider.NewInstanceFactory() {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return when {
|
||||
modelClass.isAssignableFrom(HomeViewModel::class.java) -> {
|
||||
HomeViewModel(historyDiagnoseRepository, diseaseRepository) as T
|
||||
}
|
||||
modelClass.isAssignableFrom(DetectionViewModel::class.java) -> {
|
||||
DetectionViewModel(historyDiagnoseRepository) as T
|
||||
}
|
||||
modelClass.isAssignableFrom(DiseaseViewModel::class.java) -> {
|
||||
DiseaseViewModel(diseaseRepository) as T
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var INSTANCE: ViewModelFactory? = null
|
||||
|
||||
fun getInstance(context: Context): ViewModelFactory {
|
||||
return INSTANCE ?: synchronized(this) {
|
||||
val historyDiagnoseRepository = Injection.provideDiagnoseRepository(context)
|
||||
val diseaseRepository = Injection.provideDiseaseRepository(context)
|
||||
ViewModelFactory(historyDiagnoseRepository, diseaseRepository).also {
|
||||
INSTANCE = it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.example.palmguardapp.ui.detection
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.example.palmguardapp.R
|
||||
import com.example.palmguardapp.data.local.entity.HistoryDiagnose
|
||||
import com.example.palmguardapp.databinding.FragmentDetectionBinding
|
||||
import com.example.palmguardapp.foundation.adapter.HistoryDiagnoseAdapter
|
||||
import com.example.palmguardapp.ui.ViewModelFactory
|
||||
import com.example.palmguardapp.ui.diagnose.DiagnoseDetailActivity
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class DetectionFragment : Fragment(R.layout.fragment_detection) {
|
||||
|
||||
private var _binding: FragmentDetectionBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val viewModel: DetectionViewModel by viewModels {
|
||||
ViewModelFactory.getInstance(requireContext())
|
||||
}
|
||||
|
||||
private val detectionAdapter = HistoryDiagnoseAdapter()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentDetectionBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setupRecyclerView()
|
||||
observeDetectionList()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
binding.rvResultDetection.layoutManager = LinearLayoutManager(requireContext())
|
||||
binding.rvResultDetection.adapter = detectionAdapter
|
||||
|
||||
detectionAdapter.setOnItemClickCallback(object : HistoryDiagnoseAdapter.OnItemClickCallback {
|
||||
override fun onItemClicked(data: HistoryDiagnose) {
|
||||
navigateToDiagnoseDetail(data)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun navigateToDiagnoseDetail(historyDiagnose: HistoryDiagnose) {
|
||||
val intent = Intent(requireActivity(), DiagnoseDetailActivity::class.java)
|
||||
intent.putExtra("HISTORY_DIAGNOSE", historyDiagnose)
|
||||
intent.putExtra("RETURN_FRAGMENT", "detection")
|
||||
startActivity(intent)
|
||||
}
|
||||
private fun observeDetectionList() {
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
viewModel.detectionList.collect { historyDiagnoses ->
|
||||
Log.d("DetectionFragment", "Observing detection list. Count: ${historyDiagnoses.size}")
|
||||
detectionAdapter.submitList(historyDiagnoses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.example.palmguardapp.ui.detection
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.palmguardapp.data.local.entity.HistoryDiagnose
|
||||
import com.example.palmguardapp.data.repository.HistoryDiagnoseRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class DetectionViewModel (private val historyDiagnoseRepository: HistoryDiagnoseRepository) : ViewModel() {
|
||||
|
||||
private val _detectionList = MutableSharedFlow<List<HistoryDiagnose>>()
|
||||
val detectionList : Flow<List<HistoryDiagnose>> = _detectionList.asSharedFlow()
|
||||
|
||||
init {
|
||||
getDetectionList()
|
||||
}
|
||||
|
||||
private fun getDetectionList() {
|
||||
viewModelScope.launch {
|
||||
historyDiagnoseRepository.getAllHistory().collect {
|
||||
_detectionList.emit(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package com.example.palmguardapp.ui.diagnose
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.example.palmguardapp.R
|
||||
import com.example.palmguardapp.data.local.entity.HistoryDiagnose
|
||||
import com.example.palmguardapp.databinding.ActivityDiagnoseBinding
|
||||
import com.example.palmguardapp.foundation.adapter.VPAdapter
|
||||
import com.example.palmguardapp.ui.listDisease.DiseaseDetailActivity
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
|
||||
class DiagnoseDetailActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityDiagnoseBinding
|
||||
private lateinit var historyDiagnose: HistoryDiagnose
|
||||
private lateinit var returnFragment : String
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContentView(R.layout.activity_diagnose)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
|
||||
binding = ActivityDiagnoseBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
historyDiagnose = intent.getParcelableExtra("HISTORY_DIAGNOSE")!!
|
||||
returnFragment = intent.getStringExtra("RETURN_FRAGMENT")!!
|
||||
|
||||
binding.tvTitle.text = historyDiagnose.name
|
||||
binding.ivImgTea.setImageURI(Uri.parse(historyDiagnose.imageUri))
|
||||
binding.tvConfidence.text = confidenceConverter(historyDiagnose.confidence)
|
||||
binding.viewPager.adapter = VPAdapter(this, historyDiagnose)
|
||||
binding.btnHsGallery.setOnClickListener {
|
||||
val bundle = Bundle().apply {
|
||||
putString("diseaseName", historyDiagnose.name)
|
||||
}
|
||||
val intent = Intent(this, DiseaseDetailActivity::class.java)
|
||||
intent.putExtras(bundle)
|
||||
startActivity(intent)
|
||||
}
|
||||
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
|
||||
when (position) {
|
||||
0 -> tab.text = "Diagnosa"
|
||||
1 -> tab.text = "Rekomendasi"
|
||||
}
|
||||
}.attach()
|
||||
|
||||
binding.dgsBack.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
override fun onBackPressed() {
|
||||
super.onBackPressed()
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
fun confidenceConverter(confidence: String): String {
|
||||
val confidenceValue = confidence.toDouble() * 100
|
||||
return if (confidenceValue % 1 == 0.0) {
|
||||
confidenceValue.toInt().toString() + "%"
|
||||
} else {
|
||||
String.format("%.1f", confidenceValue) + "%"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.example.palmguardapp.ui.diagnose
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.example.palmguardapp.databinding.FragmentDiagnoseBinding
|
||||
|
||||
class DiagnoseFragment : Fragment() {
|
||||
private var _binding: FragmentDiagnoseBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentDiagnoseBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val diagnosis = arguments?.getString(ARG_DIAGNOSIS) ?: ""
|
||||
binding.tvDiagnose.text = diagnosis
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ARG_DIAGNOSIS = "diagnosis"
|
||||
|
||||
fun newInstance(diagnosis: String): DiagnoseFragment {
|
||||
val fragment = DiagnoseFragment()
|
||||
val args = Bundle()
|
||||
args.putString(ARG_DIAGNOSIS, diagnosis)
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.example.palmguardapp.ui.diagnose
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.example.palmguardapp.databinding.FragmentRecommendationBinding
|
||||
|
||||
class RecommendationFragment : Fragment() {
|
||||
private var _binding: FragmentRecommendationBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentRecommendationBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val recommendation = arguments?.getString(ARG_RECOMMENDATION) ?: ""
|
||||
binding.tvRecommendation.text = recommendation
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ARG_RECOMMENDATION = "recommendation"
|
||||
|
||||
fun newInstance(recommendation: String): RecommendationFragment {
|
||||
val fragment = RecommendationFragment()
|
||||
val args = Bundle()
|
||||
args.putString(ARG_RECOMMENDATION, recommendation)
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.example.palmguardapp.ui.errorDetection
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.example.palmguardapp.R
|
||||
import com.example.palmguardapp.databinding.ActivityErrorDetectionBinding
|
||||
|
||||
class ErrorDetectionActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityErrorDetectionBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityErrorDetectionBinding.inflate(layoutInflater)
|
||||
enableEdgeToEdge()
|
||||
setContentView(binding.root)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
|
||||
binding.btErrorBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,312 @@
|
||||
package com.example.palmguardapp.ui.home
|
||||
|
||||
import ImageClassifier
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
import com.example.palmguardapp.foundation.utils.Result
|
||||
import android.net.Uri
|
||||
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.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.example.palmguardapp.R
|
||||
import com.example.palmguardapp.data.local.entity.HistoryDiagnose
|
||||
import com.example.palmguardapp.databinding.FragmentHomeBinding
|
||||
import com.example.palmguardapp.foundation.utils.saveImageToLocalStorage
|
||||
import com.example.palmguardapp.ui.ViewModelFactory
|
||||
import com.example.palmguardapp.ui.diagnose.DiagnoseDetailActivity
|
||||
import com.example.palmguardapp.ui.listDisease.DiseaseDetailActivity
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.yalantis.ucrop.UCrop
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class HomeFragment : Fragment(R.layout.fragment_home) {
|
||||
|
||||
private var _binding: FragmentHomeBinding? = null
|
||||
private val imageSize = 256
|
||||
private val binding get() = _binding!!
|
||||
private var lastDiagnosis: HistoryDiagnose? = null
|
||||
private val viewModel: HomeViewModel by viewModels {
|
||||
ViewModelFactory.getInstance(requireContext())
|
||||
}
|
||||
private val diseaseToId = mapOf(
|
||||
"Algal Leaf" to "D-001",
|
||||
"Anthracnose" to "D-002",
|
||||
"Bird Eye Spot" to "D-003",
|
||||
"Brown Blight" to "D-004",
|
||||
"Gray Light" to "D-005",
|
||||
"Red Leaf Spot" to "D-006",
|
||||
"White Spot" to "D-007",
|
||||
"Healthy" to "D-008"
|
||||
)
|
||||
|
||||
private lateinit var cameraLauncher: ActivityResultLauncher<Intent>
|
||||
private lateinit var galleryLauncher: ActivityResultLauncher<Intent>
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
cameraLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
val image = result.data?.extras?.get("data") as? Bitmap
|
||||
image?.let {
|
||||
val imageUri = saveImageToLocalStorage(requireContext(), it)
|
||||
startCrop(imageUri)
|
||||
}
|
||||
} else {
|
||||
showSnackbarError("Permission denied or image capture failed")
|
||||
}
|
||||
}
|
||||
|
||||
galleryLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
val selectedImageUri = result.data?.data
|
||||
selectedImageUri?.let {
|
||||
startCrop(it)
|
||||
}
|
||||
} else {
|
||||
showSnackbarError("Permission denied or image selection failed")
|
||||
}
|
||||
}
|
||||
|
||||
binding.btnHsCamera.setOnClickListener {
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
requireContext(),
|
||||
Manifest.permission.CAMERA
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
|
||||
cameraLauncher.launch(cameraIntent)
|
||||
} else {
|
||||
requestPermissions(arrayOf(Manifest.permission.CAMERA), 100)
|
||||
}
|
||||
}
|
||||
|
||||
binding.btnHsGallery.setOnClickListener {
|
||||
val galleryIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
|
||||
galleryLauncher.launch(galleryIntent)
|
||||
}
|
||||
|
||||
binding.cdHomeScreenAnalyze.setOnClickListener {
|
||||
lastDiagnosis?.let { diagnosis ->
|
||||
navigateToDiagnoseDetail(diagnosis)
|
||||
}
|
||||
}
|
||||
|
||||
binding.flHomeScreenListDisease.setOnClickListener {
|
||||
lifecycleScope.launch {
|
||||
viewModel.getDiseaseById("D-001")
|
||||
|
||||
viewModel.dataDisease.collect { result ->
|
||||
Log.d("flHomeScreen", result.toString())
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
val disease = result.data
|
||||
val bundle = Bundle().apply {
|
||||
putString("diseaseName", disease.diseaseName)
|
||||
putString("diseaseExplanation", disease.diseaseExplanation)
|
||||
putString("diseaseRecommendation", disease.diseaseRecommendation)
|
||||
putString("detailExplanation", disease.detailExplanation)
|
||||
putString("detailPrevention", disease.detailPrevention)
|
||||
putString("detailRecommendation", disease.detailRecommendation)
|
||||
}
|
||||
val intent = Intent(requireContext(), DiseaseDetailActivity::class.java)
|
||||
intent.putExtras(bundle)
|
||||
startActivity(intent)
|
||||
}
|
||||
is Result.Error -> {
|
||||
Toast.makeText(requireContext(), "Gagal mengambil data", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
Result.Loading -> TODO()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
viewModel.dataLastResult.collect { lastDiagnosis ->
|
||||
lastDiagnosis?.let {
|
||||
this@HomeFragment.lastDiagnosis = it
|
||||
updateResultUi(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
when (requestCode) {
|
||||
UCrop.REQUEST_CROP -> {
|
||||
val resultUri = UCrop.getOutput(data!!)
|
||||
resultUri?.let {
|
||||
val bitmap = MediaStore.Images.Media.getBitmap(requireContext().contentResolver, it)
|
||||
lifecycleScope.launch {
|
||||
classifyImage(bitmap)
|
||||
}
|
||||
}
|
||||
}
|
||||
UCrop.RESULT_ERROR -> {
|
||||
val cropError = UCrop.getError(data!!)
|
||||
cropError?.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun startCrop(uri: Uri) {
|
||||
val destinationUri = Uri.fromFile(File(requireContext().cacheDir, "${System.currentTimeMillis()}.jpg"))
|
||||
UCrop.of(uri, destinationUri)
|
||||
.withAspectRatio(1f, 1f)
|
||||
.withMaxResultSize(imageSize, imageSize)
|
||||
.start(requireContext(), this)
|
||||
}
|
||||
|
||||
private suspend fun classifyImage(image: Bitmap) {
|
||||
val classifier = ImageClassifier(requireContext())
|
||||
val result = classifier.classifyImage(image)
|
||||
|
||||
if(result != null) {
|
||||
val (diagnosis, confidence) = result
|
||||
Log.d("HomeFragment", "Diagnosis: $result")
|
||||
saveImageAndFetchData(diagnosis, confidence, image)
|
||||
} else {
|
||||
showSnackbarError("Gambar tidak sesuai, silahkan foto ulang")
|
||||
}
|
||||
}
|
||||
|
||||
private fun showSnackbarError(message: String) {
|
||||
Snackbar.make(binding.root, message, Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
private suspend fun saveImageAndFetchData(diagnosis: String, confidence: Float, image: Bitmap) {
|
||||
val imageUri = saveImageToLocalStorage(requireContext(), image)
|
||||
val formatter = SimpleDateFormat("dd-MMMM-yyyy", Locale("id", "ID"))
|
||||
val date = Date()
|
||||
val dateNow = formatter.format(date)
|
||||
val diseaseId = diseaseToId[diagnosis]
|
||||
// diseaseId?.let { id ->
|
||||
// viewModel.getDiseaseById(id)
|
||||
// viewModel.dataDisease.collect { result ->
|
||||
// when (result) {
|
||||
// is Result.Success -> {
|
||||
// val diseaseData = result.data
|
||||
// Log.d("HomeFragment", "Disease Data: $diseaseData")
|
||||
// val historyDiagnose = HistoryDiagnose(
|
||||
// name = diagnosis,
|
||||
// imageUri = imageUri.toString(),
|
||||
// diagnosis = diseaseData.data?.diseaseExplanation ?: "",
|
||||
// recommendation = diseaseData.data?.diseaseRecommendation ?: "",
|
||||
// confidence = confidence.toString(),
|
||||
// date = dateNow
|
||||
// )
|
||||
//
|
||||
// viewModel.saveDiagnose(historyDiagnose)
|
||||
// lastDiagnosis = historyDiagnose
|
||||
// Log.d("HomeFragment", "History Diagnose: $historyDiagnose")
|
||||
// binding.progressResult.visibility = View.GONE
|
||||
// restartFragment()
|
||||
// navigateToDiagnoseDetail(historyDiagnose)
|
||||
// }
|
||||
// is Result.Error -> {
|
||||
// // Handle error state
|
||||
// }
|
||||
// Result.Loading -> {
|
||||
// binding.progressResult.visibility = View.VISIBLE
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
diseaseId?.let { id ->
|
||||
viewModel.getDiseaseById(id)
|
||||
|
||||
viewLifecycleOwner.lifecycleScope.launch {
|
||||
viewModel.dataDisease.collect { result ->
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
val diseaseData = result.data
|
||||
Log.d("HomeFragment", "Disease Data: $diseaseData")
|
||||
|
||||
val historyDiagnose = HistoryDiagnose(
|
||||
name = diseaseData.diseaseName,
|
||||
imageUri = imageUri.toString(),
|
||||
diagnosis = diseaseData.diseaseExplanation,
|
||||
recommendation = diseaseData.diseaseRecommendation,
|
||||
confidence = confidence.toString(),
|
||||
date = dateNow
|
||||
)
|
||||
|
||||
viewModel.saveDiagnose(historyDiagnose)
|
||||
lastDiagnosis = historyDiagnose
|
||||
|
||||
Log.d("HomeFragment", "History Diagnose: $historyDiagnose")
|
||||
binding.progressResult.visibility = View.GONE
|
||||
restartFragment()
|
||||
navigateToDiagnoseDetail(historyDiagnose)
|
||||
}
|
||||
|
||||
is Result.Error -> {
|
||||
showSnackbarError("Gagal mengambil data penyakit dari database")
|
||||
}
|
||||
Result.Loading -> {
|
||||
binding.progressResult.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun restartFragment() {
|
||||
val fragmentManager = parentFragmentManager
|
||||
val fragmentTransaction = fragmentManager.beginTransaction()
|
||||
fragmentTransaction.detach(this).commitNow()
|
||||
fragmentTransaction.attach(this).commitNow()
|
||||
}
|
||||
|
||||
private fun navigateToDiagnoseDetail(historyDiagnose: HistoryDiagnose) {
|
||||
val intent = Intent(activity, DiagnoseDetailActivity::class.java)
|
||||
intent.putExtra("HISTORY_DIAGNOSE", historyDiagnose)
|
||||
intent.putExtra("RETURN_FRAGMENT", "home")
|
||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
private fun updateResultUi(historyDiagnose: HistoryDiagnose) {
|
||||
binding.imgResultDiagnosis.setImageURI(Uri.parse(historyDiagnose.imageUri))
|
||||
binding.titleResultDiagnosis.text = historyDiagnose.name
|
||||
val date = historyDiagnose.date.replace("-", " ")
|
||||
binding.dateResultDiagnosis.text = date
|
||||
binding.cdHomeScreenAnalyze.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.example.palmguardapp.ui.home
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.palmguardapp.data.local.entity.DiseaseDiagnose
|
||||
import com.example.palmguardapp.data.local.entity.HistoryDiagnose
|
||||
import com.example.palmguardapp.data.repository.DiseaseRepository
|
||||
import com.example.palmguardapp.data.repository.HistoryDiagnoseRepository
|
||||
import com.example.palmguardapp.foundation.utils.Result
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class HomeViewModel (
|
||||
private val historyDiagnoseRepository: HistoryDiagnoseRepository,
|
||||
private val diseaseRepository: DiseaseRepository
|
||||
) : ViewModel() {
|
||||
|
||||
private val _dataDisease = MutableSharedFlow<Result<DiseaseDiagnose>>()
|
||||
val dataDisease : Flow<Result<DiseaseDiagnose>> = _dataDisease.asSharedFlow()
|
||||
|
||||
private val _dataLastResult = MutableSharedFlow<HistoryDiagnose>()
|
||||
val dataLastResult : Flow<HistoryDiagnose> = _dataLastResult.asSharedFlow()
|
||||
|
||||
init {
|
||||
getLastHistory()
|
||||
}
|
||||
fun getDiseaseById(id: String) {
|
||||
viewModelScope.launch {
|
||||
diseaseRepository.getDiseaseById(id).collect{ disease ->
|
||||
_dataDisease.emit(Result.Success(disease))
|
||||
}
|
||||
}
|
||||
}
|
||||
suspend fun saveDiagnose(historyDiagnose: HistoryDiagnose) {
|
||||
viewModelScope.launch {
|
||||
historyDiagnoseRepository.insert(historyDiagnose)
|
||||
}
|
||||
}
|
||||
private fun getLastHistory() {
|
||||
viewModelScope.launch {
|
||||
historyDiagnoseRepository.getLastHistory().collect{
|
||||
_dataLastResult.emit(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package com.example.palmguardapp.ui.listDisease
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.bumptech.glide.Glide
|
||||
import com.example.palmguardapp.BuildConfig
|
||||
import com.example.palmguardapp.R
|
||||
import com.example.palmguardapp.data.local.entity.DiseaseDiagnose
|
||||
import com.example.palmguardapp.databinding.ActivityDiseaseDetailBinding
|
||||
import com.example.palmguardapp.foundation.utils.Result
|
||||
import com.example.palmguardapp.ui.ViewModelFactory
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class DiseaseDetailActivity : AppCompatActivity() {
|
||||
private val viewModel: DiseaseViewModel by viewModels {
|
||||
ViewModelFactory.getInstance(this)
|
||||
}
|
||||
private lateinit var binding: ActivityDiseaseDetailBinding
|
||||
private var diseaseName: String? = null
|
||||
private val diseaseToId = mapOf(
|
||||
"Brown Spots" to "D-001",
|
||||
"Healthy" to "D-002",
|
||||
"Brown Spots" to "D-003",
|
||||
"Healthy" to "D-004",
|
||||
"Brown Spots" to "D-005",
|
||||
"Healthy" to "D-006",
|
||||
"Brown Spots" to "D-007",
|
||||
"Healthy" to "D-008"
|
||||
)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
binding = ActivityDiseaseDetailBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
binding.dgsBack.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
val bundle = intent.extras
|
||||
Log.d("bundleObserve", bundle?.getString("id").toString())
|
||||
diseaseName = bundle?.getString("diseaseName")
|
||||
|
||||
observeViewModel()
|
||||
}
|
||||
|
||||
private fun setUpUi(diseaseDetail: DiseaseDiagnose?) {
|
||||
if(diseaseDetail?.diseaseName == "Brown Spots") {
|
||||
Glide.with(this)
|
||||
.load(R.drawable.dgs_wereng_img)
|
||||
.into(binding.imageDisease)
|
||||
} else {
|
||||
Glide.with(this)
|
||||
.load(R.drawable.upn_logo)
|
||||
.into(binding.imageDisease)
|
||||
}
|
||||
|
||||
binding.tvDescDisease.text = "Penjelasan Penyakit"
|
||||
binding.tvTitlePrevention.text = "Pencegahan"
|
||||
binding.tvTitleRecommended.text = "Rekomendasi Penanganan"
|
||||
binding.titleDisease.text = diseaseDetail?.diseaseName
|
||||
binding.descDisease.text = diseaseDetail?.detailExplanation
|
||||
binding.descPrevention.text = diseaseDetail?.detailPrevention
|
||||
binding.descRecommended.text = diseaseDetail?.detailRecommendation
|
||||
}
|
||||
|
||||
private fun observeViewModel() {
|
||||
lifecycleScope.launch {
|
||||
diseaseName?.let { diseaseToId[it]?.let { it1 -> viewModel.getDiseaseById(it1) } }
|
||||
viewModel.diseaseById.collect { result ->
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
binding.progressResult.visibility = android.view.View.GONE
|
||||
setUpUi(result.data)
|
||||
}
|
||||
is Result.Error -> {
|
||||
binding.progressResult.visibility = android.view.View.GONE
|
||||
Snackbar.make(
|
||||
binding.root,
|
||||
"Error loading data: ${result.error}",
|
||||
Snackbar.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
is Result.Loading -> {
|
||||
binding.progressResult.visibility = android.view.View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
super.onBackPressed()
|
||||
finish()
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.example.palmguardapp.ui.listDisease
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.palmguardapp.data.local.entity.DiseaseDiagnose
|
||||
import com.example.palmguardapp.data.repository.DiseaseRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import com.example.palmguardapp.foundation.utils.Result
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
|
||||
class DiseaseViewModel(private val diseaseRepository: DiseaseRepository) : ViewModel() {
|
||||
|
||||
private val _listDisease = MutableSharedFlow<Result<List<DiseaseDiagnose>>>()
|
||||
val listDisease: Flow<Result<List<DiseaseDiagnose>>> = _listDisease.asSharedFlow()
|
||||
|
||||
private val _diseaseById = MutableSharedFlow<Result<DiseaseDiagnose?>>()
|
||||
val diseaseById: Flow<Result<DiseaseDiagnose?>> = _diseaseById.asSharedFlow()
|
||||
|
||||
// fun getAllDisease() {
|
||||
// viewModelScope.launch {
|
||||
// _listDisease.emit(Result.Loading)
|
||||
// diseaseRepository.getAllDisease().collect { diseases ->
|
||||
// _listDisease.emit(Result.Success(diseases))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
fun getDiseaseById(id: String) {
|
||||
viewModelScope.launch {
|
||||
_diseaseById.emit(Result.Loading)
|
||||
diseaseRepository.getDiseaseById(id).collect { disease ->
|
||||
if (disease != null) {
|
||||
_diseaseById.emit(Result.Success(disease))
|
||||
} else {
|
||||
_diseaseById.emit(Result.Error("Penyakit tidak ditemukan di database lokal"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
app/src/main/ml/model.tflite
Normal file
BIN
app/src/main/res/drawable/back_button.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
7
app/src/main/res/drawable/bottom_nav_background.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners
|
||||
android:topLeftRadius="8dp"
|
||||
android:topRightRadius="8dp" />
|
||||
<solid android:color="@color/white" />
|
||||
</shape>
|
6
app/src/main/res/drawable/button_no_radius.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<!-- res/drawable/button_no_radius.xml -->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/primaryGreen" />
|
||||
<corners android:radius="0dp" />
|
||||
</shape>
|
BIN
app/src/main/res/drawable/dgs_wereng_img.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
app/src/main/res/drawable/diagnose_information_ic.png
Normal file
After Width: | Height: | Size: 659 B |
BIN
app/src/main/res/drawable/error_warning_ic_green.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
app/src/main/res/drawable/hs_camera_img.png
Normal file
After Width: | Height: | Size: 705 B |
BIN
app/src/main/res/drawable/hs_detail_explanation_img.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
app/src/main/res/drawable/hs_gallery_img.png
Normal file
After Width: | Height: | Size: 616 B |
BIN
app/src/main/res/drawable/hs_home_img.png
Normal file
After Width: | Height: | Size: 449 B |
BIN
app/src/main/res/drawable/hs_phone_analyze_img.png
Normal file
After Width: | Height: | Size: 952 B |
BIN
app/src/main/res/drawable/hs_phone_take_pic_img.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/drawable/hs_top_image.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable/hs_trace_black_img.png
Normal file
After Width: | Height: | Size: 337 B |
BIN
app/src/main/res/drawable/hs_wereng_img.png
Normal file
After Width: | Height: | Size: 12 KiB |
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
30
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
BIN
app/src/main/res/drawable/splash_screen_ic.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
app/src/main/res/drawable/upn_logo.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
app/src/main/res/font/poppins_bold.ttf
Normal file
BIN
app/src/main/res/font/poppins_medium.ttf
Normal file
BIN
app/src/main/res/font/poppins_regular.ttf
Normal file
BIN
app/src/main/res/font/poppins_semibold.ttf
Normal file
227
app/src/main/res/layout/activity_diagnose.xml
Normal file
@ -0,0 +1,227 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.diagnose.DiagnoseDetailActivity">
|
||||
|
||||
<!-- <LinearLayout-->
|
||||
<!-- android:id="@+id/ll_ds"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginHorizontal="30dp"-->
|
||||
<!-- android:orientation="vertical"-->
|
||||
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toTopOf="parent">-->
|
||||
|
||||
<!-- <ImageView-->
|
||||
<!-- android:id="@+id/dgs_back"-->
|
||||
<!-- android:layout_width="32dp"-->
|
||||
<!-- android:layout_height="32dp"-->
|
||||
<!-- android:layout_marginTop="35dp"-->
|
||||
<!-- android:layout_marginBottom="15dp"-->
|
||||
<!-- android:src="@drawable/ds_back_arrow_img" />-->
|
||||
|
||||
<!-- <LinearLayout-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:orientation="horizontal">-->
|
||||
<!-- <TextView-->
|
||||
<!-- android:id="@+id/tv_title"-->
|
||||
<!-- style="@style/ActivityDiagnoseDiseaseName"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- tools:text="Algal Leaf" />-->
|
||||
|
||||
<!-- <TextView-->
|
||||
<!-- android:id="@+id/tv_confidence"-->
|
||||
<!-- style="@style/ActivityDiagnoseDiseaseName"-->
|
||||
<!-- android:layout_marginStart="10dp"-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:text="80%" />-->
|
||||
<!-- </LinearLayout>-->
|
||||
|
||||
<!-- <com.google.android.material.card.MaterialCardView-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content">-->
|
||||
|
||||
<!-- <ImageView-->
|
||||
<!-- android:id="@+id/iv_img_tea"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="200dp"-->
|
||||
<!-- android:scaleType="fitXY"-->
|
||||
<!-- tools:src="@drawable/dgs_wereng_img" />-->
|
||||
<!-- </com.google.android.material.card.MaterialCardView>-->
|
||||
|
||||
<!-- <com.google.android.material.tabs.TabLayout-->
|
||||
<!-- android:id="@+id/tab_layout"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginVertical="8dp"-->
|
||||
<!-- app:tabSelectedTextColor="@color/primaryGreen"-->
|
||||
<!-- app:tabIndicatorColor="@color/primaryGreen"-->
|
||||
<!-- android:background="@color/grayBackground"-->
|
||||
<!-- app:layout_constraintTop_toBottomOf="@+id/img">-->
|
||||
|
||||
<!-- <com.google.android.material.tabs.TabItem-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content" />-->
|
||||
|
||||
<!-- <com.google.android.material.tabs.TabItem-->
|
||||
<!-- android:layout_width="wrap_content"-->
|
||||
<!-- android:layout_height="wrap_content" />-->
|
||||
<!-- </com.google.android.material.tabs.TabLayout>-->
|
||||
|
||||
<!-- <androidx.viewpager2.widget.ViewPager2-->
|
||||
<!-- android:id="@+id/view_pager"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||
<!-- app:layout_constraintHorizontal_bias="0.0"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toBottomOf="@id/tab_layout"-->
|
||||
<!-- app:layout_constraintVertical_bias="1.0" />-->
|
||||
<!-- </LinearLayout>-->
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dgs_back"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginTop="@dimen/margin_screen"
|
||||
android:layout_marginStart="@dimen/margin_screen"
|
||||
android:src="@drawable/back_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/ds_mci"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:cardPreventCornerOverlap="false"
|
||||
app:cardUseCompatPadding="false"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/dgs_back">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_img_tea"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:scaleType="fitXY"
|
||||
tools:src="@drawable/dgs_wereng_img" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/ds_cont_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:background="@color/primaryGreen"
|
||||
android:paddingHorizontal="5dp"
|
||||
android:paddingVertical="10dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/ds_mci">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Brown Spots" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_confidence_desc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:text="Confidence: "
|
||||
android:textColor="@color/primaryGreen"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/ds_cont_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_confidence"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="80%"
|
||||
android:textColor="@color/primaryGreen"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tv_confidence_desc"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_confidence_desc"
|
||||
app:layout_constraintTop_toTopOf="@id/tv_confidence_desc" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:background="@color/white"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_confidence_desc"
|
||||
app:tabIndicatorColor="@color/primaryGreen"
|
||||
app:tabSelectedTextColor="@color/primaryGreen">
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tab_layout"
|
||||
app:layout_constraintVertical_bias="1.0" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_hs_gallery"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/button_no_radius"
|
||||
android:fontFamily="@font/poppins_medium"
|
||||
android:gravity="center"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:layout_marginBottom="@dimen/margin_screen"
|
||||
android:paddingVertical="14dp"
|
||||
android:text="Informasi Selengkapnya"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:icon="@drawable/diagnose_information_ic"
|
||||
app:iconGravity="textStart"
|
||||
app:iconTint="@color/white"
|
||||
app:iconSize="25dp"
|
||||
app:iconPadding="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
151
app/src/main/res/layout/activity_disease_detail.xml
Normal file
@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/main"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:context=".ui.listDisease.DiseaseDetailActivity">
|
||||
<ImageView
|
||||
android:id="@+id/dgs_back"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_screen"
|
||||
android:layout_marginStart="@dimen/margin_screen"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:src="@drawable/back_button"/>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
app:layout_constraintTop_toBottomOf="@id/dgs_back"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<ImageView
|
||||
android:id="@+id/image_disease"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="185dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:src="@drawable/dgs_wereng_img"/>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/dd_cont_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:background="@color/primaryGreen"
|
||||
android:paddingHorizontal="5dp"
|
||||
android:paddingVertical="10dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/image_disease">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_disease"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Brown Spots" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_desc_disease"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Penjelasan Penyakit"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:textColor="@color/primaryGreen"
|
||||
app:layout_constraintTop_toBottomOf="@+id/dd_cont_title"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/desc_disease"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:justificationMode="inter_word"
|
||||
tools:text="deskripsi penyakit"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_desc_disease"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title_prevention"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Pencegahan"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:textColor="@color/primaryGreen"
|
||||
app:layout_constraintTop_toBottomOf="@+id/desc_disease"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/desc_prevention"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="deskripsi pencegahan"
|
||||
android:justificationMode="inter_word"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_title_prevention"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title_recommended"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Rekomendasi Penanganan"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:textColor="@color/primaryGreen"
|
||||
app:layout_constraintTop_toBottomOf="@+id/desc_prevention"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/desc_recommended"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="desc Penanganan"
|
||||
android:justificationMode="inter_word"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_title_recommended"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_result"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="invisible"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
93
app/src/main/res/layout/activity_error_detection.xml
Normal file
@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.errorDetection.ErrorDetectionActivity">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/bt_error_back"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/back_button"
|
||||
android:layout_marginTop="@dimen/margin_screen"
|
||||
android:layout_marginStart="@dimen/margin_screen"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:src="@drawable/error_warning_ic_green"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/ds_cont_title" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/ds_cont_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:background="@color/primaryGreen"
|
||||
android:paddingHorizontal="5dp"
|
||||
android:paddingVertical="10dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/bt_error_back">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Kesalahan Deteksi" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:justificationMode="inter_word"
|
||||
android:text="Lorem ipsum, dolor sit amet consectetur adipisicing elit. Impedit eos illo cupiditate, placeat odit dicta similique expedita enim in suscipit, tenetur hic aliquam ad fugiat quaerat."
|
||||
android:textColor="@color/black"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/imageView" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/es_btn_redo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/button_no_radius"
|
||||
android:fontFamily="@font/poppins_medium"
|
||||
android:gravity="center"
|
||||
android:layout_marginHorizontal="@dimen/margin_screen"
|
||||
android:layout_marginBottom="@dimen/margin_screen"
|
||||
android:paddingVertical="14dp"
|
||||
android:text="Ambil Gambar Ulang"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:icon="@drawable/diagnose_information_ic"
|
||||
app:iconGravity="textStart"
|
||||
app:iconTint="@color/white"
|
||||
app:iconSize="25dp"
|
||||
app:iconPadding="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
42
app/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white"
|
||||
tools:context=".ui.MainActivity">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/frame_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/ma_cv_nav_menu_bg"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/ma_cv_nav_menu_bg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/bottomNavigationView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:backgroundTint="@color/white"
|
||||
app:menu="@menu/bottom_nav"/>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
32
app/src/main/res/layout/activity_splash_screen.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white"
|
||||
tools:context=".ui.SplashScreenActivity">
|
||||
|
||||
<de.hdodenhof.circleimageview.CircleImageView
|
||||
android:id="@+id/circleImageView"
|
||||
android:layout_width="180dp"
|
||||
android:layout_height="180dp"
|
||||
android:src="@drawable/splash_screen_ic"
|
||||
app:civ_border_color="@color/grayBackground"
|
||||
app:civ_border_width="2dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="55dp"
|
||||
android:layout_height="55dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:src="@drawable/upn_logo"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
62
app/src/main/res/layout/fragment_detection.xml
Normal file
@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.detection.DetectionFragment">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="25dp"
|
||||
android:paddingBottom="20dp"
|
||||
android:paddingHorizontal="20dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/dd_cont_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_screen"
|
||||
android:background="@color/primaryGreen"
|
||||
android:paddingHorizontal="5dp"
|
||||
android:paddingVertical="10dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_disease"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:text="Riwayat Deteksi" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_ds"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/margin_component"
|
||||
app:layout_constraintTop_toBottomOf="@id/dd_cont_title">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_result_detection"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:listitem="@layout/item_result" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
|
||||
</ScrollView>
|
16
app/src/main/res/layout/fragment_diagnose.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.diagnose.DiagnoseFragment">
|
||||
|
||||
<!-- TODO: Update blank fragment layout -->
|
||||
<TextView
|
||||
android:id="@+id/tv_diagnose"
|
||||
style="@style/FragmentDiagnoseDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Penyakit Algal Leaf disebabkan oleh alga hijau Cephaleuros virescens yang menyerang daun teh, menyebabkan bintik-bintik hijau kusam atau oranye pada daun." />
|
||||
|
||||
</FrameLayout>
|
436
app/src/main/res/layout/fragment_home.xml
Normal file
@ -0,0 +1,436 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.home.HomeFragment">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="25dp"
|
||||
android:paddingBottom="20dp"
|
||||
android:paddingHorizontal="20dp">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cv_headline_top"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:cardBackgroundColor="@color/white"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:strokeColor="@color/greenGeneral">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_headline_top"
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/margin_component"
|
||||
android:text="SEMBUHKAN TANAMAN SAWIT ANDA!"
|
||||
android:textColor="@color/greenGeneral"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="78dp"
|
||||
android:layout_height="78dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/hs_top_image"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<!-- Jangan lupa tambahin constraint -->
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cv_tutorial"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
android:backgroundTint="@color/white"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cv_headline_top"
|
||||
app:strokeColor="@color/greenGeneral">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="@dimen/margin_component">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_hs_phone_take_pic"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:src="@drawable/hs_phone_take_pic_img"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_hs_phone_take_pic"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:text="Ambil Gambar"
|
||||
android:textColor="@color/greenGeneral"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/iv_hs_phone_take_pic" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_hs_down_arrow"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:rotation="270"
|
||||
android:src="@drawable/back_button"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_hs_phone_take_pic" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_hs_phone_analyze"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:src="@drawable/hs_phone_analyze_img"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/iv_hs_down_arrow" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_hs_phone_analyze"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Ambil Gambar"
|
||||
android:textColor="@color/greenGeneral"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/iv_hs_phone_analyze" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/btn_hs_camera"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="90dp"
|
||||
android:backgroundTint="@color/white"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/cv_tutorial"
|
||||
app:strokeColor="@color/greenGeneral">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="@dimen/margin_component">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tv_camera_img"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/hs_camera_img"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Gunakan Kamera"
|
||||
android:textColor="@color/greenGeneral"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_camera_img" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/btn_hs_gallery"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="90dp"
|
||||
android:backgroundTint="@color/greenGeneral"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/cv_tutorial"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:strokeColor="@color/greenGeneral">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="@dimen/margin_component">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tv_gallery_img"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/hs_gallery_img"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Ambil Dari Galeri"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_gallery_img" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
|
||||
<!-- <Button-->
|
||||
<!-- android:id="@+id/btn_hs_camera"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="50dp"-->
|
||||
<!-- android:layout_marginTop="20dp"-->
|
||||
<!-- android:backgroundTint="@color/primaryGreen"-->
|
||||
<!-- android:text="Gunakan Kamera"-->
|
||||
<!-- android:textColor="@color/black"-->
|
||||
<!-- android:textSize="16sp"-->
|
||||
<!-- android:textStyle="bold"-->
|
||||
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toBottomOf="@+id/cv_headline" />-->
|
||||
|
||||
<!-- <Button-->
|
||||
<!-- android:id="@+id/btn_hs_gallery"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginTop="10dp"-->
|
||||
<!-- android:backgroundTint="@color/primaryGreen"-->
|
||||
<!-- android:text="Ambil dari Galeri"-->
|
||||
<!-- android:textColor="@color/white"-->
|
||||
<!-- android:textSize="16sp"-->
|
||||
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toBottomOf="@+id/bt_use_camera" />-->
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cv_hs_detail_explanation_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:cardBackgroundColor="@color/white"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/cv_tutorial"
|
||||
app:strokeColor="@color/greenGeneral">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_headline_sickness_explanation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/margin_component"
|
||||
android:text="Baca Tentang Penyakit Brown Spots Pada Daun Tanaman Sawit"
|
||||
android:textColor="@color/greenGeneral"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cv_hs_detail_explanation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:strokeColor="@color/greenGeneral"
|
||||
android:backgroundTint="@color/greenGeneral"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/cv_hs_detail_explanation_title">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<ImageView
|
||||
android:id="@+id/iv_hs_detail_explanation"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="100dp"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/hs_detail_explanation_img"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/fl_home_screen_list_disease"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:strokeColor="@color/white"
|
||||
android:backgroundTint="@color/greenGeneral"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/iv_hs_detail_explanation">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
|
||||
android:text="Klik Di sini"
|
||||
android:textColor="@color/white" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/cv_hs_history_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:cardBackgroundColor="@color/white"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/cv_hs_detail_explanation"
|
||||
app:strokeColor="@color/greenGeneral">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_history_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/margin_component"
|
||||
android:layout_gravity="center"
|
||||
android:text="Hasil Analisis Terakhir"
|
||||
android:textColor="@color/greenGeneral"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/cd_home_screen_analyze"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:visibility="gone"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:strokeColor="@color/greenGeneral"
|
||||
app:strokeWidth="1dp"
|
||||
android:layout_marginTop="@dimen/margin_component"
|
||||
app:layout_constraintTop_toBottomOf="@+id/cv_hs_history_title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/rl_home_screen_card_analyze"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="25dp"
|
||||
android:paddingVertical="20dp">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/card_result_diagnosis"
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="75dp"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img_result_diagnosis"
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="75dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/hs_wereng_img" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/date_result_diagnosis"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="11 November 2023"
|
||||
android:layout_marginStart="@dimen/margin_component"
|
||||
android:textColor="@color/grayFont"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toEndOf="@id/card_result_diagnosis"
|
||||
app:layout_constraintTop_toTopOf="@id/card_result_diagnosis" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_result_diagnosis"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/date_result_diagnosis"
|
||||
android:text="Algal Leaf"
|
||||
android:textColor="@color/greenGeneral"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/date_result_diagnosis"
|
||||
app:layout_constraintStart_toStartOf="@id/date_result_diagnosis"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/confidence_result_diagnosis"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/title_result_diagnosis"
|
||||
android:text="Confidence: "
|
||||
android:textColor="@color/grayFont"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/title_result_diagnosis"
|
||||
app:layout_constraintStart_toStartOf="@id/title_result_diagnosis"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img_arrow2"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_below="@id/date_result_diagnosis"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:contentDescription="TODO"
|
||||
android:scaleType="fitXY"
|
||||
android:rotation="180"
|
||||
android:src="@drawable/back_button"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_result"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
16
app/src/main/res/layout/fragment_recommendation.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.diagnose.RecommendationFragment">
|
||||
|
||||
<!-- TODO: Update blank fragment layout -->
|
||||
<TextView
|
||||
android:id="@+id/tv_recommendation"
|
||||
style="@style/FragmentRecommendationDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Pangkas dan buang daun yang terinfeksi, pastikan tanaman mendapatkan sirkulasi udara yang baik, dan gunakan fungisida berbasis tembaga jika diperlukan." />
|
||||
|
||||
</FrameLayout>
|
88
app/src/main/res/layout/item_result.xml
Normal file
@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/cd_home_screen_analyze"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:strokeColor="@color/greenGeneral"
|
||||
app:strokeWidth="1dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/rl_home_screen_card_analyze"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="25dp"
|
||||
android:paddingVertical="20dp">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/card_result_diagnosis"
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="75dp"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img_result_diagnosis"
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="75dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/hs_wereng_img" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/date_result_diagnosis"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="11 November 2023"
|
||||
android:layout_marginStart="@dimen/margin_component"
|
||||
android:textColor="@color/grayFont"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toEndOf="@id/card_result_diagnosis"
|
||||
app:layout_constraintTop_toTopOf="@id/card_result_diagnosis" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_result_diagnosis"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/date_result_diagnosis"
|
||||
android:text="Algal Leaf"
|
||||
android:textColor="@color/greenGeneral"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/date_result_diagnosis"
|
||||
app:layout_constraintStart_toStartOf="@id/date_result_diagnosis"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/confidence_result_diagnosis"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/title_result_diagnosis"
|
||||
android:text="Confidence: "
|
||||
android:textColor="@color/grayFont"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/title_result_diagnosis"
|
||||
app:layout_constraintStart_toStartOf="@id/title_result_diagnosis"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img_arrow2"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_below="@id/date_result_diagnosis"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:contentDescription="TODO"
|
||||
android:scaleType="fitXY"
|
||||
android:rotation="180"
|
||||
android:src="@drawable/back_button"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
11
app/src/main/res/menu/bottom_nav.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/home"
|
||||
android:icon="@drawable/hs_home_img"
|
||||
android:title="Beranda" />
|
||||
<item
|
||||
android:id="@+id/detection"
|
||||
android:icon="@drawable/hs_trace_black_img"
|
||||
android:title="Deteksi" />
|
||||
</menu>
|
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 7.6 KiB |
17
app/src/main/res/values-v26/themes.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="FragmentDiagnoseDescription">
|
||||
<item name="fontFamily">@font/poppins_medium</item>
|
||||
<item name="android:justificationMode">inter_word</item>
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:layout_marginBottom">25dp</item>
|
||||
</style>
|
||||
|
||||
<style name="FragmentRecommendationDescription">
|
||||
<item name="fontFamily">@font/poppins_medium</item>
|
||||
<item name="android:justificationMode">inter_word</item>
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:layout_marginBottom">25dp</item>
|
||||
</style>
|
||||
</resources>
|
10
app/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="grayBackground">#EEEEEE</color>
|
||||
<color name="grayBackgroundCard">#F1F2F2</color>
|
||||
<color name="grayFont">#AEAEAE</color>
|
||||
<color name="greenGeneral">#d2eac1</color>
|
||||
<color name="primaryGreen">#d2eac1</color>
|
||||
</resources>
|
7
app/src/main/res/values/dimens.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="padding_horizontal">30dp</dimen>
|
||||
<dimen name="padding_vertical_top">60dp</dimen>
|
||||
<dimen name="margin_screen">20dp</dimen>
|
||||
<dimen name="margin_component">15dp</dimen>
|
||||
</resources>
|
7
app/src/main/res/values/splash.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="Theme.MyApp.MySplash" parent="Theme.SplashScreen">
|
||||
<item name="windowSplashScreenBackground">@color/white</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@drawable/splash_screen_ic</item>
|
||||
</style>
|
||||
</resources>
|
7
app/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<resources>
|
||||
<string name="app_name">PalmGuard</string>
|
||||
<!-- TODO: Remove or change this placeholder text -->
|
||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||
<string name="ig_teaguard">@teaguardteam</string>
|
||||
|
||||
</resources>
|
115
app/src/main/res/values/themes.xml
Normal file
@ -0,0 +1,115 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Base.Theme.TeaGuard" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<!-- Customize your light theme here. -->
|
||||
<item name="colorPrimary">@color/primaryGreen</item>
|
||||
<item name="android:windowBackground">@color/white</item>
|
||||
<item name="bottomNavigationStyle">@style/Widget.App.BottomNavigationView</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.App.BottomNavigationView" parent="Widget.MaterialComponents.BottomNavigationView.Colored">
|
||||
<item name="materialThemeOverlay">@style/ThemeOverlay.App.BottomNavigationView</item>
|
||||
</style>
|
||||
|
||||
<style name="ThemeOverlay.App.BottomNavigationView" parent="">
|
||||
<item name="colorOnPrimary">@color/black</item>
|
||||
</style>
|
||||
<style name="NavigationCardView" parent="@style/Widget.MaterialComponents.CardView">
|
||||
<item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.MaterialCardView.Cut</item>
|
||||
<item name="strokeWidth">0dp</item>
|
||||
</style>
|
||||
<style name="ButtonGeneral" parent="@style/ShapeAppearanceOverlay.Material3.Corner.Bottom">
|
||||
<item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.Material3.CustomCut</item>
|
||||
</style>
|
||||
|
||||
<style name="ShapeAppearanceOverlay.Material3.CustomCut" parent="">
|
||||
<item name="cornerSize">8dp</item>
|
||||
</style>
|
||||
<style name="ShapeAppearanceOverlay.MaterialCardView.Cut" parent="">
|
||||
<item name="cornerSizeTopRight">8dp</item>
|
||||
<item name="cornerSizeTopLeft">8dp</item>
|
||||
<item name="cornerSizeBottomRight">0dp</item>
|
||||
<item name="cornerSizeBottomLeft">0dp</item>
|
||||
</style>
|
||||
|
||||
<!-- DIAGNOSE ACTIVITY START -->
|
||||
|
||||
<style name="ActivityDiagnoseDiseaseName">
|
||||
<item name="fontFamily">@font/poppins_regular</item>
|
||||
<item name="android:textAlignment">center</item>
|
||||
<item name="android:textSize">24sp</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:textColor">@color/black</item>
|
||||
<item name="android:layout_marginBottom">25dp</item>
|
||||
</style>
|
||||
|
||||
<!-- DIAGNOSE ACTIVITY END -->
|
||||
|
||||
<!-- DETECTION FRAGMENT START -->
|
||||
|
||||
<style name="FragmentDetectionTitle">
|
||||
<item name="fontFamily">@font/poppins_bold</item>
|
||||
<item name="android:textAlignment">center</item>
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:textColor">@color/black</item>
|
||||
<item name="android:layout_marginBottom">25dp</item>
|
||||
</style>
|
||||
|
||||
<style name="FragmentDetectionCardDate">
|
||||
<item name="fontFamily">@font/poppins_regular</item>
|
||||
<item name="android:textColor">@color/grayFont</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
<style name="FragmentDetectionCardDiseaseTitle">
|
||||
<item name="fontFamily">@font/poppins_regular</item>
|
||||
<item name="android:textColor">@color/primaryGreen</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<!-- DETECTION FRAGMENT END -->
|
||||
|
||||
<!-- HOME FRAGMENT START -->
|
||||
|
||||
<style name="FragmentHomeTitle">
|
||||
<item name="fontFamily">@font/poppins_regular</item>
|
||||
<item name="android:layout_marginBottom">24dp</item>
|
||||
<item name="android:textSize">18sp</item>
|
||||
<item name="android:textColor">@color/black</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<style name="FragmentHomeCardTutorial">
|
||||
<item name="fontFamily">@font/poppins_regular</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textAlignment">center</item>
|
||||
</style>
|
||||
|
||||
<style name="FragmentHomeAnalyzeTitle">
|
||||
<item name="fontFamily">@font/poppins_regular</item>
|
||||
<item name="android:layout_marginTop">14dp</item>
|
||||
<item name="android:layout_marginBottom">14dp</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textColor">@color/black</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<style name="FragmentHomeCardDate">
|
||||
<item name="fontFamily">@font/poppins_regular</item>
|
||||
<item name="android:textColor">@color/grayFont</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
<style name="FragmentHomeCardDiseaseTitle">
|
||||
<item name="fontFamily">@font/poppins_regular</item>
|
||||
<item name="android:textColor">@color/primaryGreen</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
<!-- HOME FRAGMENT END -->
|
||||
|
||||
<style name="Theme.TeaGuard" parent="Base.Theme.TeaGuard" />
|
||||
</resources>
|
13
app/src/main/res/xml/backup_rules.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Sample backup rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/guide/topics/data/autobackup
|
||||
for details.
|
||||
Note: This file is ignored for devices older that API 31
|
||||
See https://developer.android.com/about/versions/12/backup-restore
|
||||
-->
|
||||
<full-backup-content>
|
||||
<!--
|
||||
<include domain="sharedpref" path="."/>
|
||||
<exclude domain="sharedpref" path="device.xml"/>
|
||||
-->
|
||||
</full-backup-content>
|
19
app/src/main/res/xml/data_extraction_rules.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Sample data extraction rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||
for details.
|
||||
-->
|
||||
<data-extraction-rules>
|
||||
<cloud-backup>
|
||||
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
-->
|
||||
</cloud-backup>
|
||||
<!--
|
||||
<device-transfer>
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
</device-transfer>
|
||||
-->
|
||||
</data-extraction-rules>
|
@ -0,0 +1,17 @@
|
||||
package com.example.palmguardapp
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|