diff --git a/Work1/WON/FeelingApplication/.gitignore b/Work1/WON/FeelingApplication/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/Work1/WON/FeelingApplication/.gitignore
@@ -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
diff --git a/Work1/WON/FeelingApplication/.idea/.gitignore b/Work1/WON/FeelingApplication/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Work1/WON/FeelingApplication/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Work1/WON/FeelingApplication/.idea/compiler.xml b/Work1/WON/FeelingApplication/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/Work1/WON/FeelingApplication/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/.idea/deploymentTargetSelector.xml b/Work1/WON/FeelingApplication/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/Work1/WON/FeelingApplication/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/.idea/gradle.xml b/Work1/WON/FeelingApplication/.idea/gradle.xml
new file mode 100644
index 0000000..7b3006b
--- /dev/null
+++ b/Work1/WON/FeelingApplication/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/.idea/kotlinc.xml b/Work1/WON/FeelingApplication/.idea/kotlinc.xml
new file mode 100644
index 0000000..fdf8d99
--- /dev/null
+++ b/Work1/WON/FeelingApplication/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/.idea/migrations.xml b/Work1/WON/FeelingApplication/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/Work1/WON/FeelingApplication/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/.idea/misc.xml b/Work1/WON/FeelingApplication/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/Work1/WON/FeelingApplication/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/.idea/runConfigurations.xml b/Work1/WON/FeelingApplication/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/Work1/WON/FeelingApplication/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/Group 462 (1).svg b/Work1/WON/FeelingApplication/Group 462 (1).svg
new file mode 100644
index 0000000..96c0a01
--- /dev/null
+++ b/Work1/WON/FeelingApplication/Group 462 (1).svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/Group 462 (2).svg b/Work1/WON/FeelingApplication/Group 462 (2).svg
new file mode 100644
index 0000000..33e9b0a
--- /dev/null
+++ b/Work1/WON/FeelingApplication/Group 462 (2).svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/Group 462 (3).svg b/Work1/WON/FeelingApplication/Group 462 (3).svg
new file mode 100644
index 0000000..532ece1
--- /dev/null
+++ b/Work1/WON/FeelingApplication/Group 462 (3).svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/Group 462 (4).svg b/Work1/WON/FeelingApplication/Group 462 (4).svg
new file mode 100644
index 0000000..8c74506
--- /dev/null
+++ b/Work1/WON/FeelingApplication/Group 462 (4).svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/Group 462.svg b/Work1/WON/FeelingApplication/Group 462.svg
new file mode 100644
index 0000000..d2bb709
--- /dev/null
+++ b/Work1/WON/FeelingApplication/Group 462.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/app/.gitignore b/Work1/WON/FeelingApplication/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/build.gradle.kts b/Work1/WON/FeelingApplication/app/build.gradle.kts
new file mode 100644
index 0000000..6655307
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/build.gradle.kts
@@ -0,0 +1,50 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.feelingapplication"
+ compileSdk = 34
+
+ defaultConfig {
+ applicationId = "com.example.feelingapplication"
+ minSdk = 24
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+dependencies {
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.activity)
+ implementation(libs.androidx.constraintlayout)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/proguard-rules.pro b/Work1/WON/FeelingApplication/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/androidTest/java/com/example/feelingapplication/ExampleInstrumentedTest.kt b/Work1/WON/FeelingApplication/app/src/androidTest/java/com/example/feelingapplication/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..1109913
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/androidTest/java/com/example/feelingapplication/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.feelingapplication
+
+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.feelingapplication", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/AndroidManifest.xml b/Work1/WON/FeelingApplication/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..f39d207
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/AndroidManifest.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity.kt b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity.kt
new file mode 100644
index 0000000..db8010a
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity.kt
@@ -0,0 +1,78 @@
+package com.example.feelingapplication
+
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import android.widget.Button
+import android.widget.ImageButton
+import android.widget.ImageView
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+import kotlin.reflect.KProperty
+
+class MainActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ setContentView(R.layout.activity_main)
+
+ val imageButton = findViewById(R.id.imageButton)
+ val imageButton2 = findViewById(R.id.imageButton2)
+ val imageButton3 = findViewById(R.id.imageButton3)
+ val imageButton4 = findViewById(R.id.imageButton4)
+ val imageButton5 = findViewById(R.id.imageButton5)
+
+ //페이지 이동
+ fun moveToAnotherPage1() {
+ val intent = Intent(this, MainActivity2::class.java)
+ startActivity(intent)
+ }
+
+ fun moveToAnotherPage2() {
+ val intent = Intent(this, MainActivity3::class.java)
+ startActivity(intent)
+ }
+
+ fun moveToAnotherPage3() {
+ val intent = Intent(this, MainActivity4::class.java)
+ startActivity(intent)
+ }
+
+ fun moveToAnotherPage4() {
+ val intent = Intent(this, MainActivity5::class.java)
+ startActivity(intent)
+ }
+
+ fun moveToAnotherPage5() {
+ val intent = Intent(this, MainActivity6::class.java)
+ startActivity(intent)
+ }
+
+ //함수 호출
+ imageButton.setOnClickListener {
+ moveToAnotherPage1()
+ }
+ imageButton2.setOnClickListener {
+ moveToAnotherPage2()
+ }
+ imageButton3.setOnClickListener {
+ moveToAnotherPage3()
+ }
+ imageButton4.setOnClickListener {
+ moveToAnotherPage4()
+ }
+ imageButton5.setOnClickListener {
+ moveToAnotherPage5()
+ }
+
+ 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
+ }
+ }
+}
+
diff --git a/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity2.kt b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity2.kt
new file mode 100644
index 0000000..270ccb1
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity2.kt
@@ -0,0 +1,21 @@
+package com.example.feelingapplication
+
+import android.os.Bundle
+import android.view.View
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+
+class MainActivity2 : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ this.enableEdgeToEdge()
+ setContentView(R.layout.activity_main2)
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v: View, insets: WindowInsetsCompat ->
+ val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
+ insets
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity3.kt b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity3.kt
new file mode 100644
index 0000000..e5de85a
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity3.kt
@@ -0,0 +1,25 @@
+package com.example.feelingapplication
+
+import android.content.Intent
+import android.os.Bundle
+import android.widget.Button
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+import androidx.lifecycle.ReportFragment.Companion.reportFragment
+
+class MainActivity3 : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ setContentView(R.layout.activity_main3)
+
+ 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
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity4.kt b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity4.kt
new file mode 100644
index 0000000..2f77a29
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity4.kt
@@ -0,0 +1,20 @@
+package com.example.feelingapplication
+
+import android.os.Bundle
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+
+class MainActivity4 : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ setContentView(R.layout.activity_main4)
+ 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
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity5.kt b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity5.kt
new file mode 100644
index 0000000..78b8295
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity5.kt
@@ -0,0 +1,20 @@
+package com.example.feelingapplication
+
+import android.os.Bundle
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+
+class MainActivity5 : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ setContentView(R.layout.activity_main5)
+ 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
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity6.kt b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity6.kt
new file mode 100644
index 0000000..0404b5f
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/java/com/example/feelingapplication/MainActivity6.kt
@@ -0,0 +1,20 @@
+package com.example.feelingapplication
+
+import android.os.Bundle
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+
+class MainActivity6 : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ setContentView(R.layout.activity_main6)
+ 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
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/drawable/angry.xml b/Work1/WON/FeelingApplication/app/src/main/res/drawable/angry.xml
new file mode 100644
index 0000000..5377e99
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/drawable/angry.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/drawable/excited.xml b/Work1/WON/FeelingApplication/app/src/main/res/drawable/excited.xml
new file mode 100644
index 0000000..85b0198
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/drawable/excited.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/drawable/happy.xml b/Work1/WON/FeelingApplication/app/src/main/res/drawable/happy.xml
new file mode 100644
index 0000000..2faf724
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/drawable/happy.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/drawable/ic_launcher_background.xml b/Work1/WON/FeelingApplication/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/drawable/ic_launcher_foreground.xml b/Work1/WON/FeelingApplication/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/drawable/nervous.xml b/Work1/WON/FeelingApplication/app/src/main/res/drawable/nervous.xml
new file mode 100644
index 0000000..e8a2ca9
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/drawable/nervous.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/drawable/normal.xml b/Work1/WON/FeelingApplication/app/src/main/res/drawable/normal.xml
new file mode 100644
index 0000000..ede1bbe
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/drawable/normal.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main.xml b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..47f1211
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main2.xml b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main2.xml
new file mode 100644
index 0000000..584244b
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main2.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main3.xml b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main3.xml
new file mode 100644
index 0000000..5f6de6e
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main3.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main4.xml b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main4.xml
new file mode 100644
index 0000000..43dcc5e
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main4.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main5.xml b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main5.xml
new file mode 100644
index 0000000..ed67fa4
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main5.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main6.xml b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main6.xml
new file mode 100644
index 0000000..9b0ab49
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/layout/activity_main6.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/Work1/WON/FeelingApplication/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/values-night/themes.xml b/Work1/WON/FeelingApplication/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..a3c1dcf
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/values/colors.xml b/Work1/WON/FeelingApplication/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..c8524cd
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/values/strings.xml b/Work1/WON/FeelingApplication/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..454bc76
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ FeelingApplication
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/values/themes.xml b/Work1/WON/FeelingApplication/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..1110d5a
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/xml/backup_rules.xml b/Work1/WON/FeelingApplication/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/main/res/xml/data_extraction_rules.xml b/Work1/WON/FeelingApplication/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/app/src/test/java/com/example/feelingapplication/ExampleUnitTest.kt b/Work1/WON/FeelingApplication/app/src/test/java/com/example/feelingapplication/ExampleUnitTest.kt
new file mode 100644
index 0000000..7ac6eca
--- /dev/null
+++ b/Work1/WON/FeelingApplication/app/src/test/java/com/example/feelingapplication/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.feelingapplication
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/build.gradle.kts b/Work1/WON/FeelingApplication/build.gradle.kts
new file mode 100644
index 0000000..922f551
--- /dev/null
+++ b/Work1/WON/FeelingApplication/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+}
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/gradle.properties b/Work1/WON/FeelingApplication/gradle.properties
new file mode 100644
index 0000000..20e2a01
--- /dev/null
+++ b/Work1/WON/FeelingApplication/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Work1/WON/FeelingApplication/gradle/libs.versions.toml b/Work1/WON/FeelingApplication/gradle/libs.versions.toml
new file mode 100644
index 0000000..faf6ca2
--- /dev/null
+++ b/Work1/WON/FeelingApplication/gradle/libs.versions.toml
@@ -0,0 +1,26 @@
+[versions]
+agp = "8.6.0"
+kotlin = "1.9.0"
+coreKtx = "1.13.1"
+junit = "4.13.2"
+junitVersion = "1.2.1"
+espressoCore = "3.6.1"
+appcompat = "1.7.0"
+material = "1.12.0"
+activity = "1.9.2"
+constraintlayout = "2.1.4"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+
diff --git a/Work1/WON/FeelingApplication/gradle/wrapper/gradle-wrapper.jar b/Work1/WON/FeelingApplication/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/Work1/WON/FeelingApplication/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Work1/WON/FeelingApplication/gradle/wrapper/gradle-wrapper.properties b/Work1/WON/FeelingApplication/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..f84e6e0
--- /dev/null
+++ b/Work1/WON/FeelingApplication/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Sep 27 11:05:45 KST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Work1/WON/FeelingApplication/gradlew b/Work1/WON/FeelingApplication/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/Work1/WON/FeelingApplication/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Work1/WON/FeelingApplication/gradlew.bat b/Work1/WON/FeelingApplication/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/Work1/WON/FeelingApplication/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Work1/WON/FeelingApplication/settings.gradle.kts b/Work1/WON/FeelingApplication/settings.gradle.kts
new file mode 100644
index 0000000..23b55c6
--- /dev/null
+++ b/Work1/WON/FeelingApplication/settings.gradle.kts
@@ -0,0 +1,24 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "FeelingApplication"
+include(":app")
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/.gitignore b/Work2/WON/Project2/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/Work2/WON/Project2/.gitignore
@@ -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
diff --git a/Work2/WON/Project2/.idea/.gitignore b/Work2/WON/Project2/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Work2/WON/Project2/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Work2/WON/Project2/.idea/compiler.xml b/Work2/WON/Project2/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/Work2/WON/Project2/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/.idea/deploymentTargetSelector.xml b/Work2/WON/Project2/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/Work2/WON/Project2/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/.idea/gradle.xml b/Work2/WON/Project2/.idea/gradle.xml
new file mode 100644
index 0000000..7b3006b
--- /dev/null
+++ b/Work2/WON/Project2/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/.idea/kotlinc.xml b/Work2/WON/Project2/.idea/kotlinc.xml
new file mode 100644
index 0000000..148fdd2
--- /dev/null
+++ b/Work2/WON/Project2/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/.idea/migrations.xml b/Work2/WON/Project2/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/Work2/WON/Project2/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/.idea/misc.xml b/Work2/WON/Project2/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/Work2/WON/Project2/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/.idea/runConfigurations.xml b/Work2/WON/Project2/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/Work2/WON/Project2/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/.gitignore b/Work2/WON/Project2/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Work2/WON/Project2/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/build.gradle.kts b/Work2/WON/Project2/app/build.gradle.kts
new file mode 100644
index 0000000..8ce6db4
--- /dev/null
+++ b/Work2/WON/Project2/app/build.gradle.kts
@@ -0,0 +1,48 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.project2"
+ compileSdk = 35
+
+ defaultConfig {
+ applicationId = "com.example.project2"
+ minSdk = 24
+ targetSdk = 35
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+}
+
+dependencies {
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.activity)
+ implementation(libs.androidx.constraintlayout)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/proguard-rules.pro b/Work2/WON/Project2/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Work2/WON/Project2/app/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/androidTest/java/com/example/project2/ExampleInstrumentedTest.kt b/Work2/WON/Project2/app/src/androidTest/java/com/example/project2/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..ce214e0
--- /dev/null
+++ b/Work2/WON/Project2/app/src/androidTest/java/com/example/project2/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.project2
+
+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.project2", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/main/AndroidManifest.xml b/Work2/WON/Project2/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9ded2a6
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/AndroidManifest.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/main/java/com/example/project2/CategoryFragment.kt b/Work2/WON/Project2/app/src/main/java/com/example/project2/CategoryFragment.kt
new file mode 100644
index 0000000..d77b134
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/java/com/example/project2/CategoryFragment.kt
@@ -0,0 +1,15 @@
+package com.example.project2
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+class CategoryFragment : Fragment() {
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.fragment_category, container, false)
+ }
+}
diff --git a/Work2/WON/Project2/app/src/main/java/com/example/project2/HistoryFragment.kt b/Work2/WON/Project2/app/src/main/java/com/example/project2/HistoryFragment.kt
new file mode 100644
index 0000000..503f6c8
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/java/com/example/project2/HistoryFragment.kt
@@ -0,0 +1,15 @@
+package com.example.project2
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+class HistoryFragment : Fragment() {
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.fragment_history, container, false)
+ }
+}
diff --git a/Work2/WON/Project2/app/src/main/java/com/example/project2/HomeFragment.kt b/Work2/WON/Project2/app/src/main/java/com/example/project2/HomeFragment.kt
new file mode 100644
index 0000000..d055c97
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/java/com/example/project2/HomeFragment.kt
@@ -0,0 +1,15 @@
+package com.example.project2
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+class HomeFragment : Fragment() {
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.fragment_home, container, false)
+ }
+}
diff --git a/Work2/WON/Project2/app/src/main/java/com/example/project2/MainActivity.kt b/Work2/WON/Project2/app/src/main/java/com/example/project2/MainActivity.kt
new file mode 100644
index 0000000..67ce7cd
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/java/com/example/project2/MainActivity.kt
@@ -0,0 +1,58 @@
+package com.example.project2
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+import com.google.android.material.bottomnavigation.BottomNavigationView
+
+class MainActivity : AppCompatActivity() {
+ private var currentFragment: Fragment? = null // 현재 프래그먼트 저장
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ val bottomNavigationView = findViewById(R.id.bottom_navigation)
+
+ // 처음 시작할 때 홈 프래그먼트 보여주기
+ val homeFragment = HomeFragment()
+ replaceFragment(homeFragment, false)
+ currentFragment = homeFragment
+
+ // 홈 버튼을 기본 선택 상태로 설정
+ bottomNavigationView.selectedItemId = R.id.nav_home
+
+ bottomNavigationView.setOnItemSelectedListener { item ->
+ val selectedFragment = when (item.itemId) {
+ R.id.nav_category -> CategoryFragment()
+ R.id.nav_shutter -> ShutterFragment()
+ R.id.nav_home -> HomeFragment()
+ R.id.nav_history -> HistoryFragment()
+ R.id.nav_my -> MyFragment()
+ else -> return@setOnItemSelectedListener false
+ }
+
+ // 현재 프래그먼트와 동일한 경우 변경하지 않음
+ if (selectedFragment::class == currentFragment!!::class) return@setOnItemSelectedListener false
+
+ replaceFragment(selectedFragment, true)
+ currentFragment = selectedFragment
+ true
+ }
+ }
+
+ private fun replaceFragment(fragment: Fragment, addAnimation: Boolean) {
+ val transaction = supportFragmentManager.beginTransaction()
+
+ if (addAnimation) {
+ // **오른쪽에서 왼쪽으로 슬라이드 효과**
+ transaction.setCustomAnimations(
+ R.anim.slide_in_right, // 새 프래그먼트 들어올 때
+ R.anim.slide_out_left // 기존 프래그먼트 나갈 때
+ )
+ }
+
+ transaction.replace(R.id.frame_container, fragment)
+ transaction.commit()
+ }
+}
diff --git a/Work2/WON/Project2/app/src/main/java/com/example/project2/MyFragment.kt b/Work2/WON/Project2/app/src/main/java/com/example/project2/MyFragment.kt
new file mode 100644
index 0000000..06b22c6
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/java/com/example/project2/MyFragment.kt
@@ -0,0 +1,15 @@
+package com.example.project2
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+class MyFragment : Fragment() {
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.fragment_my, container, false)
+ }
+}
diff --git a/Work2/WON/Project2/app/src/main/java/com/example/project2/ShutterFragment.kt b/Work2/WON/Project2/app/src/main/java/com/example/project2/ShutterFragment.kt
new file mode 100644
index 0000000..b7fc18b
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/java/com/example/project2/ShutterFragment.kt
@@ -0,0 +1,15 @@
+package com.example.project2
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+class ShutterFragment : Fragment() {
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.fragment_shutter, container, false)
+ }
+}
diff --git a/Work2/WON/Project2/app/src/main/java/com/example/project2/SplashActivity.kt b/Work2/WON/Project2/app/src/main/java/com/example/project2/SplashActivity.kt
new file mode 100644
index 0000000..bbe15e1
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/java/com/example/project2/SplashActivity.kt
@@ -0,0 +1,24 @@
+package com.example.project2
+
+import android.content.Intent
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat.startActivity
+
+class SplashActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ // 스플래시 화면의 XML 파일 설정
+ setContentView(R.layout.activity_splash)
+
+ // 2초 후 MainActivity로 이동
+ Handler(Looper.getMainLooper()).postDelayed({
+ val intent = Intent(this, MainActivity::class.java)
+ startActivity(intent)
+ finish() // 현재 액티비티 종료 (뒤로 가기 방지)
+ }, 2000) // 2초 (2000ms)
+ }
+}
diff --git a/Work2/WON/Project2/app/src/main/res/anim/slide_in_right.xml b/Work2/WON/Project2/app/src/main/res/anim/slide_in_right.xml
new file mode 100644
index 0000000..23444a7
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/anim/slide_in_right.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/anim/slide_out_left.xml b/Work2/WON/Project2/app/src/main/res/anim/slide_out_left.xml
new file mode 100644
index 0000000..8163efa
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/anim/slide_out_left.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/category.jpg b/Work2/WON/Project2/app/src/main/res/drawable/category.jpg
new file mode 100644
index 0000000..f5e2d4d
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/drawable/category.jpg differ
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/history.jpg b/Work2/WON/Project2/app/src/main/res/drawable/history.jpg
new file mode 100644
index 0000000..d017e4d
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/drawable/history.jpg differ
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/home_image.jpg b/Work2/WON/Project2/app/src/main/res/drawable/home_image.jpg
new file mode 100644
index 0000000..3b384a0
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/drawable/home_image.jpg differ
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/ic_category.xml b/Work2/WON/Project2/app/src/main/res/drawable/ic_category.xml
new file mode 100644
index 0000000..b1f86bb
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/drawable/ic_category.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/ic_history.xml b/Work2/WON/Project2/app/src/main/res/drawable/ic_history.xml
new file mode 100644
index 0000000..6ad75a1
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/drawable/ic_history.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/ic_home.xml b/Work2/WON/Project2/app/src/main/res/drawable/ic_home.xml
new file mode 100644
index 0000000..20cb4d6
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/drawable/ic_home.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/ic_launcher_background.xml b/Work2/WON/Project2/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/ic_launcher_foreground.xml b/Work2/WON/Project2/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/ic_my.xml b/Work2/WON/Project2/app/src/main/res/drawable/ic_my.xml
new file mode 100644
index 0000000..f4cc418
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/drawable/ic_my.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/ic_shutter.xml b/Work2/WON/Project2/app/src/main/res/drawable/ic_shutter.xml
new file mode 100644
index 0000000..36727c6
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/drawable/ic_shutter.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/img.png b/Work2/WON/Project2/app/src/main/res/drawable/img.png
new file mode 100644
index 0000000..b8c69fb
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/drawable/img.png differ
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/my.jpg b/Work2/WON/Project2/app/src/main/res/drawable/my.jpg
new file mode 100644
index 0000000..adcf337
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/drawable/my.jpg differ
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/oliveyoung.jpg b/Work2/WON/Project2/app/src/main/res/drawable/oliveyoung.jpg
new file mode 100644
index 0000000..2be07f3
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/drawable/oliveyoung.jpg differ
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/oliveyoung_logo.jpeg b/Work2/WON/Project2/app/src/main/res/drawable/oliveyoung_logo.jpeg
new file mode 100644
index 0000000..49de72a
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/drawable/oliveyoung_logo.jpeg differ
diff --git a/Work2/WON/Project2/app/src/main/res/drawable/shutter.jpg b/Work2/WON/Project2/app/src/main/res/drawable/shutter.jpg
new file mode 100644
index 0000000..07b1471
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/drawable/shutter.jpg differ
diff --git a/Work2/WON/Project2/app/src/main/res/layout/activity_main.xml b/Work2/WON/Project2/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..ea74a96
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/layout/activity_splash.xml b/Work2/WON/Project2/app/src/main/res/layout/activity_splash.xml
new file mode 100644
index 0000000..5311d11
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/layout/activity_splash.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/layout/fragment_category.xml b/Work2/WON/Project2/app/src/main/res/layout/fragment_category.xml
new file mode 100644
index 0000000..77cb13e
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/layout/fragment_category.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/layout/fragment_history.xml b/Work2/WON/Project2/app/src/main/res/layout/fragment_history.xml
new file mode 100644
index 0000000..1e37c67
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/layout/fragment_history.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/layout/fragment_home.xml b/Work2/WON/Project2/app/src/main/res/layout/fragment_home.xml
new file mode 100644
index 0000000..f4dc8dd
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/layout/fragment_home.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/layout/fragment_my.xml b/Work2/WON/Project2/app/src/main/res/layout/fragment_my.xml
new file mode 100644
index 0000000..4b39f71
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/layout/fragment_my.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/layout/fragment_shutter.xml b/Work2/WON/Project2/app/src/main/res/layout/fragment_shutter.xml
new file mode 100644
index 0000000..9231e61
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/layout/fragment_shutter.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/menu/bottom_nav_menu.xml b/Work2/WON/Project2/app/src/main/res/menu/bottom_nav_menu.xml
new file mode 100644
index 0000000..3999bbd
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/menu/bottom_nav_menu.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Work2/WON/Project2/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Work2/WON/Project2/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Work2/WON/Project2/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Work2/WON/Project2/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Work2/WON/Project2/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Work2/WON/Project2/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Work2/WON/Project2/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Work2/WON/Project2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Work2/WON/Project2/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Work2/WON/Project2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Work2/WON/Project2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Work2/WON/Project2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Work2/WON/Project2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/Work2/WON/Project2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Work2/WON/Project2/app/src/main/res/values-night/themes.xml b/Work2/WON/Project2/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..e43ed5c
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/main/res/values/colors.xml b/Work2/WON/Project2/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..c8524cd
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/main/res/values/strings.xml b/Work2/WON/Project2/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..4e6c3c4
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Project2
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/main/res/values/themes.xml b/Work2/WON/Project2/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..29dc426
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/main/res/xml/backup_rules.xml b/Work2/WON/Project2/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/main/res/xml/data_extraction_rules.xml b/Work2/WON/Project2/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/Work2/WON/Project2/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work2/WON/Project2/app/src/test/java/com/example/project2/ExampleUnitTest.kt b/Work2/WON/Project2/app/src/test/java/com/example/project2/ExampleUnitTest.kt
new file mode 100644
index 0000000..52769e7
--- /dev/null
+++ b/Work2/WON/Project2/app/src/test/java/com/example/project2/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.project2
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work2/WON/Project2/build.gradle.kts b/Work2/WON/Project2/build.gradle.kts
new file mode 100644
index 0000000..922f551
--- /dev/null
+++ b/Work2/WON/Project2/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+}
\ No newline at end of file
diff --git a/Work2/WON/Project2/gradle.properties b/Work2/WON/Project2/gradle.properties
new file mode 100644
index 0000000..20e2a01
--- /dev/null
+++ b/Work2/WON/Project2/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Work2/WON/Project2/gradle/libs.versions.toml b/Work2/WON/Project2/gradle/libs.versions.toml
new file mode 100644
index 0000000..2a7aee7
--- /dev/null
+++ b/Work2/WON/Project2/gradle/libs.versions.toml
@@ -0,0 +1,26 @@
+[versions]
+agp = "8.8.0"
+kotlin = "1.9.24"
+coreKtx = "1.15.0"
+junit = "4.13.2"
+junitVersion = "1.2.1"
+espressoCore = "3.6.1"
+appcompat = "1.7.0"
+material = "1.12.0"
+activity = "1.10.1"
+constraintlayout = "2.2.1"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+
diff --git a/Work2/WON/Project2/gradle/wrapper/gradle-wrapper.jar b/Work2/WON/Project2/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/Work2/WON/Project2/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Work2/WON/Project2/gradle/wrapper/gradle-wrapper.properties b/Work2/WON/Project2/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..3fb2dbb
--- /dev/null
+++ b/Work2/WON/Project2/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sun Mar 23 22:13:29 KST 2025
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Work2/WON/Project2/gradlew b/Work2/WON/Project2/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/Work2/WON/Project2/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Work2/WON/Project2/gradlew.bat b/Work2/WON/Project2/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/Work2/WON/Project2/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Work2/WON/Project2/settings.gradle.kts b/Work2/WON/Project2/settings.gradle.kts
new file mode 100644
index 0000000..a8f7d84
--- /dev/null
+++ b/Work2/WON/Project2/settings.gradle.kts
@@ -0,0 +1,24 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "Project2"
+include(":app")
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/.gitignore b/Work3/WON/Mission3/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/Work3/WON/Mission3/.gitignore
@@ -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
diff --git a/Work3/WON/Mission3/.idea/.gitignore b/Work3/WON/Mission3/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Work3/WON/Mission3/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Work3/WON/Mission3/.idea/compiler.xml b/Work3/WON/Mission3/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/Work3/WON/Mission3/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/.idea/deploymentTargetSelector.xml b/Work3/WON/Mission3/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/Work3/WON/Mission3/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/.idea/gradle.xml b/Work3/WON/Mission3/.idea/gradle.xml
new file mode 100644
index 0000000..7b3006b
--- /dev/null
+++ b/Work3/WON/Mission3/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/.idea/kotlinc.xml b/Work3/WON/Mission3/.idea/kotlinc.xml
new file mode 100644
index 0000000..fdf8d99
--- /dev/null
+++ b/Work3/WON/Mission3/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/.idea/migrations.xml b/Work3/WON/Mission3/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/Work3/WON/Mission3/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/.idea/misc.xml b/Work3/WON/Mission3/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/Work3/WON/Mission3/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/.idea/runConfigurations.xml b/Work3/WON/Mission3/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/Work3/WON/Mission3/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/.gitignore b/Work3/WON/Mission3/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Work3/WON/Mission3/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/build.gradle.kts b/Work3/WON/Mission3/app/build.gradle.kts
new file mode 100644
index 0000000..5826818
--- /dev/null
+++ b/Work3/WON/Mission3/app/build.gradle.kts
@@ -0,0 +1,56 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.mission3"
+ compileSdk = 34
+
+ viewBinding {
+ enable=true
+ }
+
+ defaultConfig {
+ applicationId = "com.example.mission3"
+ minSdk = 24
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+dependencies {
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.activity)
+ implementation(libs.androidx.constraintlayout)
+ implementation(libs.androidx.room.common)
+ implementation(libs.androidx.room.ktx) // Room의 공통 라이브러리
+
+
+
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/proguard-rules.pro b/Work3/WON/Mission3/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Work3/WON/Mission3/app/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/AndroidManifest.xml b/Work3/WON/Mission3/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9624502
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/AndroidManifest.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/Album.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/Album.kt
new file mode 100644
index 0000000..9aa079b
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/Album.kt
@@ -0,0 +1,8 @@
+package com.example.mission3
+
+data class Album(
+ val title: String,
+ val singer: String,
+ val coverImage: Int
+
+)
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt
new file mode 100644
index 0000000..98a2f11
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt
@@ -0,0 +1,38 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class AlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapter(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt
new file mode 100644
index 0000000..e6ccd88
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapter (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> SongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt
new file mode 100644
index 0000000..6d4ba64
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapterDrowning (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> DrowningSongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt
new file mode 100644
index 0000000..e2b4f78
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapterIdome (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> IdomeSongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt
new file mode 100644
index 0000000..16d14b0
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner1Binding
+
+class AllBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner1Binding // 이름 변경
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner1Binding.inflate(inflater, container, false) // 이름 변경
+ return binding.root
+ }
+}
+
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt
new file mode 100644
index 0000000..ec7814b
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragAudioBinding
+import com.example.mission3.databinding.FragMymusicBinding
+
+class AudioFrag : Fragment() {
+ private var _binding: FragAudioBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragAudioBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt
new file mode 100644
index 0000000..a1141c2
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt
@@ -0,0 +1,18 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class BannerViewPagerAdapter(fragment : Fragment) : FragmentStateAdapter(fragment) {
+
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position){
+ 0 -> AllBannerFragment()
+ 1 -> TwoBannerFragment()
+ else -> ThreeBannerFragment()
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt
new file mode 100644
index 0000000..49ef847
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentDetailBinding
+
+class DetailFragment : Fragment() {
+ lateinit var binding: FragmentDetailBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentDetailBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt
new file mode 100644
index 0000000..aa24713
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt
@@ -0,0 +1,40 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.example.mission3.databinding.FragmentAlbumDrowningBinding
+import com.example.mission3.databinding.FragmentAlbumIdomeBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class DrowningAlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumDrowningBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumDrowningBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapterDrowning(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt
new file mode 100644
index 0000000..45e7322
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt
@@ -0,0 +1,24 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+import com.example.mission3.databinding.FragmentSongDrowningBinding
+import com.example.mission3.databinding.FragmentSongIdomeBinding
+
+class DrowningSongFragment : Fragment() {
+ lateinit var binding: FragmentSongDrowningBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongDrowningBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt
new file mode 100644
index 0000000..47d711d
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt
@@ -0,0 +1,4 @@
+package com.example.mission3
+
+class HomeAdapter {
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt
new file mode 100644
index 0000000..e0ff126
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt
@@ -0,0 +1,45 @@
+package com.example.mission3
+
+// HomeBannerAdapter.kt
+
+
+import android.media.Image
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.recyclerview.widget.RecyclerView
+
+class HomeBannerAdapter(
+ private val bannerLayouts: List,
+ private val onItemClick: (Int) -> Unit
+) : RecyclerView.Adapter() {
+
+ inner class BannerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ init {
+ itemView.setOnClickListener {
+ val position = adapterPosition
+ if (position != RecyclerView.NO_POSITION) {
+ onItemClick(position)
+ }
+ }
+ }
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return bannerLayouts[position]
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(viewType, parent, false)
+ return BannerViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: BannerViewHolder, position: Int) {
+ // 이미지가 레이아웃 파일에 이미 설정되어 있으므로 별도의 바인딩이 필요하지 않을 수 있습니다.
+ // 그러나 필요하다면 여기에 추가적인 바인딩 로직을 구현할 수 있습니다.
+ }
+
+ override fun getItemCount(): Int = bannerLayouts.size
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt
new file mode 100644
index 0000000..6a33265
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt
@@ -0,0 +1,169 @@
+package com.example.mission3
+
+
+import android.content.Intent
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.widget.ViewPager2
+import com.example.mission3.databinding.FragmentHomeBinding
+import java.util.Timer
+import java.util.TimerTask
+
+class HomeFragment : Fragment() {
+
+ private lateinit var homeBannerVp: ViewPager2
+ private lateinit var day6Iv: ImageView
+ private lateinit var idomeIv: ImageView
+ private lateinit var drowningIv: ImageView
+ private lateinit var bannerAdapter: HomeBannerAdapter
+ private lateinit var binding: FragmentHomeBinding
+
+ private val bannerLayouts = listOf(
+ R.layout.fragment_banner_1,
+ R.layout.fragment_banner_2,
+ R.layout.fragment_banner_3
+ )
+
+ private val songDuration = 191
+ private var currentProcess = 0
+ private var isPlaying = false // 플레이 상태 확인 변수
+ private lateinit var timer: Timer
+ private val handler = Handler(Looper.getMainLooper())
+ private var currentPage = 0
+
+ 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)
+
+ //val seekBar = binding.miniPlayerSeekBar
+ //seekBar.max = songDuration
+
+ // Play/Pause 버튼 클릭 시 재생/일시 정지 처리
+ binding.itemAlbumPlayImgIv.setOnClickListener {
+ if (isPlaying) {
+ pauseMusic()
+ } else {
+ startMusic()
+ }
+ }
+
+ // mainPlayerCl 클릭 시 SongActivity로 이동
+ binding.mainPlayerCl.setOnClickListener {
+ val song = Song(
+ title = binding.miniPlayerSongTitleTv.text.toString(),
+ singer = binding.miniPlayerSingerTv.text.toString(),
+ second = currentProcess,
+ playTime = songDuration,
+ isPlaying = isPlaying
+ )
+
+ val intent = Intent(requireContext(), SongActivity::class.java)
+ intent.putExtra("title", song.title)
+ intent.putExtra("singer", song.singer)
+ intent.putExtra("second", song.second)
+ intent.putExtra("playTime", song.playTime)
+ intent.putExtra("isPlaying", song.isPlaying)
+ startActivity(intent)
+ }
+
+ // ViewPager2 초기화 및 어댑터 설정
+ homeBannerVp = binding.homeBannerVp
+ bannerAdapter = HomeBannerAdapter(bannerLayouts) { position -> }
+ homeBannerVp.adapter = bannerAdapter
+
+ // 배너 자동 슬라이드 구현
+ startBannerAutoSlide()
+
+ // day6 ImageView 클릭 시 AlbumFragment로 이동
+ day6Iv = binding.day6Iv
+ day6Iv.setOnClickListener {
+ val fragmentAlbum = AlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbum)
+ .addToBackStack(null)
+ .commit()
+ }
+
+ // idome ImageView 클릭 시 IdomeAlbumFragment로 이동
+ idomeIv = binding.idomeIv
+ idomeIv.setOnClickListener {
+ val fragmentAlbumIdome = IdomeAlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbumIdome)
+ .addToBackStack(null)
+ .commit()
+ }
+
+ // drowning ImageView 클릭 시 IdomeAlbumFragment로 이동
+ drowningIv = binding.drowningIv
+ drowningIv.setOnClickListener {
+ val fragmentAlbumDrowning = DrowningAlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbumDrowning)
+ .addToBackStack(null)
+ .commit()
+ }
+ }
+
+ // 배너 자동 슬라이드 시작
+ private fun startBannerAutoSlide() {
+ handler.postDelayed(object : Runnable {
+ override fun run() {
+ currentPage = (currentPage + 1) % 3 // 3개의 배너를 순환
+ homeBannerVp.setCurrentItem(currentPage, true)
+ handler.postDelayed(this, 3000) // 3초마다 슬라이드
+ }
+ }, 3000) // 3초 후 시작
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ if (::timer.isInitialized) timer.cancel()
+ }
+
+ // 음악 재생 시작
+ private fun startMusic() {
+ isPlaying = true
+ binding.itemAlbumPlayImgIv.setImageResource(R.drawable.baseline_pause_24) // Pause 아이콘으로 변경
+ //startSeekBar() // SeekBar 업데이트 시작
+ }
+
+
+ // 음악 일시 정지
+ private fun pauseMusic() {
+ isPlaying = false
+ binding.itemAlbumPlayImgIv.setImageResource(R.drawable.baseline_play_24) // Play 아이콘으로 변경
+ if (::timer.isInitialized) timer.cancel() // 타이머 정지
+ }
+
+
+ // SeekBar 업데이트 시작
+// private fun startSeekBar() {
+// timer = Timer()
+// timer.scheduleAtFixedRate(object : TimerTask() {
+// override fun run() {
+// if (currentProcess < songDuration) {
+// currentProcess++
+// handler.post {
+// binding.miniPlayerSeekBar.progress = currentProcess
+// }
+// } else {
+// timer.cancel() // 끝나면 타이머 취소
+// }
+// }
+// }, 0, 1000) // 1초마다 진행
+// }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt
new file mode 100644
index 0000000..b516f6e
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt
@@ -0,0 +1,39 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.example.mission3.databinding.FragmentAlbumIdomeBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class IdomeAlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumIdomeBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumIdomeBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapterIdome(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt
new file mode 100644
index 0000000..cecdd3d
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt
@@ -0,0 +1,23 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+import com.example.mission3.databinding.FragmentSongIdomeBinding
+
+class IdomeSongFragment : Fragment() {
+ lateinit var binding: FragmentSongIdomeBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongIdomeBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt
new file mode 100644
index 0000000..74e38fd
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt
@@ -0,0 +1,117 @@
+package com.example.mission3
+
+import android.content.Intent
+import android.content.SharedPreferences
+import android.os.Bundle
+import android.view.View
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.lifecycleScope
+import com.example.mission3.databinding.ActivityMainBinding
+import com.google.android.material.bottomnavigation.BottomNavigationView
+import kotlinx.coroutines.launch
+
+class MainActivity : AppCompatActivity() {
+ private lateinit var binding: ActivityMainBinding
+ private lateinit var sharedPreferences: SharedPreferences
+ private lateinit var bottomNavi: BottomNavigationView
+ private lateinit var dbHelper: SongDatabaseHelper
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ sharedPreferences = getSharedPreferences("MusicApp", MODE_PRIVATE)
+
+ // SongDatabaseHelper 인스턴스 초기화
+ dbHelper = SongDatabaseHelper(this)
+
+ // DB에 더미 데이터 삽입
+ lifecycleScope.launch {
+ insertDummySongs()
+ }
+
+ // HomeFragment가 기본 프래그먼트로 표시되도록 설정
+ if (savedInstanceState == null) {
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commit()
+ }
+
+ // 상태 표시줄 색상 설정
+ window.statusBarColor = resources.getColor(android.R.color.white, theme)
+
+ bottomNavi = binding.bottomNavi
+
+ // BottomNavigationView 아이템 선택 리스너 설정
+ bottomNavi.setOnItemSelectedListener { item ->
+ when (item.itemId) {
+ R.id.action_home -> {
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commit()
+ true
+ }
+ R.id.action_audio -> {
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.main, AudioFrag())
+ .commit()
+ true
+ }
+ R.id.action_search -> {
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.main, SearchFrag())
+ .commit()
+ true
+ }
+ R.id.action_mymusic -> {
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.main, MyMusicFragment())
+ .commit()
+ true
+ }
+ R.id.action_menu -> {
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.main, MenuFrag())
+ .commit()
+ true
+ }
+ else -> false
+ }
+ }
+
+ // mainPlayerCl을 클릭했을 때 SongActivity로 이동
+ binding.mainPlayerCl.setOnClickListener {
+ // songId를 얻어와서 SongActivity로 전달
+ val songId = getSongIdFromPreferences()
+ val intent = Intent(this, SongActivity::class.java)
+ intent.putExtra("songId", songId)
+ startActivity(intent)
+ }
+ }
+
+ // DB에 더미 데이터 삽입
+ private suspend fun insertDummySongs() {
+ val song1 = Song(id = 1, title = "HAPPY", singer = "DAY6(데이식스)", second = 0, playTime = 190, isPlaying = false, isLike = false)
+ val song2 = Song(id = 2, title = "I DO ME", singer = "KiiiKiii (키키)", second = 0, playTime = 191, isPlaying = false, isLike = false)
+ val song3 = Song(id=3, title="Drowning", singer = "WOODZ", second = 0, playTime = 245, isPlaying = false, isLike = false)
+
+ // 더미 데이터 삽입 (DB 작업)
+ dbHelper.insertSong(song1)
+ dbHelper.insertSong(song2)
+ dbHelper.insertSong((song3))
+ }
+
+ // SharedPreferences에 songId 저장
+ private fun saveSongId(songId: Int) {
+ val editor = sharedPreferences.edit()
+ editor.putInt("songId", songId)
+ editor.apply()
+ }
+
+ // SharedPreferences에서 songId 가져오기
+ private fun getSongIdFromPreferences(): Int {
+ return sharedPreferences.getInt("songId", 0) // 기본값으로 0 반환
+ }
+}
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt
new file mode 100644
index 0000000..52d5fd8
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragMenuBinding
+import com.example.mission3.databinding.FragMymusicBinding
+
+class MenuFrag : Fragment() {
+ private var _binding: FragMenuBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragMenuBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt
new file mode 100644
index 0000000..dfcd9f4
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt
@@ -0,0 +1,19 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentMusicFileBinding
+
+class MusicFileFragment: Fragment() {
+
+ lateinit var binding: FragmentMusicFileBinding
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ binding = FragmentMusicFileBinding.inflate(inflater, container, false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt
new file mode 100644
index 0000000..a2e13b5
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt
@@ -0,0 +1,38 @@
+package com.example.mission3
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.mission3.databinding.ItemMymusicAlbumBinding
+
+class MyMusicAlbumRVAdapter(private val albumList: ArrayList) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = ItemMymusicAlbumBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bind(albumList[position])
+ holder.binding.itemMymusicAlbumMoreIv.setOnClickListener {
+ // 클릭 시 해당 아이템 삭제
+ removeItem(position)
+ }
+ }
+
+ override fun getItemCount(): Int = albumList.size
+
+ fun removeItem(position: Int) {
+ albumList.removeAt(position) // 해당 아이템 제거
+ notifyItemRemoved(position) // 아이템 제거 후 갱신
+ notifyItemRangeChanged(position, albumList.size) // 나머지 아이템 갱신
+ }
+
+ inner class ViewHolder(val binding: ItemMymusicAlbumBinding) : RecyclerView.ViewHolder(binding.root) {
+ fun bind(album: Album) {
+ binding.itemMymusicAlbumTitleTv.text = album.title
+ binding.itemMymusicAlbumSingerTv.text = album.singer
+ binding.itemMymusicAlbumCoverImgIv.setImageResource(album.coverImage)
+ }
+ }
+}
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt
new file mode 100644
index 0000000..5f61e75
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt
@@ -0,0 +1,30 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.google.android.material.tabs.TabLayoutMediator
+import com.example.mission3.databinding.FragMymusicBinding
+
+class MyMusicFragment : Fragment() {
+ private lateinit var binding: FragMymusicBinding
+ private val information = arrayListOf("저장한곡", "음악파일")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = FragMymusicBinding.inflate(inflater, container, false)
+
+ val lockerAdapter = MyMusicVPAdapter(this)
+ binding.mymusicContentVp.adapter = lockerAdapter
+ TabLayoutMediator(binding.mymusicContentTb, binding.mymusicContentVp) { tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt
new file mode 100644
index 0000000..b1771db
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt
@@ -0,0 +1,15 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class MyMusicVPAdapter (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount() : Int = 2
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> SavedSongFragment()
+ else -> MusicFileFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt
new file mode 100644
index 0000000..6222cb8
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt
@@ -0,0 +1,29 @@
+package com.example.mission3
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.mission3.databinding.RecyclerviewItemBinding
+
+class RVAdapter(private val items: MutableList) : RecyclerView.Adapter(){
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding: RecyclerviewItemBinding = RecyclerviewItemBinding
+ .inflate(LayoutInflater.from(parent.context), parent, false)
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bindItems(items[position])
+ }
+
+ override fun getItemCount(): Int = items.size
+
+ // ViewHolder 내부 클래스 정의
+ inner class ViewHolder(private val binding: RecyclerviewItemBinding) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bindItems(item: String) {
+ binding.itemAlbumTitleTv.text = item
+ }
+ }
+}
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt
new file mode 100644
index 0000000..606d3b2
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt
@@ -0,0 +1,45 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.example.mission3.databinding.FragmentSavedSongBinding
+
+class SavedSongFragment : Fragment() {
+
+ private var albumDatas = ArrayList()
+ lateinit var binding: FragmentSavedSongBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSavedSongBinding.inflate(inflater, container, false)
+
+ albumDatas.apply {
+ add(Album("HAPPY", "DAY6(데이식스)", R.drawable.happy))
+ add(Album("I DO ME", "KiiiKiii (키키)", R.drawable.idome))
+ add(Album("Drowning", "WOODZ", R.drawable.drowning))
+ add(Album("Welcome to the show", "DAY6 (데이식스)", R.drawable.happy))
+ add(Album("아니 근데 진짜", "LUCY", R.drawable.happy))
+ add(Album("B.O.M.B", "TREASURE (트레저)", R.drawable.happy))
+ add(Album("Supernova", "aespa", R.drawable.happy))
+ add(Album("April shower", "세븐틴 (SEVENTEEN)", R.drawable.happy))
+ add(Album("Blueming", "아이유 (IU)", R.drawable.happy))
+ }
+
+ val myMusicAlbumRVAdapter = MyMusicAlbumRVAdapter(albumDatas)
+ binding.mymusicMusicAlbumRv.adapter = myMusicAlbumRVAdapter
+ binding.mymusicMusicAlbumRv.layoutManager = LinearLayoutManager(requireActivity())
+
+ return binding.root
+ }
+}
+
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt
new file mode 100644
index 0000000..61c15ea
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragMymusicBinding
+import com.example.mission3.databinding.FragSearchBinding
+
+class SearchFrag : Fragment() {
+ private var _binding: FragSearchBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragSearchBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/Song.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/Song.kt
new file mode 100644
index 0000000..a6ec32e
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/Song.kt
@@ -0,0 +1,12 @@
+package com.example.mission3
+
+data class Song(
+ val title: String = "",
+ val singer: String = "",
+ var second: Int = 0,
+ var playTime: Int = 60,
+ var isPlaying: Boolean = false,
+ var isLike: Boolean = false, // 좋아요 상태 추가
+ val id: Int = 0, // Primary key를 수동으로 관리
+ val imageRes: Int = 0 // 이미지 리소스를 추가 (이미지 리소스 ID)
+)
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt
new file mode 100644
index 0000000..d2b1462
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt
@@ -0,0 +1,235 @@
+package com.example.mission3
+
+import android.content.Context.MODE_PRIVATE
+import android.content.SharedPreferences
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.edit
+import com.example.mission3.databinding.ActivitySongBinding
+
+class
+SongActivity : AppCompatActivity() {
+ private lateinit var binding: ActivitySongBinding
+ private lateinit var song: Song
+ private var countDownTimer: CountDownTimer? = null
+ private var isPlaying = false
+ private var currentTime = 0 // 현재 재생 시간
+ private lateinit var sharedPreferences: SharedPreferences
+ private var isFavorite = false
+ private var songList: List = listOf() // 곡 리스트
+ private var currentSongIndex: Int = 0 // 현재 곡 인덱스
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivitySongBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ sharedPreferences = getSharedPreferences("MyMusicApp", MODE_PRIVATE)
+
+ initSongList()
+ initSong()
+ setPlayer(song)
+
+ // 즐겨찾기 상태 로드
+ loadFavoriteStatus()
+ updateFavoriteButton()
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ window.statusBarColor = Color.parseColor("#FFFFFF")
+ }
+
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ binding.songSettingIb.setOnClickListener {
+ finish()
+ }
+
+ binding.playPauseButton.setOnClickListener {
+ if (isPlaying) {
+ pauseSong()
+ } else {
+ playSong()
+ }
+ }
+
+ // 즐겨찾기 버튼 클릭 리스너
+ binding.favoriteButton.setOnClickListener {
+ isFavorite = !isFavorite
+ updateFavoriteButton()
+ saveFavoriteStatus()
+ }
+
+ // 이전 곡 버튼 클릭 리스너
+ binding.skipPrevious.setOnClickListener {
+ goToPreviousSong()
+ }
+
+ // 다음 곡 버튼 클릭 리스너
+ binding.songNextIv.setOnClickListener {
+ goToNextSong()
+ }
+ }
+
+ private val lyricsList = listOf(
+ "그런 날이 있을까요? \n마냥 좋은 그런 날이요", // HAPPY
+ "I could go somewhere \nMaybe anywhere", // I DO ME
+ "미치도록 사랑했던 \n지겹도록 다투었던" // Drowning
+ )
+
+ private fun setLyrics(index: Int) {
+ if (index in lyricsList.indices) {
+ binding.songAlbumTextTv.text = lyricsList[index]
+ }
+ }
+
+ private fun initSongList() {
+ // 곡 리스트를 불러오기 (예: DB에서 불러오기)
+ songList = listOf(
+ Song("HAPPY", "DAY6(데이식스)", 0, 190, false, imageRes = R.drawable.happy),
+ Song("I DO ME", "KiiiKiii (키키)", 0, 191, false, imageRes = R.drawable.idome),
+ Song("Drowning", "WOODZ", 0, 245, false, imageRes = R.drawable.drowning)
+ )
+
+ // SharedPreferences에서 현재 곡 인덱스 불러오기
+ currentSongIndex = sharedPreferences.getInt("current_song_index", 0)
+ }
+
+ private fun initSong() {
+ // 곡 정보를 리스트에서 가져오기
+ song = songList[currentSongIndex]
+ }
+
+ private fun setPlayer(song: Song) {
+ binding.songTitleTv.text = song.title
+ binding.songSingerTv.text = song.singer
+ binding.songStartTimeTv.text = String.format("%02d:%02d", song.second / 60, song.second % 60)
+ binding.songEndTimeTv.text = String.format("%02d:%02d", song.playTime / 60, song.playTime % 60)
+
+ // 곡 이미지 설정 (새로 추가)
+ binding.songAlbumIv.setImageResource(song.imageRes)
+
+ binding.songProgressbarView.max = song.playTime * 1000
+ binding.songProgressbarView.progress = song.second * 1000
+
+ setPlayerStatus(song.isPlaying)
+
+ // 가사 설정 추가
+ setLyrics(currentSongIndex)
+ }
+
+ private fun setPlayerStatus(isPlaying: Boolean) {
+ if (isPlaying) {
+ binding.playPauseButton.setImageResource(R.drawable.baseline_pause_24)
+ binding.songProgressbarView.progressTintList = ColorStateList.valueOf(Color.parseColor("#81BEF7"))
+ startTimer() // 타이머 시작
+ } else {
+ binding.playPauseButton.setImageResource(R.drawable.baseline_play_24)
+ binding.songProgressbarView.progressTintList = ColorStateList.valueOf(Color.GRAY)
+ }
+ }
+
+ private fun startTimer() {
+ countDownTimer = object : CountDownTimer(song.playTime * 1000L, 1000) {
+ private var elapsedSeconds = song.second
+
+ override fun onTick(millisUntilFinished: Long) {
+ elapsedSeconds++
+ binding.songProgressbarView.progress = (elapsedSeconds * 1000)
+
+ binding.songStartTimeTv.text = String.format("%02d:%02d", elapsedSeconds / 60, elapsedSeconds % 60)
+ }
+
+ override fun onFinish() {
+ binding.songProgressbarView.progress = binding.songProgressbarView.max
+ pauseSong() // 재생 완료 후 일시정지 상태로 변경
+ }
+ }.start()
+ }
+
+ private fun playSong() {
+ isPlaying = true
+ setPlayerStatus(isPlaying)
+ }
+
+ private fun pauseSong() {
+ isPlaying = false
+ countDownTimer?.cancel()
+ setPlayerStatus(isPlaying)
+ }
+
+ // 즐겨찾기 버튼 상태 업데이트
+ private fun updateFavoriteButton() {
+ if (isFavorite) {
+ binding.favoriteButton.setImageResource(R.drawable.baseline_favorite_24) // 하트 채운 아이콘
+ } else {
+ binding.favoriteButton.setImageResource(R.drawable.baseline_favorite_border_24) // 하트 비어있는 아이콘
+ }
+ }
+
+ // 즐겨찾기 상태 저장
+ private fun saveFavoriteStatus() {
+ // 곡 제목과 ID를 결합하여 고유 키 생성
+ val key = "${song.title}-${song.singer}" // 예시로 제목과 가수명을 결합
+ sharedPreferences.edit {
+ putBoolean(key, isFavorite) // 고유한 키로 즐겨찾기 상태 저장
+ }
+ }
+
+ // 즐겨찾기 상태 로드
+ private fun loadFavoriteStatus() {
+ // 곡 제목과 ID를 결합하여 고유 키 생성
+ val key = "${song.title}-${song.singer}" // 예시로 제목과 가수명을 결합
+ isFavorite = sharedPreferences.getBoolean(key, false)
+ }
+
+
+ private fun goToPreviousSong() {
+ if (currentSongIndex > 0) {
+ currentSongIndex--
+ song = songList[currentSongIndex]
+ setPlayer(song)
+ stopSong() // 곡 전환 시 이전 곡 멈추기
+ playSong() // 새로운 곡 시작
+
+ // SharedPreferences에 현재 곡 인덱스 저장
+ sharedPreferences.edit {
+ putInt("current_song_index", currentSongIndex)
+ }
+ }
+ }
+
+ private fun goToNextSong() {
+ if (currentSongIndex < songList.size - 1) {
+ currentSongIndex++
+ song = songList[currentSongIndex]
+ setPlayer(song)
+ stopSong() // 곡 전환 시 이전 곡 멈추기
+ playSong() // 새로운 곡 시작
+
+ // SharedPreferences에 현재 곡 인덱스 저장
+ sharedPreferences.edit {
+ putInt("current_song_index", currentSongIndex)
+ }
+ }
+ }
+
+ private fun stopSong() {
+ // 곡 멈추기 (임시로 노래 재생 없이 처리)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ countDownTimer?.cancel()
+ }
+
+ override fun onSupportNavigateUp(): Boolean {
+ onBackPressed()
+ return true
+ }
+}
+
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt
new file mode 100644
index 0000000..56317b3
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt
@@ -0,0 +1,146 @@
+package com.example.mission3
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import android.database.Cursor
+import android.content.ContentValues
+import android.database.SQLException
+import android.database.sqlite.SQLiteOpenHelper
+
+
+class SongDatabaseHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
+
+ companion object {
+ private const val DATABASE_NAME = "songs.db"
+ private const val DATABASE_VERSION = 1
+
+ // 테이블 및 컬럼 이름
+ const val TABLE_SONGS = "songs"
+ const val COLUMN_ID = "id"
+ const val COLUMN_TITLE = "title"
+ const val COLUMN_SINGER = "singer"
+ const val COLUMN_SECOND = "second"
+ const val COLUMN_PLAYTIME = "playTime"
+ const val COLUMN_ISPLAYING = "isPlaying"
+ const val COLUMN_ISLIKE = "isLike"
+ }
+
+ override fun onCreate(db: SQLiteDatabase?) {
+ val createTableQuery = """
+ CREATE TABLE $TABLE_SONGS (
+ $COLUMN_ID INTEGER PRIMARY KEY AUTOINCREMENT,
+ $COLUMN_TITLE TEXT,
+ $COLUMN_SINGER TEXT,
+ $COLUMN_SECOND INTEGER,
+ $COLUMN_PLAYTIME INTEGER,
+ $COLUMN_ISPLAYING INTEGER,
+ $COLUMN_ISLIKE INTEGER
+ )
+ """
+ db?.execSQL(createTableQuery)
+ }
+
+ override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
+ db?.execSQL("DROP TABLE IF EXISTS $TABLE_SONGS")
+ onCreate(db)
+ }
+
+ // Song 삽입 메서드
+ fun insertSong(song: Song): Long {
+ val db = writableDatabase
+ val values = ContentValues().apply {
+ put(COLUMN_TITLE, song.title)
+ put(COLUMN_SINGER, song.singer)
+ put(COLUMN_SECOND, song.second)
+ put(COLUMN_PLAYTIME, song.playTime)
+ put(COLUMN_ISPLAYING, if (song.isPlaying) 1 else 0)
+ put(COLUMN_ISLIKE, if (song.isLike) 1 else 0)
+ }
+
+ return db.insert(TABLE_SONGS, null, values)
+ }
+
+ // Song 업데이트 메서드
+ fun updateSong(song: Song) {
+ val db = writableDatabase
+ val values = ContentValues().apply {
+ put(COLUMN_TITLE, song.title)
+ put(COLUMN_SINGER, song.singer)
+ put(COLUMN_SECOND, song.second)
+ put(COLUMN_PLAYTIME, song.playTime)
+ put(COLUMN_ISPLAYING, if (song.isPlaying) 1 else 0)
+ put(COLUMN_ISLIKE, if (song.isLike) 1 else 0)
+ }
+
+ db.update(TABLE_SONGS, values, "$COLUMN_ID = ?", arrayOf(song.id.toString()))
+ }
+
+ // ID로 Song 조회 메서드
+ @SuppressLint("Range")
+ fun getSongById(id: Int): Song? {
+ val db = readableDatabase
+ val cursor: Cursor = db.query(
+ TABLE_SONGS,
+ null,
+ "$COLUMN_ID = ?",
+ arrayOf(id.toString()),
+ null,
+ null,
+ null
+ )
+
+ return if (cursor.moveToFirst()) {
+ val title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE))
+ val singer = cursor.getString(cursor.getColumnIndex(COLUMN_SINGER))
+ val second = cursor.getInt(cursor.getColumnIndex(COLUMN_SECOND))
+ val playTime = cursor.getInt(cursor.getColumnIndex(COLUMN_PLAYTIME))
+ val isPlaying = cursor.getInt(cursor.getColumnIndex(COLUMN_ISPLAYING)) == 1
+ val isLike = cursor.getInt(cursor.getColumnIndex(COLUMN_ISLIKE)) == 1
+ val songId = cursor.getInt(cursor.getColumnIndex(COLUMN_ID))
+
+ Song(title, singer, second, playTime, isPlaying, isLike, songId)
+ } else {
+ null
+ }
+ }
+
+ // 모든 Song 조회 메서드
+ @SuppressLint("Range")
+ fun getAllSongs(): List {
+ val songList = mutableListOf()
+ val db = readableDatabase
+ val cursor: Cursor = db.query(
+ TABLE_SONGS,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+
+ if (cursor.moveToFirst()) {
+ do {
+ val title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE))
+ val singer = cursor.getString(cursor.getColumnIndex(COLUMN_SINGER))
+ val second = cursor.getInt(cursor.getColumnIndex(COLUMN_SECOND))
+ val playTime = cursor.getInt(cursor.getColumnIndex(COLUMN_PLAYTIME))
+ val isPlaying = cursor.getInt(cursor.getColumnIndex(COLUMN_ISPLAYING)) == 1
+ val isLike = cursor.getInt(cursor.getColumnIndex(COLUMN_ISLIKE)) == 1
+ val songId = cursor.getInt(cursor.getColumnIndex(COLUMN_ID))
+
+ songList.add(Song(title, singer, second, playTime, isPlaying, isLike, songId))
+ } while (cursor.moveToNext())
+ }
+
+ cursor.close()
+ return songList
+ }
+
+ // Song 삭제 메서드
+ fun deleteSong(id: Int) {
+ val db = writableDatabase
+ db.delete(TABLE_SONGS, "$COLUMN_ID = ?", arrayOf(id.toString()))
+ }
+}
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt
new file mode 100644
index 0000000..56f6e2a
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+
+class SongFragment : Fragment() {
+ lateinit var binding: FragmentSongBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt
new file mode 100644
index 0000000..9314d0f
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner3Binding
+
+class ThreeBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner3Binding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner3Binding.inflate(inflater,container,false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt
new file mode 100644
index 0000000..879e2d7
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner2Binding
+
+class TwoBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner2Binding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner2Binding.inflate(inflater,container,false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt
new file mode 100644
index 0000000..cb0b9b0
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+
+import com.example.mission3.databinding.FragmentVideoBinding
+
+class ViedoFragment : Fragment() {
+ lateinit var binding: FragmentVideoBinding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentVideoBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/banner1.jpg b/Work3/WON/Mission3/app/src/main/res/drawable/banner1.jpg
new file mode 100644
index 0000000..81524e1
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/drawable/banner1.jpg differ
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/banner2.jpg b/Work3/WON/Mission3/app/src/main/res/drawable/banner2.jpg
new file mode 100644
index 0000000..bc20bf4
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/drawable/banner2.jpg differ
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/banner3.jpg b/Work3/WON/Mission3/app/src/main/res/drawable/banner3.jpg
new file mode 100644
index 0000000..8b55d5f
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/drawable/banner3.jpg differ
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml
new file mode 100644
index 0000000..99f85de
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml
new file mode 100644
index 0000000..1a69b23
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml
new file mode 100644
index 0000000..6e3d747
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_audio_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_audio_24.xml
new file mode 100644
index 0000000..82ea4d3
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_audio_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_check_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_check_24.xml
new file mode 100644
index 0000000..356e998
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_check_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml
new file mode 100644
index 0000000..badf5ea
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml
new file mode 100644
index 0000000..2acceab
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_home_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_home_24.xml
new file mode 100644
index 0000000..20cb4d6
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_home_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml
new file mode 100644
index 0000000..0e5587b
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml
new file mode 100644
index 0000000..1146d4c
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml
new file mode 100644
index 0000000..a7912d8
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_menu_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_menu_24.xml
new file mode 100644
index 0000000..75c361f
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_menu_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml
new file mode 100644
index 0000000..52ede6a
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml
new file mode 100644
index 0000000..c9c2ad9
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_next_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_next_24.xml
new file mode 100644
index 0000000..4904368
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_next_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_pause_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_pause_24.xml
new file mode 100644
index 0000000..ae853f2
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_pause_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml
new file mode 100644
index 0000000..1e24cf3
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_play_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_play_24.xml
new file mode 100644
index 0000000..b176182
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_play_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_play_more24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_play_more24.xml
new file mode 100644
index 0000000..5ffb98a
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_play_more24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml
new file mode 100644
index 0000000..c7d89f1
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml
new file mode 100644
index 0000000..151a3e1
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_search_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_search_24.xml
new file mode 100644
index 0000000..d29c6ea
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_search_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml
new file mode 100644
index 0000000..5a79f5e
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml
new file mode 100644
index 0000000..7951d71
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_star_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_star_24.xml
new file mode 100644
index 0000000..925b973
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_star_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml
new file mode 100644
index 0000000..f775f11
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/baseline_volume_24.xml b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_volume_24.xml
new file mode 100644
index 0000000..a53186e
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/baseline_volume_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/drowning.jpg b/Work3/WON/Mission3/app/src/main/res/drawable/drowning.jpg
new file mode 100644
index 0000000..97fa652
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/drawable/drowning.jpg differ
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/happy.jpg b/Work3/WON/Mission3/app/src/main/res/drawable/happy.jpg
new file mode 100644
index 0000000..6b24b63
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/drawable/happy.jpg differ
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/ic_launcher_background.xml b/Work3/WON/Mission3/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml b/Work3/WON/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/drawable/idome.jpg b/Work3/WON/Mission3/app/src/main/res/drawable/idome.jpg
new file mode 100644
index 0000000..b40b38f
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/drawable/idome.jpg differ
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/activity_main.xml b/Work3/WON/Mission3/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..463c204
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/activity_song.xml b/Work3/WON/Mission3/app/src/main/res/layout/activity_song.xml
new file mode 100644
index 0000000..6be6395
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/activity_song.xml
@@ -0,0 +1,283 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/frag_audio.xml b/Work3/WON/Mission3/app/src/main/res/layout/frag_audio.xml
new file mode 100644
index 0000000..ae66603
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/frag_audio.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/frag_menu.xml b/Work3/WON/Mission3/app/src/main/res/layout/frag_menu.xml
new file mode 100644
index 0000000..d6811d0
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/frag_menu.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/frag_mymusic.xml b/Work3/WON/Mission3/app/src/main/res/layout/frag_mymusic.xml
new file mode 100644
index 0000000..7f4cef8
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/frag_mymusic.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/frag_search.xml b/Work3/WON/Mission3/app/src/main/res/layout/frag_search.xml
new file mode 100644
index 0000000..d523e6e
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/frag_search.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_album.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_album.xml
new file mode 100644
index 0000000..825ab0d
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_album.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_album_drowning.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_album_drowning.xml
new file mode 100644
index 0000000..e341853
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_album_drowning.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_album_idome.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_album_idome.xml
new file mode 100644
index 0000000..6792827
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_album_idome.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_banner_1.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_banner_1.xml
new file mode 100644
index 0000000..142a6b8
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_banner_1.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_banner_2.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_banner_2.xml
new file mode 100644
index 0000000..f194ac2
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_banner_2.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_banner_3.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_banner_3.xml
new file mode 100644
index 0000000..5923f27
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_banner_3.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_detail.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_detail.xml
new file mode 100644
index 0000000..413125c
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_detail.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_home.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_home.xml
new file mode 100644
index 0000000..899c14f
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_home.xml
@@ -0,0 +1,348 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_music_file.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_music_file.xml
new file mode 100644
index 0000000..77d9ef6
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_music_file.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_saved_song.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_saved_song.xml
new file mode 100644
index 0000000..6130fb1
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_saved_song.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_song.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_song.xml
new file mode 100644
index 0000000..d8b7921
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_song.xml
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_song_drowning.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_song_drowning.xml
new file mode 100644
index 0000000..6566743
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_song_drowning.xml
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_song_idome.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_song_idome.xml
new file mode 100644
index 0000000..e92ec6f
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_song_idome.xml
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/fragment_video.xml b/Work3/WON/Mission3/app/src/main/res/layout/fragment_video.xml
new file mode 100644
index 0000000..e86dad1
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/fragment_video.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/item_mymusic_album.xml b/Work3/WON/Mission3/app/src/main/res/layout/item_mymusic_album.xml
new file mode 100644
index 0000000..b515f94
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/item_mymusic_album.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/layout/recyclerview_item.xml b/Work3/WON/Mission3/app/src/main/res/layout/recyclerview_item.xml
new file mode 100644
index 0000000..30c304a
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/layout/recyclerview_item.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/menu/menu.xml b/Work3/WON/Mission3/app/src/main/res/menu/menu.xml
new file mode 100644
index 0000000..4472d4b
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/menu/menu.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Work3/WON/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Work3/WON/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Work3/WON/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Work3/WON/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Work3/WON/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Work3/WON/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Work3/WON/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Work3/WON/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Work3/WON/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Work3/WON/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Work3/WON/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Work3/WON/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Work3/WON/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/Work3/WON/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Work3/WON/Mission3/app/src/main/res/values-night/themes.xml b/Work3/WON/Mission3/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..ebeb9cd
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/values/colors.xml b/Work3/WON/Mission3/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..aacedae
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/values/strings.xml b/Work3/WON/Mission3/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..90c25e1
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/values/strings.xml
@@ -0,0 +1,12 @@
+
+ Mission3
+ NewJeans 이미지
+ 배너 이미지
+ Home
+ Album
+ Audio
+ Search
+ My Music
+ Menu
+ Play/Pause
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/values/themes.xml b/Work3/WON/Mission3/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..66e5370
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/values/themes.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/xml/backup_rules.xml b/Work3/WON/Mission3/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/main/res/xml/data_extraction_rules.xml b/Work3/WON/Mission3/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt b/Work3/WON/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt
new file mode 100644
index 0000000..6c8895e
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.mission3
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt b/Work3/WON/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt
new file mode 100644
index 0000000..49f80b4
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.missionn3
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt b/Work3/WON/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt
new file mode 100644
index 0000000..e500fb8
--- /dev/null
+++ b/Work3/WON/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.myapplication
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/build.gradle.kts b/Work3/WON/Mission3/build.gradle.kts
new file mode 100644
index 0000000..922f551
--- /dev/null
+++ b/Work3/WON/Mission3/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+}
\ No newline at end of file
diff --git a/Work3/WON/Mission3/gradle.properties b/Work3/WON/Mission3/gradle.properties
new file mode 100644
index 0000000..20e2a01
--- /dev/null
+++ b/Work3/WON/Mission3/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Work3/WON/Mission3/gradle/libs.versions.toml b/Work3/WON/Mission3/gradle/libs.versions.toml
new file mode 100644
index 0000000..0b1b772
--- /dev/null
+++ b/Work3/WON/Mission3/gradle/libs.versions.toml
@@ -0,0 +1,32 @@
+[versions]
+agp = "8.6.0"
+kotlin = "1.9.0"
+coreKtx = "1.13.1"
+junit = "4.13.2"
+junitVersion = "1.2.1"
+espressoCore = "3.6.1"
+appcompat = "1.7.0"
+material = "1.12.0"
+activity = "1.9.2"
+constraintlayout = "2.1.4"
+roomCommon = "2.6.1"
+roomKtx = "2.6.1"
+supportAnnotations = "28.0.0"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+androidx-room-common = { group = "androidx.room", name = "room-common", version.ref = "roomCommon" }
+androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "roomKtx" }
+support-annotations = { group = "com.android.support", name = "support-annotations", version.ref = "supportAnnotations" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+
diff --git a/Work3/WON/Mission3/gradle/wrapper/gradle-wrapper.jar b/Work3/WON/Mission3/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/Work3/WON/Mission3/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Work3/WON/Mission3/gradle/wrapper/gradle-wrapper.properties b/Work3/WON/Mission3/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..e9384f5
--- /dev/null
+++ b/Work3/WON/Mission3/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Oct 11 15:46:02 KST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Work3/WON/Mission3/gradlew b/Work3/WON/Mission3/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/Work3/WON/Mission3/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Work3/WON/Mission3/gradlew.bat b/Work3/WON/Mission3/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/Work3/WON/Mission3/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Work3/WON/Mission3/settings.gradle.kts b/Work3/WON/Mission3/settings.gradle.kts
new file mode 100644
index 0000000..f1d91db
--- /dev/null
+++ b/Work3/WON/Mission3/settings.gradle.kts
@@ -0,0 +1,26 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "Mission3"
+include(":app")
+include(":app")
+include(":app")
+
\ No newline at end of file
diff --git a/Work4/mission4/.gitignore b/Work4/mission4/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/Work4/mission4/.gitignore
@@ -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
diff --git a/Work4/mission4/.idea/.gitignore b/Work4/mission4/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Work4/mission4/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Work4/mission4/.idea/compiler.xml b/Work4/mission4/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/Work4/mission4/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/.idea/deploymentTargetSelector.xml b/Work4/mission4/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/Work4/mission4/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/.idea/gradle.xml b/Work4/mission4/.idea/gradle.xml
new file mode 100644
index 0000000..7b3006b
--- /dev/null
+++ b/Work4/mission4/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/.idea/kotlinc.xml b/Work4/mission4/.idea/kotlinc.xml
new file mode 100644
index 0000000..fdf8d99
--- /dev/null
+++ b/Work4/mission4/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/.idea/migrations.xml b/Work4/mission4/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/Work4/mission4/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/.idea/misc.xml b/Work4/mission4/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/Work4/mission4/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/.idea/runConfigurations.xml b/Work4/mission4/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/Work4/mission4/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/app/.gitignore b/Work4/mission4/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Work4/mission4/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Work4/mission4/app/build.gradle.kts b/Work4/mission4/app/build.gradle.kts
new file mode 100644
index 0000000..20425a8
--- /dev/null
+++ b/Work4/mission4/app/build.gradle.kts
@@ -0,0 +1,48 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.mission4"
+ compileSdk = 34
+
+ defaultConfig {
+ applicationId = "com.example.mission4"
+ minSdk = 24
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+dependencies {
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.activity)
+ implementation(libs.androidx.constraintlayout)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
\ No newline at end of file
diff --git a/Work4/mission4/app/proguard-rules.pro b/Work4/mission4/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Work4/mission4/app/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/Work4/mission4/app/src/androidTest/java/com/example/mission4/ExampleInstrumentedTest.kt b/Work4/mission4/app/src/androidTest/java/com/example/mission4/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..f8cf2e0
--- /dev/null
+++ b/Work4/mission4/app/src/androidTest/java/com/example/mission4/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.mission4
+
+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.mission4", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/Work4/mission4/app/src/main/AndroidManifest.xml b/Work4/mission4/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ddaa770
--- /dev/null
+++ b/Work4/mission4/app/src/main/AndroidManifest.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/app/src/main/java/com/example/mission4/MainActivity.kt b/Work4/mission4/app/src/main/java/com/example/mission4/MainActivity.kt
new file mode 100644
index 0000000..488997d
--- /dev/null
+++ b/Work4/mission4/app/src/main/java/com/example/mission4/MainActivity.kt
@@ -0,0 +1,97 @@
+package com.example.mission4
+
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.view.View
+import android.widget.Button
+import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
+import kotlinx.coroutines.*
+
+class MainActivity : AppCompatActivity() {
+
+ private lateinit var timerTextView: TextView
+ private lateinit var startButton: Button
+ private lateinit var pauseButton: Button
+ private lateinit var clearButton: Button
+
+ private var isRunning = false
+ private var elapsedTime = 0L
+ private var coroutineJob: Job? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ //상태 표시줄 색상 변경
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ window.statusBarColor = Color.parseColor("#E6E6E6")
+ }
+
+ timerTextView = findViewById(R.id.timerTextView)
+ startButton = findViewById(R.id.startButton)
+ pauseButton = findViewById(R.id.pauseButton)
+ clearButton = findViewById(R.id.clearButton)
+
+ // 초기 타이머 설정
+ timerTextView.text = "00:00,00"
+
+ startButton.setOnClickListener {
+ startTimer()
+ }
+
+ pauseButton.setOnClickListener {
+ pauseTimer()
+ }
+
+ clearButton.setOnClickListener {
+ clearTimer()
+ }
+ }
+
+ private fun startTimer() {
+ if (!isRunning) {
+ isRunning = true
+ startButton.visibility = View.GONE
+ pauseButton.visibility = View.VISIBLE
+
+ // 타이머가 시작될 때 텍스트 형식을 변경
+ timerTextView.text = formatTime(elapsedTime) // 초기 값 표시
+
+ coroutineJob = CoroutineScope(Dispatchers.Main).launch {
+ while (isRunning) {
+ elapsedTime += 10 // 10ms 단위로 증가
+ timerTextView.text = formatTime(elapsedTime)
+ delay(10) // 10ms마다 업데이트
+ }
+ }
+ }
+ }
+
+ private fun pauseTimer() {
+ isRunning = false
+ startButton.visibility = View.VISIBLE
+ pauseButton.visibility = View.GONE
+ coroutineJob?.cancel() // 코루틴 중지
+ }
+
+ private fun clearTimer() {
+ isRunning = false
+ elapsedTime = 0L
+ timerTextView.text = "00:00.00" // 초기화 시 업데이트 (이제는 점(.) 사용)
+ startButton.visibility = View.VISIBLE
+ pauseButton.visibility = View.GONE
+ coroutineJob?.cancel() // 코루틴 중지
+ }
+
+ private fun formatTime(timeInMillis: Long): String {
+ val milliseconds = (timeInMillis % 1000) / 10 //0.01초 단위로 표시
+ val seconds = (timeInMillis / 1000) % 60
+ val minutes = (timeInMillis / (1000 * 60)) % 60
+
+ return String.format("%02d:%02d.%02d", minutes, seconds, milliseconds) // 100ms 단위로 표시
+ }
+}
+
+
diff --git a/Work4/mission4/app/src/main/res/drawable/ic_launcher_background.xml b/Work4/mission4/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work4/mission4/app/src/main/res/drawable/ic_launcher_foreground.xml b/Work4/mission4/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/app/src/main/res/layout/activity_main.xml b/Work4/mission4/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..6782dad
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work4/mission4/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Work4/mission4/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Work4/mission4/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Work4/mission4/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/Work4/mission4/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Work4/mission4/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Work4/mission4/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/Work4/mission4/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Work4/mission4/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Work4/mission4/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/Work4/mission4/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Work4/mission4/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Work4/mission4/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/Work4/mission4/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Work4/mission4/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Work4/mission4/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/Work4/mission4/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Work4/mission4/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Work4/mission4/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/Work4/mission4/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Work4/mission4/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Work4/mission4/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/Work4/mission4/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Work4/mission4/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Work4/mission4/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/Work4/mission4/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Work4/mission4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Work4/mission4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/Work4/mission4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Work4/mission4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Work4/mission4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/Work4/mission4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Work4/mission4/app/src/main/res/values-night/themes.xml b/Work4/mission4/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..b5974a0
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/app/src/main/res/values/colors.xml b/Work4/mission4/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..c8524cd
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/Work4/mission4/app/src/main/res/values/strings.xml b/Work4/mission4/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..c2907d6
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ mission4
+
\ No newline at end of file
diff --git a/Work4/mission4/app/src/main/res/values/themes.xml b/Work4/mission4/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..ce62b91
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/app/src/main/res/xml/backup_rules.xml b/Work4/mission4/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/app/src/main/res/xml/data_extraction_rules.xml b/Work4/mission4/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/Work4/mission4/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work4/mission4/app/src/test/java/com/example/mission4/ExampleUnitTest.kt b/Work4/mission4/app/src/test/java/com/example/mission4/ExampleUnitTest.kt
new file mode 100644
index 0000000..72117fe
--- /dev/null
+++ b/Work4/mission4/app/src/test/java/com/example/mission4/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.mission4
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work4/mission4/build.gradle.kts b/Work4/mission4/build.gradle.kts
new file mode 100644
index 0000000..922f551
--- /dev/null
+++ b/Work4/mission4/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+}
\ No newline at end of file
diff --git a/Work4/mission4/gradle.properties b/Work4/mission4/gradle.properties
new file mode 100644
index 0000000..20e2a01
--- /dev/null
+++ b/Work4/mission4/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Work4/mission4/gradle/libs.versions.toml b/Work4/mission4/gradle/libs.versions.toml
new file mode 100644
index 0000000..faf6ca2
--- /dev/null
+++ b/Work4/mission4/gradle/libs.versions.toml
@@ -0,0 +1,26 @@
+[versions]
+agp = "8.6.0"
+kotlin = "1.9.0"
+coreKtx = "1.13.1"
+junit = "4.13.2"
+junitVersion = "1.2.1"
+espressoCore = "3.6.1"
+appcompat = "1.7.0"
+material = "1.12.0"
+activity = "1.9.2"
+constraintlayout = "2.1.4"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+
diff --git a/Work4/mission4/gradle/wrapper/gradle-wrapper.jar b/Work4/mission4/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/Work4/mission4/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Work4/mission4/gradle/wrapper/gradle-wrapper.properties b/Work4/mission4/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..31c29bf
--- /dev/null
+++ b/Work4/mission4/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sat Oct 26 16:01:22 KST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Work4/mission4/gradlew b/Work4/mission4/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/Work4/mission4/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Work4/mission4/gradlew.bat b/Work4/mission4/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/Work4/mission4/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Work4/mission4/settings.gradle.kts b/Work4/mission4/settings.gradle.kts
new file mode 100644
index 0000000..0007306
--- /dev/null
+++ b/Work4/mission4/settings.gradle.kts
@@ -0,0 +1,24 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "mission4"
+include(":app")
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/.gitignore b/Work5/FLO/Mission3/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/Work5/FLO/Mission3/.gitignore
@@ -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
diff --git a/Work5/FLO/Mission3/.idea/.gitignore b/Work5/FLO/Mission3/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Work5/FLO/Mission3/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Work5/FLO/Mission3/.idea/compiler.xml b/Work5/FLO/Mission3/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/Work5/FLO/Mission3/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/.idea/deploymentTargetSelector.xml b/Work5/FLO/Mission3/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/Work5/FLO/Mission3/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/.idea/gradle.xml b/Work5/FLO/Mission3/.idea/gradle.xml
new file mode 100644
index 0000000..7b3006b
--- /dev/null
+++ b/Work5/FLO/Mission3/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/.idea/kotlinc.xml b/Work5/FLO/Mission3/.idea/kotlinc.xml
new file mode 100644
index 0000000..fdf8d99
--- /dev/null
+++ b/Work5/FLO/Mission3/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/.idea/migrations.xml b/Work5/FLO/Mission3/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/Work5/FLO/Mission3/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/.idea/misc.xml b/Work5/FLO/Mission3/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/Work5/FLO/Mission3/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/.idea/runConfigurations.xml b/Work5/FLO/Mission3/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/Work5/FLO/Mission3/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/.gitignore b/Work5/FLO/Mission3/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Work5/FLO/Mission3/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/build.gradle.kts b/Work5/FLO/Mission3/app/build.gradle.kts
new file mode 100644
index 0000000..5826818
--- /dev/null
+++ b/Work5/FLO/Mission3/app/build.gradle.kts
@@ -0,0 +1,56 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.mission3"
+ compileSdk = 34
+
+ viewBinding {
+ enable=true
+ }
+
+ defaultConfig {
+ applicationId = "com.example.mission3"
+ minSdk = 24
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+dependencies {
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.activity)
+ implementation(libs.androidx.constraintlayout)
+ implementation(libs.androidx.room.common)
+ implementation(libs.androidx.room.ktx) // Room의 공통 라이브러리
+
+
+
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/proguard-rules.pro b/Work5/FLO/Mission3/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Work5/FLO/Mission3/app/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/AndroidManifest.xml b/Work5/FLO/Mission3/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9624502
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/AndroidManifest.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/Album.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/Album.kt
new file mode 100644
index 0000000..9aa079b
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/Album.kt
@@ -0,0 +1,8 @@
+package com.example.mission3
+
+data class Album(
+ val title: String,
+ val singer: String,
+ val coverImage: Int
+
+)
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt
new file mode 100644
index 0000000..98a2f11
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt
@@ -0,0 +1,38 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class AlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapter(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt
new file mode 100644
index 0000000..e6ccd88
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapter (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> SongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt
new file mode 100644
index 0000000..6d4ba64
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapterDrowning (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> DrowningSongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt
new file mode 100644
index 0000000..e2b4f78
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapterIdome (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> IdomeSongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt
new file mode 100644
index 0000000..16d14b0
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner1Binding
+
+class AllBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner1Binding // 이름 변경
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner1Binding.inflate(inflater, container, false) // 이름 변경
+ return binding.root
+ }
+}
+
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt
new file mode 100644
index 0000000..ec7814b
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragAudioBinding
+import com.example.mission3.databinding.FragMymusicBinding
+
+class AudioFrag : Fragment() {
+ private var _binding: FragAudioBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragAudioBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt
new file mode 100644
index 0000000..a1141c2
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt
@@ -0,0 +1,18 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class BannerViewPagerAdapter(fragment : Fragment) : FragmentStateAdapter(fragment) {
+
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position){
+ 0 -> AllBannerFragment()
+ 1 -> TwoBannerFragment()
+ else -> ThreeBannerFragment()
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt
new file mode 100644
index 0000000..49ef847
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentDetailBinding
+
+class DetailFragment : Fragment() {
+ lateinit var binding: FragmentDetailBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentDetailBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt
new file mode 100644
index 0000000..aa24713
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt
@@ -0,0 +1,40 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.example.mission3.databinding.FragmentAlbumDrowningBinding
+import com.example.mission3.databinding.FragmentAlbumIdomeBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class DrowningAlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumDrowningBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumDrowningBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapterDrowning(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt
new file mode 100644
index 0000000..45e7322
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt
@@ -0,0 +1,24 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+import com.example.mission3.databinding.FragmentSongDrowningBinding
+import com.example.mission3.databinding.FragmentSongIdomeBinding
+
+class DrowningSongFragment : Fragment() {
+ lateinit var binding: FragmentSongDrowningBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongDrowningBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt
new file mode 100644
index 0000000..47d711d
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt
@@ -0,0 +1,4 @@
+package com.example.mission3
+
+class HomeAdapter {
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt
new file mode 100644
index 0000000..e0ff126
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt
@@ -0,0 +1,45 @@
+package com.example.mission3
+
+// HomeBannerAdapter.kt
+
+
+import android.media.Image
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.recyclerview.widget.RecyclerView
+
+class HomeBannerAdapter(
+ private val bannerLayouts: List,
+ private val onItemClick: (Int) -> Unit
+) : RecyclerView.Adapter() {
+
+ inner class BannerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ init {
+ itemView.setOnClickListener {
+ val position = adapterPosition
+ if (position != RecyclerView.NO_POSITION) {
+ onItemClick(position)
+ }
+ }
+ }
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return bannerLayouts[position]
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(viewType, parent, false)
+ return BannerViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: BannerViewHolder, position: Int) {
+ // 이미지가 레이아웃 파일에 이미 설정되어 있으므로 별도의 바인딩이 필요하지 않을 수 있습니다.
+ // 그러나 필요하다면 여기에 추가적인 바인딩 로직을 구현할 수 있습니다.
+ }
+
+ override fun getItemCount(): Int = bannerLayouts.size
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt
new file mode 100644
index 0000000..53508e5
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt
@@ -0,0 +1,148 @@
+package com.example.mission3
+
+
+import android.content.Intent
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.widget.ViewPager2
+import com.example.mission3.databinding.FragmentHomeBinding
+import java.util.Timer
+import java.util.TimerTask
+
+class HomeFragment : Fragment() {
+
+ private lateinit var homeBannerVp: ViewPager2
+ private lateinit var day6Iv: ImageView
+ private lateinit var idomeIv: ImageView
+ private lateinit var drowningIv: ImageView
+ private lateinit var bannerAdapter: HomeBannerAdapter
+ private lateinit var binding: FragmentHomeBinding
+
+ private val bannerLayouts = listOf(
+ R.layout.fragment_banner_1,
+ R.layout.fragment_banner_2,
+ R.layout.fragment_banner_3
+ )
+
+ private val songDuration = 191
+ private var currentProcess = 0
+ private var isPlaying = false // 플레이 상태 확인 변수
+ private lateinit var timer: Timer
+ private val handler = Handler(Looper.getMainLooper())
+ private var currentPage = 0
+
+ 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)
+
+ //val seekBar = binding.miniPlayerSeekBar
+ //seekBar.max = songDuration
+
+ // Play/Pause 버튼 클릭 시 재생/일시 정지 처리
+
+
+ // mainPlayerCl 클릭 시 SongActivity로 이동
+
+
+ // ViewPager2 초기화 및 어댑터 설정
+ homeBannerVp = binding.homeBannerVp
+ bannerAdapter = HomeBannerAdapter(bannerLayouts) { position -> }
+ homeBannerVp.adapter = bannerAdapter
+
+ // 배너 자동 슬라이드 구현
+ startBannerAutoSlide()
+
+ // day6 ImageView 클릭 시 AlbumFragment로 이동
+ day6Iv = binding.day6Iv
+ day6Iv.setOnClickListener {
+ val fragmentAlbum = AlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbum)
+ .addToBackStack(null)
+ .commit()
+ }
+
+ // idome ImageView 클릭 시 IdomeAlbumFragment로 이동
+ idomeIv = binding.idomeIv
+ idomeIv.setOnClickListener {
+ val fragmentAlbumIdome = IdomeAlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbumIdome)
+ .addToBackStack(null)
+ .commit()
+ }
+
+ // drowning ImageView 클릭 시 IdomeAlbumFragment로 이동
+ drowningIv = binding.drowningIv
+ drowningIv.setOnClickListener {
+ val fragmentAlbumDrowning = DrowningAlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbumDrowning)
+ .addToBackStack(null)
+ .commit()
+ }
+ }
+
+
+ // 배너 자동 슬라이드 시작
+ private fun startBannerAutoSlide() {
+ handler.postDelayed(object : Runnable {
+ override fun run() {
+ currentPage = (currentPage + 1) % 3 // 3개의 배너를 순환
+ homeBannerVp.setCurrentItem(currentPage, true)
+ handler.postDelayed(this, 3000) // 3초마다 슬라이드
+ }
+ }, 3000) // 3초 후 시작
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ if (::timer.isInitialized) timer.cancel()
+ }
+
+ // 음악 재생 시작
+ private fun startMusic() {
+ isPlaying = true
+ binding.itemAlbumPlayImgIv.setImageResource(R.drawable.baseline_pause_24) // Pause 아이콘으로 변경
+ //startSeekBar() // SeekBar 업데이트 시작
+ }
+
+
+ // 음악 일시 정지
+ private fun pauseMusic() {
+ isPlaying = false
+ binding.itemAlbumPlayImgIv.setImageResource(R.drawable.baseline_play_24) // Play 아이콘으로 변경
+ if (::timer.isInitialized) timer.cancel() // 타이머 정지
+ }
+
+
+ // SeekBar 업데이트 시작
+// private fun startSeekBar() {
+// timer = Timer()
+// timer.scheduleAtFixedRate(object : TimerTask() {
+// override fun run() {
+// if (currentProcess < songDuration) {
+// currentProcess++
+// handler.post {
+// binding.miniPlayerSeekBar.progress = currentProcess
+// }
+// } else {
+// timer.cancel() // 끝나면 타이머 취소
+// }
+// }
+// }, 0, 1000) // 1초마다 진행
+// }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt
new file mode 100644
index 0000000..b516f6e
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt
@@ -0,0 +1,39 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.example.mission3.databinding.FragmentAlbumIdomeBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class IdomeAlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumIdomeBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumIdomeBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapterIdome(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt
new file mode 100644
index 0000000..cecdd3d
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt
@@ -0,0 +1,23 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+import com.example.mission3.databinding.FragmentSongIdomeBinding
+
+class IdomeSongFragment : Fragment() {
+ lateinit var binding: FragmentSongIdomeBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongIdomeBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt
new file mode 100644
index 0000000..5861211
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt
@@ -0,0 +1,192 @@
+package com.example.mission3
+
+import android.content.Context.MODE_PRIVATE
+import android.content.Intent
+import android.content.SharedPreferences
+import android.os.Bundle
+import android.widget.SeekBar
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.lifecycleScope
+import com.example.mission3.databinding.ActivityMainBinding
+import com.google.android.material.bottomnavigation.BottomNavigationView
+import kotlinx.coroutines.launch
+import java.util.*
+
+class MainActivity : AppCompatActivity() {
+ private lateinit var binding: ActivityMainBinding
+ private lateinit var sharedPreferences: SharedPreferences
+ private lateinit var bottomNavi: BottomNavigationView
+ private lateinit var dbHelper: SongDatabaseHelper
+ private lateinit var songProgressSb: SeekBar
+
+ // 곡 리스트 및 현재 인덱스
+ private val songList = listOf(
+ Song(id = 1, title = "HAPPY", singer = "DAY6(데이식스)", second = 0, playTime = 190, isPlaying = false, isLike = false, imageRes = R.drawable.happy),
+ Song(id = 2, title = "I DO ME", singer = "KiiiKiii (키키)", second = 0, playTime = 191, isPlaying = false, isLike = false, imageRes = R.drawable.idome),
+ Song(id = 3, title = "Drowning", singer = "WOODZ", second = 0, playTime = 245, isPlaying = false, isLike = false, imageRes = R.drawable.drowning)
+ )
+ private var currentSongIndex = 0
+ private var timer: Timer? = null
+ private var isPlaying = false // ▶️ 재생 상태
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ // songProgressSb를 찾고 초기화
+ songProgressSb = findViewById(R.id.mini_player_seekbar)
+
+ sharedPreferences = getSharedPreferences("MusicApp", MODE_PRIVATE)
+ dbHelper = SongDatabaseHelper(this)
+
+ // DB에 더미 데이터 삽입
+ lifecycleScope.launch {
+ insertDummySongs()
+ }
+
+ // 기본 프래그먼트
+ if (savedInstanceState == null) {
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commit()
+ }
+
+ // 상태 표시줄 색상
+ window.statusBarColor = resources.getColor(android.R.color.white, theme)
+
+ bottomNavi = binding.bottomNavi
+ bottomNavi.setOnItemSelectedListener { item ->
+ when (item.itemId) {
+ R.id.action_home -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, HomeFragment()).commit()
+ true
+ }
+ R.id.action_audio -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, AudioFrag()).commit()
+ true
+ }
+ R.id.action_search -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, SearchFrag()).commit()
+ true
+ }
+ R.id.action_mymusic -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, MyMusicFragment()).commit()
+ true
+ }
+ R.id.action_menu -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, MenuFrag()).commit()
+ true
+ }
+ else -> false
+ }
+ }
+
+ // mini-player 클릭 시 SongActivity로 이동
+ binding.mainPlayerCl.setOnClickListener {
+ val song = songList[currentSongIndex]
+ val currentTime = binding.miniPlayerSeekbar.progress // 현재 시간 (SeekBar의 위치)
+
+ // Intent에 추가 데이터 넣기
+ val intent = Intent(this, SongActivity::class.java).apply {
+ intent.putExtra("current_position", songProgressSb.progress) // 현재 진행 상태를 전달
+ putExtra("songTitle", song.title) // 곡 제목
+ putExtra("songSinger", song.singer) // 곡 아티스트
+ putExtra("songProgress", currentTime) // SeekBar의 현재 위치 (초 단위)
+ putExtra("songDuration", song.playTime) // 곡 전체 길이 (초 단위)
+ putExtra("songImageRes", song.imageRes) // 앨범
+ }
+ startActivity(intent)
+ }
+
+
+ // 이전 곡 버튼
+ binding.prevBtn.setOnClickListener {
+ currentSongIndex = if (currentSongIndex - 1 < 0) songList.size - 1 else currentSongIndex - 1
+ updateMiniPlayer(songList[currentSongIndex])
+ }
+
+ // 다음 곡 버튼
+ binding.nextBtn.setOnClickListener {
+ currentSongIndex = (currentSongIndex + 1) % songList.size
+ updateMiniPlayer(songList[currentSongIndex])
+ }
+
+ // Play/Pause 버튼
+ binding.playPauseBtn.setOnClickListener {
+ isPlaying = !isPlaying
+ if (isPlaying) {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_pause_24)
+ startSeekBar(songList[currentSongIndex])
+ } else {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ timer?.cancel()
+ }
+ }
+
+ // 초기 미니플레이어 설정
+ updateMiniPlayer(songList[currentSongIndex])
+ }
+
+ // 미니플레이어 UI 업데이트
+ private fun updateMiniPlayer(song: Song) {
+ binding.miniPlayerSongTitleTv.text = song.title
+ binding.miniPlayerSingerTv.text = song.singer
+ binding.miniPlayerSeekbar.max = song.playTime
+ binding.miniPlayerSeekbar.progress = song.second
+ saveSongId(song.id)
+
+ if (isPlaying) {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_pause_24)
+ startSeekBar(song)
+ } else {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ timer?.cancel()
+ }
+ }
+
+ // SeekBar 업데이트 타이머
+ private fun startSeekBar(song: Song) {
+ timer?.cancel()
+ var progress = binding.miniPlayerSeekbar.progress
+ timer = Timer()
+ timer?.scheduleAtFixedRate(object : TimerTask() {
+ override fun run() {
+ runOnUiThread {
+ if (progress < song.playTime) {
+ progress++
+ binding.miniPlayerSeekbar.progress = progress
+ } else {
+ timer?.cancel()
+ isPlaying = false
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ }
+ }
+ }
+ }, 1000, 1000)
+ }
+
+ // DB에 더미 데이터 삽입
+ private suspend fun insertDummySongs() {
+ for (song in songList) {
+ dbHelper.insertSong(song)
+ }
+ }
+
+ // SharedPreferences 저장/불러오기
+ private fun saveSongId(songId: Int) {
+ val editor = sharedPreferences.edit()
+ editor.putInt("songId", songId)
+ editor.putInt("songTime", binding.miniPlayerSeekbar.progress) // 현재 시간도 저장
+ editor.apply()
+ }
+
+ private fun getSongIdFromPreferences(): Int {
+ return sharedPreferences.getInt("songId", 0)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ timer?.cancel()
+ }
+}
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt
new file mode 100644
index 0000000..52d5fd8
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragMenuBinding
+import com.example.mission3.databinding.FragMymusicBinding
+
+class MenuFrag : Fragment() {
+ private var _binding: FragMenuBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragMenuBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt
new file mode 100644
index 0000000..dfcd9f4
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt
@@ -0,0 +1,19 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentMusicFileBinding
+
+class MusicFileFragment: Fragment() {
+
+ lateinit var binding: FragmentMusicFileBinding
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ binding = FragmentMusicFileBinding.inflate(inflater, container, false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt
new file mode 100644
index 0000000..a2e13b5
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt
@@ -0,0 +1,38 @@
+package com.example.mission3
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.mission3.databinding.ItemMymusicAlbumBinding
+
+class MyMusicAlbumRVAdapter(private val albumList: ArrayList) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = ItemMymusicAlbumBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bind(albumList[position])
+ holder.binding.itemMymusicAlbumMoreIv.setOnClickListener {
+ // 클릭 시 해당 아이템 삭제
+ removeItem(position)
+ }
+ }
+
+ override fun getItemCount(): Int = albumList.size
+
+ fun removeItem(position: Int) {
+ albumList.removeAt(position) // 해당 아이템 제거
+ notifyItemRemoved(position) // 아이템 제거 후 갱신
+ notifyItemRangeChanged(position, albumList.size) // 나머지 아이템 갱신
+ }
+
+ inner class ViewHolder(val binding: ItemMymusicAlbumBinding) : RecyclerView.ViewHolder(binding.root) {
+ fun bind(album: Album) {
+ binding.itemMymusicAlbumTitleTv.text = album.title
+ binding.itemMymusicAlbumSingerTv.text = album.singer
+ binding.itemMymusicAlbumCoverImgIv.setImageResource(album.coverImage)
+ }
+ }
+}
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt
new file mode 100644
index 0000000..5f61e75
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt
@@ -0,0 +1,30 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.google.android.material.tabs.TabLayoutMediator
+import com.example.mission3.databinding.FragMymusicBinding
+
+class MyMusicFragment : Fragment() {
+ private lateinit var binding: FragMymusicBinding
+ private val information = arrayListOf("저장한곡", "음악파일")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = FragMymusicBinding.inflate(inflater, container, false)
+
+ val lockerAdapter = MyMusicVPAdapter(this)
+ binding.mymusicContentVp.adapter = lockerAdapter
+ TabLayoutMediator(binding.mymusicContentTb, binding.mymusicContentVp) { tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt
new file mode 100644
index 0000000..b1771db
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt
@@ -0,0 +1,15 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class MyMusicVPAdapter (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount() : Int = 2
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> SavedSongFragment()
+ else -> MusicFileFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt
new file mode 100644
index 0000000..6222cb8
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt
@@ -0,0 +1,29 @@
+package com.example.mission3
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.mission3.databinding.RecyclerviewItemBinding
+
+class RVAdapter(private val items: MutableList) : RecyclerView.Adapter(){
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding: RecyclerviewItemBinding = RecyclerviewItemBinding
+ .inflate(LayoutInflater.from(parent.context), parent, false)
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bindItems(items[position])
+ }
+
+ override fun getItemCount(): Int = items.size
+
+ // ViewHolder 내부 클래스 정의
+ inner class ViewHolder(private val binding: RecyclerviewItemBinding) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bindItems(item: String) {
+ binding.itemAlbumTitleTv.text = item
+ }
+ }
+}
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt
new file mode 100644
index 0000000..606d3b2
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt
@@ -0,0 +1,45 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.example.mission3.databinding.FragmentSavedSongBinding
+
+class SavedSongFragment : Fragment() {
+
+ private var albumDatas = ArrayList()
+ lateinit var binding: FragmentSavedSongBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSavedSongBinding.inflate(inflater, container, false)
+
+ albumDatas.apply {
+ add(Album("HAPPY", "DAY6(데이식스)", R.drawable.happy))
+ add(Album("I DO ME", "KiiiKiii (키키)", R.drawable.idome))
+ add(Album("Drowning", "WOODZ", R.drawable.drowning))
+ add(Album("Welcome to the show", "DAY6 (데이식스)", R.drawable.happy))
+ add(Album("아니 근데 진짜", "LUCY", R.drawable.happy))
+ add(Album("B.O.M.B", "TREASURE (트레저)", R.drawable.happy))
+ add(Album("Supernova", "aespa", R.drawable.happy))
+ add(Album("April shower", "세븐틴 (SEVENTEEN)", R.drawable.happy))
+ add(Album("Blueming", "아이유 (IU)", R.drawable.happy))
+ }
+
+ val myMusicAlbumRVAdapter = MyMusicAlbumRVAdapter(albumDatas)
+ binding.mymusicMusicAlbumRv.adapter = myMusicAlbumRVAdapter
+ binding.mymusicMusicAlbumRv.layoutManager = LinearLayoutManager(requireActivity())
+
+ return binding.root
+ }
+}
+
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt
new file mode 100644
index 0000000..61c15ea
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragMymusicBinding
+import com.example.mission3.databinding.FragSearchBinding
+
+class SearchFrag : Fragment() {
+ private var _binding: FragSearchBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragSearchBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/Song.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/Song.kt
new file mode 100644
index 0000000..a6ec32e
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/Song.kt
@@ -0,0 +1,12 @@
+package com.example.mission3
+
+data class Song(
+ val title: String = "",
+ val singer: String = "",
+ var second: Int = 0,
+ var playTime: Int = 60,
+ var isPlaying: Boolean = false,
+ var isLike: Boolean = false, // 좋아요 상태 추가
+ val id: Int = 0, // Primary key를 수동으로 관리
+ val imageRes: Int = 0 // 이미지 리소스를 추가 (이미지 리소스 ID)
+)
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt
new file mode 100644
index 0000000..9b4612a
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt
@@ -0,0 +1,254 @@
+package com.example.mission3
+
+import android.content.Context.MODE_PRIVATE
+import android.content.SharedPreferences
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.os.Handler
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.edit
+import com.example.mission3.databinding.ActivitySongBinding
+
+class SongActivity : AppCompatActivity() {
+ private lateinit var binding: ActivitySongBinding
+ private lateinit var song: Song
+ private var isPlaying = false
+ private var currentTime = 0 // 현재 재생 시간 (초 단위)
+ private lateinit var sharedPreferences: SharedPreferences
+ private var isFavorite = false
+ private var songList: List = listOf() // 곡 리스트
+ private var currentSongIndex: Int = 0 // 현재 곡 인덱스
+
+ private val handler = Handler()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivitySongBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ sharedPreferences = getSharedPreferences("MyMusicApp", MODE_PRIVATE)
+
+ // Intent에서 받은 데이터를 기반으로 초기화
+ val songTitle = intent.getStringExtra("songTitle")
+ val songSinger = intent.getStringExtra("songSinger")
+ currentTime = intent.getIntExtra("songProgress", 0)
+ val songDuration = intent.getIntExtra("songDuration", 0)
+ val key = "$songTitle-$songSinger"
+ val imageResFromPrefs = sharedPreferences.getInt("${key}_imageRes", -1)
+ val imageRes = if (imageResFromPrefs != -1) imageResFromPrefs else {
+ intent.getIntExtra("songImageRes", R.drawable.happy)
+ }
+
+ // Song 객체 초기화
+ song = Song(
+ title = songTitle ?: "",
+ singer = songSinger ?: "",
+ second = currentTime,
+ playTime = songDuration,
+ isPlaying = false,
+ isLike = false,
+ id = 0,
+ imageRes = imageRes
+ )
+
+
+ songList = listOf(
+ Song("HAPPY", "DAY6(데이식스)", 0, 190, false, imageRes = R.drawable.happy),
+ Song("I DO ME", "KiiiKiii (키키)", 0, 191, false, imageRes = R.drawable.idome),
+ Song("Drowning", "WOODZ", 0, 245, false, imageRes = R.drawable.drowning)
+ )
+ currentSongIndex = songList.indexOf(song) // song에 맞는 인덱스를 찾습니다.
+
+ setPlayer(song) // 플레이어 설정
+
+ // 즐겨찾기 상태 로드
+ loadFavoriteStatus()
+ updateFavoriteButton()
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ window.statusBarColor = Color.parseColor("#FFFFFF")
+ }
+
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ binding.songSettingIb.setOnClickListener {
+ finish()
+ }
+
+ binding.playPauseButton.setOnClickListener {
+ if (isPlaying) {
+ pauseSong()
+ } else {
+ playSong()
+ }
+ }
+
+ // 즐겨찾기 버튼 클릭 리스너
+ binding.favoriteButton.setOnClickListener {
+ isFavorite = !isFavorite
+ updateFavoriteButton()
+ saveFavoriteStatus()
+ }
+
+ // 이전 곡 버튼 클릭 리스너
+ binding.skipPrevious.setOnClickListener {
+ goToPreviousSong()
+ }
+
+ // 다음 곡 버튼 클릭 리스너
+ binding.songNextIv.setOnClickListener {
+ goToNextSong()
+ }
+ }
+
+ private fun setPlayer(song: Song) {
+ binding.songTitleTv.text = song.title
+ binding.songSingerTv.text = song.singer
+ binding.songStartTimeTv.text = String.format("%02d:%02d", song.second / 60, song.second % 60)
+ binding.songEndTimeTv.text = String.format("%02d:%02d", song.playTime / 60, song.playTime % 60)
+
+ binding.songAlbumIv.setImageResource(song.imageRes)
+
+ binding.songProgressbarView.max = song.playTime * 1000
+ binding.songProgressbarView.progress = song.second * 1000
+
+ setPlayerStatus(song.isPlaying)
+ }
+
+ private fun setPlayerStatus(isPlaying: Boolean) {
+ if (isPlaying) {
+ binding.playPauseButton.setImageResource(R.drawable.baseline_pause_24)
+ binding.songProgressbarView.progressTintList = ColorStateList.valueOf(Color.parseColor("#81BEF7"))
+ startTimer() // 타이머 시작
+ } else {
+ binding.playPauseButton.setImageResource(R.drawable.baseline_play_24)
+ binding.songProgressbarView.progressTintList = ColorStateList.valueOf(Color.GRAY)
+ }
+ }
+
+ private fun startTimer() {
+ handler.postDelayed(object : Runnable {
+ override fun run() {
+ if (isPlaying) {
+ currentTime++
+ updateSeekBar() // SeekBar 업데이트
+ updateTimeDisplay() // 시간 텍스트 업데이트
+ if (currentTime < song.playTime) {
+ handler.postDelayed(this, 1000) // 1초 후에 다시 실행
+ }
+ }
+ }
+ }, 1000)
+ }
+
+ private fun updateSeekBar() {
+ binding.songProgressbarView.progress = currentTime * 1000
+ }
+
+ private fun updateTimeDisplay() {
+ val minutes = currentTime / 60
+ val seconds = currentTime % 60
+ binding.songStartTimeTv.text = String.format("%02d:%02d", minutes, seconds)
+
+ val remainingTime = song.playTime - currentTime
+ val endMinutes = remainingTime / 60
+ val endSeconds = remainingTime % 60
+ binding.songEndTimeTv.text = String.format("-%02d:%02d", endMinutes, endSeconds)
+ }
+
+ private fun playSong() {
+ isPlaying = true
+ setPlayerStatus(isPlaying)
+ }
+
+ private fun pauseSong() {
+ isPlaying = false
+ handler.removeCallbacksAndMessages(null) // 타이머 취소
+ setPlayerStatus(isPlaying)
+ }
+
+ private fun updateFavoriteButton() {
+ if (isFavorite) {
+ binding.favoriteButton.setImageResource(R.drawable.baseline_favorite_24)
+ } else {
+ binding.favoriteButton.setImageResource(R.drawable.baseline_favorite_border_24)
+ }
+ }
+
+ private fun saveFavoriteStatus() {
+ val key = "${song.title}-${song.singer}"
+ sharedPreferences.edit {
+ putBoolean(key, isFavorite)
+ putInt("${key}_imageRes", song.imageRes) // 이미지 리소스 ID 저장
+ }
+ }
+
+ private fun loadFavoriteStatus() {
+ val key = "${song.title}-${song.singer}"
+ isFavorite = sharedPreferences.getBoolean(key, false)
+ }
+
+ private fun goToPreviousSong() {
+ if (currentSongIndex > 0) {
+ currentSongIndex--
+ song = songList[currentSongIndex]
+ setPlayer(song)
+ stopSong()
+ playSong()
+
+ sharedPreferences.edit {
+ putInt("current_song_index", currentSongIndex)
+ }
+ }
+ }
+
+ private fun goToNextSong() {
+ if (currentSongIndex < songList.size - 1) {
+ currentSongIndex++
+ song = songList[currentSongIndex]
+ currentTime = 0 // 시간 초기화
+ setPlayer(song)
+ stopSong()
+ playSong()
+
+ sharedPreferences.edit {
+ putInt("current_song_index", currentSongIndex)
+ }
+ }
+ }
+
+ private fun stopSong() {
+ // 곡 멈추기
+ isPlaying = false
+ handler.removeCallbacksAndMessages(null)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ // 타이머는 멈추지 않고 상태 유지
+ }
+
+ override fun onResume() {
+ super.onResume()
+ // 화면이 다시 보여질 때 타이머가 계속 진행되도록 설정
+ if (isPlaying) {
+ startTimer() // 타이머 다시 시작
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ handler.removeCallbacksAndMessages(null) // 화면 종료 시 타이머 정지
+ }
+
+ override fun onSupportNavigateUp(): Boolean {
+ onBackPressed()
+ return true
+ }
+}
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt
new file mode 100644
index 0000000..56317b3
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt
@@ -0,0 +1,146 @@
+package com.example.mission3
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import android.database.Cursor
+import android.content.ContentValues
+import android.database.SQLException
+import android.database.sqlite.SQLiteOpenHelper
+
+
+class SongDatabaseHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
+
+ companion object {
+ private const val DATABASE_NAME = "songs.db"
+ private const val DATABASE_VERSION = 1
+
+ // 테이블 및 컬럼 이름
+ const val TABLE_SONGS = "songs"
+ const val COLUMN_ID = "id"
+ const val COLUMN_TITLE = "title"
+ const val COLUMN_SINGER = "singer"
+ const val COLUMN_SECOND = "second"
+ const val COLUMN_PLAYTIME = "playTime"
+ const val COLUMN_ISPLAYING = "isPlaying"
+ const val COLUMN_ISLIKE = "isLike"
+ }
+
+ override fun onCreate(db: SQLiteDatabase?) {
+ val createTableQuery = """
+ CREATE TABLE $TABLE_SONGS (
+ $COLUMN_ID INTEGER PRIMARY KEY AUTOINCREMENT,
+ $COLUMN_TITLE TEXT,
+ $COLUMN_SINGER TEXT,
+ $COLUMN_SECOND INTEGER,
+ $COLUMN_PLAYTIME INTEGER,
+ $COLUMN_ISPLAYING INTEGER,
+ $COLUMN_ISLIKE INTEGER
+ )
+ """
+ db?.execSQL(createTableQuery)
+ }
+
+ override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
+ db?.execSQL("DROP TABLE IF EXISTS $TABLE_SONGS")
+ onCreate(db)
+ }
+
+ // Song 삽입 메서드
+ fun insertSong(song: Song): Long {
+ val db = writableDatabase
+ val values = ContentValues().apply {
+ put(COLUMN_TITLE, song.title)
+ put(COLUMN_SINGER, song.singer)
+ put(COLUMN_SECOND, song.second)
+ put(COLUMN_PLAYTIME, song.playTime)
+ put(COLUMN_ISPLAYING, if (song.isPlaying) 1 else 0)
+ put(COLUMN_ISLIKE, if (song.isLike) 1 else 0)
+ }
+
+ return db.insert(TABLE_SONGS, null, values)
+ }
+
+ // Song 업데이트 메서드
+ fun updateSong(song: Song) {
+ val db = writableDatabase
+ val values = ContentValues().apply {
+ put(COLUMN_TITLE, song.title)
+ put(COLUMN_SINGER, song.singer)
+ put(COLUMN_SECOND, song.second)
+ put(COLUMN_PLAYTIME, song.playTime)
+ put(COLUMN_ISPLAYING, if (song.isPlaying) 1 else 0)
+ put(COLUMN_ISLIKE, if (song.isLike) 1 else 0)
+ }
+
+ db.update(TABLE_SONGS, values, "$COLUMN_ID = ?", arrayOf(song.id.toString()))
+ }
+
+ // ID로 Song 조회 메서드
+ @SuppressLint("Range")
+ fun getSongById(id: Int): Song? {
+ val db = readableDatabase
+ val cursor: Cursor = db.query(
+ TABLE_SONGS,
+ null,
+ "$COLUMN_ID = ?",
+ arrayOf(id.toString()),
+ null,
+ null,
+ null
+ )
+
+ return if (cursor.moveToFirst()) {
+ val title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE))
+ val singer = cursor.getString(cursor.getColumnIndex(COLUMN_SINGER))
+ val second = cursor.getInt(cursor.getColumnIndex(COLUMN_SECOND))
+ val playTime = cursor.getInt(cursor.getColumnIndex(COLUMN_PLAYTIME))
+ val isPlaying = cursor.getInt(cursor.getColumnIndex(COLUMN_ISPLAYING)) == 1
+ val isLike = cursor.getInt(cursor.getColumnIndex(COLUMN_ISLIKE)) == 1
+ val songId = cursor.getInt(cursor.getColumnIndex(COLUMN_ID))
+
+ Song(title, singer, second, playTime, isPlaying, isLike, songId)
+ } else {
+ null
+ }
+ }
+
+ // 모든 Song 조회 메서드
+ @SuppressLint("Range")
+ fun getAllSongs(): List {
+ val songList = mutableListOf()
+ val db = readableDatabase
+ val cursor: Cursor = db.query(
+ TABLE_SONGS,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+
+ if (cursor.moveToFirst()) {
+ do {
+ val title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE))
+ val singer = cursor.getString(cursor.getColumnIndex(COLUMN_SINGER))
+ val second = cursor.getInt(cursor.getColumnIndex(COLUMN_SECOND))
+ val playTime = cursor.getInt(cursor.getColumnIndex(COLUMN_PLAYTIME))
+ val isPlaying = cursor.getInt(cursor.getColumnIndex(COLUMN_ISPLAYING)) == 1
+ val isLike = cursor.getInt(cursor.getColumnIndex(COLUMN_ISLIKE)) == 1
+ val songId = cursor.getInt(cursor.getColumnIndex(COLUMN_ID))
+
+ songList.add(Song(title, singer, second, playTime, isPlaying, isLike, songId))
+ } while (cursor.moveToNext())
+ }
+
+ cursor.close()
+ return songList
+ }
+
+ // Song 삭제 메서드
+ fun deleteSong(id: Int) {
+ val db = writableDatabase
+ db.delete(TABLE_SONGS, "$COLUMN_ID = ?", arrayOf(id.toString()))
+ }
+}
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt
new file mode 100644
index 0000000..56f6e2a
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+
+class SongFragment : Fragment() {
+ lateinit var binding: FragmentSongBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt
new file mode 100644
index 0000000..9314d0f
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner3Binding
+
+class ThreeBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner3Binding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner3Binding.inflate(inflater,container,false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt
new file mode 100644
index 0000000..879e2d7
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner2Binding
+
+class TwoBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner2Binding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner2Binding.inflate(inflater,container,false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt
new file mode 100644
index 0000000..cb0b9b0
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+
+import com.example.mission3.databinding.FragmentVideoBinding
+
+class ViedoFragment : Fragment() {
+ lateinit var binding: FragmentVideoBinding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentVideoBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/banner1.jpg b/Work5/FLO/Mission3/app/src/main/res/drawable/banner1.jpg
new file mode 100644
index 0000000..81524e1
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/drawable/banner1.jpg differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/banner2.jpg b/Work5/FLO/Mission3/app/src/main/res/drawable/banner2.jpg
new file mode 100644
index 0000000..bc20bf4
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/drawable/banner2.jpg differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/banner3.jpg b/Work5/FLO/Mission3/app/src/main/res/drawable/banner3.jpg
new file mode 100644
index 0000000..8b55d5f
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/drawable/banner3.jpg differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml
new file mode 100644
index 0000000..99f85de
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml
new file mode 100644
index 0000000..1a69b23
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml
new file mode 100644
index 0000000..6e3d747
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_audio_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_audio_24.xml
new file mode 100644
index 0000000..82ea4d3
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_audio_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_check_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_check_24.xml
new file mode 100644
index 0000000..356e998
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_check_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml
new file mode 100644
index 0000000..badf5ea
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml
new file mode 100644
index 0000000..2acceab
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_home_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_home_24.xml
new file mode 100644
index 0000000..20cb4d6
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_home_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml
new file mode 100644
index 0000000..0e5587b
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml
new file mode 100644
index 0000000..1146d4c
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml
new file mode 100644
index 0000000..a7912d8
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_menu_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_menu_24.xml
new file mode 100644
index 0000000..75c361f
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_menu_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml
new file mode 100644
index 0000000..52ede6a
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml
new file mode 100644
index 0000000..c9c2ad9
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_next_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_next_24.xml
new file mode 100644
index 0000000..4904368
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_next_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_pause_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_pause_24.xml
new file mode 100644
index 0000000..ae853f2
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_pause_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml
new file mode 100644
index 0000000..1e24cf3
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_play_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_play_24.xml
new file mode 100644
index 0000000..b176182
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_play_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_play_more24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_play_more24.xml
new file mode 100644
index 0000000..5ffb98a
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_play_more24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml
new file mode 100644
index 0000000..c7d89f1
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml
new file mode 100644
index 0000000..151a3e1
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_search_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_search_24.xml
new file mode 100644
index 0000000..d29c6ea
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_search_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml
new file mode 100644
index 0000000..5a79f5e
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml
new file mode 100644
index 0000000..7951d71
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_star_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_star_24.xml
new file mode 100644
index 0000000..925b973
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_star_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml
new file mode 100644
index 0000000..f775f11
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_volume_24.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_volume_24.xml
new file mode 100644
index 0000000..a53186e
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/baseline_volume_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/drowning.jpg b/Work5/FLO/Mission3/app/src/main/res/drawable/drowning.jpg
new file mode 100644
index 0000000..97fa652
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/drawable/drowning.jpg differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/happy.jpg b/Work5/FLO/Mission3/app/src/main/res/drawable/happy.jpg
new file mode 100644
index 0000000..6b24b63
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/drawable/happy.jpg differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/ic_launcher_background.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml b/Work5/FLO/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/drawable/idome.jpg b/Work5/FLO/Mission3/app/src/main/res/drawable/idome.jpg
new file mode 100644
index 0000000..b40b38f
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/drawable/idome.jpg differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/activity_main.xml b/Work5/FLO/Mission3/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..dded351
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/activity_song.xml b/Work5/FLO/Mission3/app/src/main/res/layout/activity_song.xml
new file mode 100644
index 0000000..6be6395
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/activity_song.xml
@@ -0,0 +1,283 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/frag_audio.xml b/Work5/FLO/Mission3/app/src/main/res/layout/frag_audio.xml
new file mode 100644
index 0000000..ae66603
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/frag_audio.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/frag_menu.xml b/Work5/FLO/Mission3/app/src/main/res/layout/frag_menu.xml
new file mode 100644
index 0000000..d6811d0
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/frag_menu.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/frag_mymusic.xml b/Work5/FLO/Mission3/app/src/main/res/layout/frag_mymusic.xml
new file mode 100644
index 0000000..7f4cef8
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/frag_mymusic.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/frag_search.xml b/Work5/FLO/Mission3/app/src/main/res/layout/frag_search.xml
new file mode 100644
index 0000000..d523e6e
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/frag_search.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_album.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_album.xml
new file mode 100644
index 0000000..825ab0d
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_album.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_album_drowning.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_album_drowning.xml
new file mode 100644
index 0000000..e341853
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_album_drowning.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_album_idome.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_album_idome.xml
new file mode 100644
index 0000000..6792827
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_album_idome.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_banner_1.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_banner_1.xml
new file mode 100644
index 0000000..142a6b8
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_banner_1.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_banner_2.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_banner_2.xml
new file mode 100644
index 0000000..f194ac2
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_banner_2.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_banner_3.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_banner_3.xml
new file mode 100644
index 0000000..5923f27
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_banner_3.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_detail.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_detail.xml
new file mode 100644
index 0000000..413125c
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_detail.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_home.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_home.xml
new file mode 100644
index 0000000..859952e
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_home.xml
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_music_file.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_music_file.xml
new file mode 100644
index 0000000..77d9ef6
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_music_file.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_saved_song.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_saved_song.xml
new file mode 100644
index 0000000..6130fb1
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_saved_song.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_song.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_song.xml
new file mode 100644
index 0000000..7da782e
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_song.xml
@@ -0,0 +1,422 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_song_drowning.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_song_drowning.xml
new file mode 100644
index 0000000..6566743
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_song_drowning.xml
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_song_idome.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_song_idome.xml
new file mode 100644
index 0000000..e92ec6f
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_song_idome.xml
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/fragment_video.xml b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_video.xml
new file mode 100644
index 0000000..e86dad1
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/fragment_video.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/item_mymusic_album.xml b/Work5/FLO/Mission3/app/src/main/res/layout/item_mymusic_album.xml
new file mode 100644
index 0000000..b515f94
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/item_mymusic_album.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/layout/recyclerview_item.xml b/Work5/FLO/Mission3/app/src/main/res/layout/recyclerview_item.xml
new file mode 100644
index 0000000..30c304a
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/layout/recyclerview_item.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/menu/menu.xml b/Work5/FLO/Mission3/app/src/main/res/menu/menu.xml
new file mode 100644
index 0000000..4472d4b
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/menu/menu.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Work5/FLO/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Work5/FLO/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Work5/FLO/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Work5/FLO/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Work5/FLO/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Work5/FLO/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Work5/FLO/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Work5/FLO/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Work5/FLO/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Work5/FLO/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Work5/FLO/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Work5/FLO/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/Work5/FLO/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Work5/FLO/Mission3/app/src/main/res/values-night/themes.xml b/Work5/FLO/Mission3/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..ebeb9cd
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/values/colors.xml b/Work5/FLO/Mission3/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..aacedae
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/values/strings.xml b/Work5/FLO/Mission3/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..90c25e1
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/values/strings.xml
@@ -0,0 +1,12 @@
+
+ Mission3
+ NewJeans 이미지
+ 배너 이미지
+ Home
+ Album
+ Audio
+ Search
+ My Music
+ Menu
+ Play/Pause
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/values/themes.xml b/Work5/FLO/Mission3/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..66e5370
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/values/themes.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/xml/backup_rules.xml b/Work5/FLO/Mission3/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/main/res/xml/data_extraction_rules.xml b/Work5/FLO/Mission3/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt b/Work5/FLO/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt
new file mode 100644
index 0000000..6c8895e
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.mission3
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt b/Work5/FLO/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt
new file mode 100644
index 0000000..49f80b4
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.missionn3
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt b/Work5/FLO/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt
new file mode 100644
index 0000000..e500fb8
--- /dev/null
+++ b/Work5/FLO/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.myapplication
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/build.gradle.kts b/Work5/FLO/Mission3/build.gradle.kts
new file mode 100644
index 0000000..922f551
--- /dev/null
+++ b/Work5/FLO/Mission3/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+}
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/gradle.properties b/Work5/FLO/Mission3/gradle.properties
new file mode 100644
index 0000000..20e2a01
--- /dev/null
+++ b/Work5/FLO/Mission3/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Work5/FLO/Mission3/gradle/libs.versions.toml b/Work5/FLO/Mission3/gradle/libs.versions.toml
new file mode 100644
index 0000000..0b1b772
--- /dev/null
+++ b/Work5/FLO/Mission3/gradle/libs.versions.toml
@@ -0,0 +1,32 @@
+[versions]
+agp = "8.6.0"
+kotlin = "1.9.0"
+coreKtx = "1.13.1"
+junit = "4.13.2"
+junitVersion = "1.2.1"
+espressoCore = "3.6.1"
+appcompat = "1.7.0"
+material = "1.12.0"
+activity = "1.9.2"
+constraintlayout = "2.1.4"
+roomCommon = "2.6.1"
+roomKtx = "2.6.1"
+supportAnnotations = "28.0.0"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+androidx-room-common = { group = "androidx.room", name = "room-common", version.ref = "roomCommon" }
+androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "roomKtx" }
+support-annotations = { group = "com.android.support", name = "support-annotations", version.ref = "supportAnnotations" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+
diff --git a/Work5/FLO/Mission3/gradle/wrapper/gradle-wrapper.jar b/Work5/FLO/Mission3/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/Work5/FLO/Mission3/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Work5/FLO/Mission3/gradle/wrapper/gradle-wrapper.properties b/Work5/FLO/Mission3/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..e9384f5
--- /dev/null
+++ b/Work5/FLO/Mission3/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Oct 11 15:46:02 KST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Work5/FLO/Mission3/gradlew b/Work5/FLO/Mission3/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/Work5/FLO/Mission3/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Work5/FLO/Mission3/gradlew.bat b/Work5/FLO/Mission3/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/Work5/FLO/Mission3/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Work5/FLO/Mission3/settings.gradle.kts b/Work5/FLO/Mission3/settings.gradle.kts
new file mode 100644
index 0000000..f1d91db
--- /dev/null
+++ b/Work5/FLO/Mission3/settings.gradle.kts
@@ -0,0 +1,26 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "Mission3"
+include(":app")
+include(":app")
+include(":app")
+
\ No newline at end of file
diff --git a/Work5/mission_5/.gitignore b/Work5/mission_5/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/Work5/mission_5/.gitignore
@@ -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
diff --git a/Work5/mission_5/.idea/.gitignore b/Work5/mission_5/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Work5/mission_5/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Work5/mission_5/.idea/compiler.xml b/Work5/mission_5/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/Work5/mission_5/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/.idea/deploymentTargetSelector.xml b/Work5/mission_5/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/Work5/mission_5/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/.idea/gradle.xml b/Work5/mission_5/.idea/gradle.xml
new file mode 100644
index 0000000..ae733f1
--- /dev/null
+++ b/Work5/mission_5/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/.idea/kotlinc.xml b/Work5/mission_5/.idea/kotlinc.xml
new file mode 100644
index 0000000..148fdd2
--- /dev/null
+++ b/Work5/mission_5/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/.idea/migrations.xml b/Work5/mission_5/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/Work5/mission_5/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/.idea/misc.xml b/Work5/mission_5/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/Work5/mission_5/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/.idea/runConfigurations.xml b/Work5/mission_5/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/Work5/mission_5/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/.gitignore b/Work5/mission_5/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Work5/mission_5/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Work5/mission_5/app/build.gradle.kts b/Work5/mission_5/app/build.gradle.kts
new file mode 100644
index 0000000..7f0c2d9
--- /dev/null
+++ b/Work5/mission_5/app/build.gradle.kts
@@ -0,0 +1,48 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.mission_5"
+ compileSdk = 35
+
+ defaultConfig {
+ applicationId = "com.example.mission_5"
+ minSdk = 24
+ targetSdk = 35
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+}
+
+dependencies {
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.activity)
+ implementation(libs.androidx.constraintlayout)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
\ No newline at end of file
diff --git a/Work5/mission_5/app/proguard-rules.pro b/Work5/mission_5/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Work5/mission_5/app/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/androidTest/java/com/example/mission_5/ExampleInstrumentedTest.kt b/Work5/mission_5/app/src/androidTest/java/com/example/mission_5/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..4bc03a6
--- /dev/null
+++ b/Work5/mission_5/app/src/androidTest/java/com/example/mission_5/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.mission_5
+
+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.mission_5", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/main/AndroidManifest.xml b/Work5/mission_5/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..dac9560
--- /dev/null
+++ b/Work5/mission_5/app/src/main/AndroidManifest.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/main/java/com/example/mission_5/ConfirmActivity.kt b/Work5/mission_5/app/src/main/java/com/example/mission_5/ConfirmActivity.kt
new file mode 100644
index 0000000..b0b9fe7
--- /dev/null
+++ b/Work5/mission_5/app/src/main/java/com/example/mission_5/ConfirmActivity.kt
@@ -0,0 +1,17 @@
+package com.example.mission_5
+
+import android.os.Bundle
+import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
+
+class ConfirmActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_confirm)
+
+ val memo = intent.getStringExtra("memo")
+ val memoTextView = findViewById(R.id.memoTextView)
+ memoTextView.text = memo
+ }
+}
diff --git a/Work5/mission_5/app/src/main/java/com/example/mission_5/MainActivity.kt b/Work5/mission_5/app/src/main/java/com/example/mission_5/MainActivity.kt
new file mode 100644
index 0000000..b11beba
--- /dev/null
+++ b/Work5/mission_5/app/src/main/java/com/example/mission_5/MainActivity.kt
@@ -0,0 +1,57 @@
+package com.example.mission_5
+
+import android.app.AlertDialog
+import android.content.Intent
+import android.os.Bundle
+import android.widget.Button
+import android.widget.EditText
+import androidx.appcompat.app.AppCompatActivity
+
+class MainActivity : AppCompatActivity() {
+
+ private lateinit var memoEditText: EditText
+
+ companion object {
+ var savedMemo: String? = null
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+
+ memoEditText = findViewById(R.id.memoEditText)
+ val nextButton = findViewById(R.id.nextButton)
+
+ nextButton.setOnClickListener {
+ val intent = Intent(this, ConfirmActivity::class.java)
+ intent.putExtra("memo", memoEditText.text.toString())
+ startActivity(intent)
+ }
+ }
+
+ override fun onPause() {
+ super.onPause()
+ savedMemo = memoEditText.text.toString()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ savedMemo?.let {
+ memoEditText.setText(it)
+ }
+ }
+
+ override fun onRestart() {
+ super.onRestart()
+
+ val builder = AlertDialog.Builder(this)
+ builder.setTitle("다시 작성할까요?")
+ builder.setMessage("이전에 작성한 내용을 다시 작성하시겠습니까?")
+ builder.setPositiveButton("예") { _, _ -> /* 그대로 유지 */ }
+ builder.setNegativeButton("아니요") { _, _ ->
+ savedMemo = null
+ memoEditText.setText("")
+ }
+ builder.show()
+ }
+}
diff --git a/Work5/mission_5/app/src/main/res/drawable/ic_launcher_background.xml b/Work5/mission_5/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work5/mission_5/app/src/main/res/drawable/ic_launcher_foreground.xml b/Work5/mission_5/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/main/res/layout/activity_confirm.xml b/Work5/mission_5/app/src/main/res/layout/activity_confirm.xml
new file mode 100644
index 0000000..75a2a54
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/layout/activity_confirm.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/Work5/mission_5/app/src/main/res/layout/activity_main.xml b/Work5/mission_5/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..1c66dcd
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
diff --git a/Work5/mission_5/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Work5/mission_5/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Work5/mission_5/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Work5/mission_5/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/Work5/mission_5/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Work5/mission_5/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Work5/mission_5/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/Work5/mission_5/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Work5/mission_5/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Work5/mission_5/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/Work5/mission_5/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Work5/mission_5/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Work5/mission_5/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/Work5/mission_5/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Work5/mission_5/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Work5/mission_5/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/Work5/mission_5/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Work5/mission_5/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Work5/mission_5/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/Work5/mission_5/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Work5/mission_5/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Work5/mission_5/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/Work5/mission_5/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Work5/mission_5/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Work5/mission_5/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/Work5/mission_5/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Work5/mission_5/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Work5/mission_5/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/Work5/mission_5/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Work5/mission_5/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Work5/mission_5/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/Work5/mission_5/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Work5/mission_5/app/src/main/res/values-night/themes.xml b/Work5/mission_5/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..c31724a
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/main/res/values/colors.xml b/Work5/mission_5/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..c8524cd
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/main/res/values/strings.xml b/Work5/mission_5/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..57fb87e
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ mission_5
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/main/res/values/themes.xml b/Work5/mission_5/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..2bdb7ec
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/main/res/xml/backup_rules.xml b/Work5/mission_5/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/main/res/xml/data_extraction_rules.xml b/Work5/mission_5/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/Work5/mission_5/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work5/mission_5/app/src/test/java/com/example/mission_5/ExampleUnitTest.kt b/Work5/mission_5/app/src/test/java/com/example/mission_5/ExampleUnitTest.kt
new file mode 100644
index 0000000..1cff19e
--- /dev/null
+++ b/Work5/mission_5/app/src/test/java/com/example/mission_5/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.mission_5
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work5/mission_5/build.gradle.kts b/Work5/mission_5/build.gradle.kts
new file mode 100644
index 0000000..922f551
--- /dev/null
+++ b/Work5/mission_5/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+}
\ No newline at end of file
diff --git a/Work5/mission_5/gradle.properties b/Work5/mission_5/gradle.properties
new file mode 100644
index 0000000..20e2a01
--- /dev/null
+++ b/Work5/mission_5/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Work5/mission_5/gradle/libs.versions.toml b/Work5/mission_5/gradle/libs.versions.toml
new file mode 100644
index 0000000..df613bf
--- /dev/null
+++ b/Work5/mission_5/gradle/libs.versions.toml
@@ -0,0 +1,26 @@
+[versions]
+agp = "8.8.0"
+kotlin = "1.9.24"
+coreKtx = "1.16.0"
+junit = "4.13.2"
+junitVersion = "1.2.1"
+espressoCore = "3.6.1"
+appcompat = "1.7.0"
+material = "1.12.0"
+activity = "1.10.1"
+constraintlayout = "2.2.1"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+
diff --git a/Work5/mission_5/gradle/wrapper/gradle-wrapper.jar b/Work5/mission_5/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/Work5/mission_5/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Work5/mission_5/gradle/wrapper/gradle-wrapper.properties b/Work5/mission_5/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..768f09e
--- /dev/null
+++ b/Work5/mission_5/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon May 05 17:53:56 KST 2025
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Work5/mission_5/gradlew b/Work5/mission_5/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/Work5/mission_5/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Work5/mission_5/gradlew.bat b/Work5/mission_5/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/Work5/mission_5/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Work5/mission_5/settings.gradle.kts b/Work5/mission_5/settings.gradle.kts
new file mode 100644
index 0000000..235b39f
--- /dev/null
+++ b/Work5/mission_5/settings.gradle.kts
@@ -0,0 +1,24 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "mission_5"
+include(":app")
+
\ No newline at end of file
diff --git a/Work6/Mission3/.gitignore b/Work6/Mission3/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/Work6/Mission3/.gitignore
@@ -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
diff --git a/Work6/Mission3/.idea/.gitignore b/Work6/Mission3/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Work6/Mission3/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Work6/Mission3/.idea/compiler.xml b/Work6/Mission3/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/Work6/Mission3/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/.idea/deploymentTargetSelector.xml b/Work6/Mission3/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/Work6/Mission3/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/.idea/gradle.xml b/Work6/Mission3/.idea/gradle.xml
new file mode 100644
index 0000000..7b3006b
--- /dev/null
+++ b/Work6/Mission3/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/.idea/kotlinc.xml b/Work6/Mission3/.idea/kotlinc.xml
new file mode 100644
index 0000000..fdf8d99
--- /dev/null
+++ b/Work6/Mission3/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/.idea/migrations.xml b/Work6/Mission3/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/Work6/Mission3/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/.idea/misc.xml b/Work6/Mission3/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/Work6/Mission3/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/.idea/runConfigurations.xml b/Work6/Mission3/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/Work6/Mission3/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/.gitignore b/Work6/Mission3/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Work6/Mission3/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Work6/Mission3/app/build.gradle.kts b/Work6/Mission3/app/build.gradle.kts
new file mode 100644
index 0000000..5826818
--- /dev/null
+++ b/Work6/Mission3/app/build.gradle.kts
@@ -0,0 +1,56 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.mission3"
+ compileSdk = 34
+
+ viewBinding {
+ enable=true
+ }
+
+ defaultConfig {
+ applicationId = "com.example.mission3"
+ minSdk = 24
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+dependencies {
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.activity)
+ implementation(libs.androidx.constraintlayout)
+ implementation(libs.androidx.room.common)
+ implementation(libs.androidx.room.ktx) // Room의 공통 라이브러리
+
+
+
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/proguard-rules.pro b/Work6/Mission3/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Work6/Mission3/app/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/AndroidManifest.xml b/Work6/Mission3/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9624502
--- /dev/null
+++ b/Work6/Mission3/app/src/main/AndroidManifest.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/Album.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/Album.kt
new file mode 100644
index 0000000..9aa079b
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/Album.kt
@@ -0,0 +1,8 @@
+package com.example.mission3
+
+data class Album(
+ val title: String,
+ val singer: String,
+ val coverImage: Int
+
+)
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt
new file mode 100644
index 0000000..98a2f11
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt
@@ -0,0 +1,38 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class AlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapter(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt
new file mode 100644
index 0000000..e6ccd88
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapter (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> SongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt
new file mode 100644
index 0000000..6d4ba64
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapterDrowning (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> DrowningSongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt
new file mode 100644
index 0000000..e2b4f78
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapterIdome (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> IdomeSongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt
new file mode 100644
index 0000000..16d14b0
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner1Binding
+
+class AllBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner1Binding // 이름 변경
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner1Binding.inflate(inflater, container, false) // 이름 변경
+ return binding.root
+ }
+}
+
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt
new file mode 100644
index 0000000..ec7814b
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragAudioBinding
+import com.example.mission3.databinding.FragMymusicBinding
+
+class AudioFrag : Fragment() {
+ private var _binding: FragAudioBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragAudioBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt
new file mode 100644
index 0000000..a1141c2
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt
@@ -0,0 +1,18 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class BannerViewPagerAdapter(fragment : Fragment) : FragmentStateAdapter(fragment) {
+
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position){
+ 0 -> AllBannerFragment()
+ 1 -> TwoBannerFragment()
+ else -> ThreeBannerFragment()
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt
new file mode 100644
index 0000000..49ef847
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentDetailBinding
+
+class DetailFragment : Fragment() {
+ lateinit var binding: FragmentDetailBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentDetailBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt
new file mode 100644
index 0000000..aa24713
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt
@@ -0,0 +1,40 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.example.mission3.databinding.FragmentAlbumDrowningBinding
+import com.example.mission3.databinding.FragmentAlbumIdomeBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class DrowningAlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumDrowningBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumDrowningBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapterDrowning(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt
new file mode 100644
index 0000000..45e7322
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt
@@ -0,0 +1,24 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+import com.example.mission3.databinding.FragmentSongDrowningBinding
+import com.example.mission3.databinding.FragmentSongIdomeBinding
+
+class DrowningSongFragment : Fragment() {
+ lateinit var binding: FragmentSongDrowningBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongDrowningBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/FavoriteSongsAdapter.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/FavoriteSongsAdapter.kt
new file mode 100644
index 0000000..381fe7c
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/FavoriteSongsAdapter.kt
@@ -0,0 +1,4 @@
+package com.example.mission3
+
+class FavoriteSongsAdapter {
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt
new file mode 100644
index 0000000..47d711d
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt
@@ -0,0 +1,4 @@
+package com.example.mission3
+
+class HomeAdapter {
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt
new file mode 100644
index 0000000..e0ff126
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt
@@ -0,0 +1,45 @@
+package com.example.mission3
+
+// HomeBannerAdapter.kt
+
+
+import android.media.Image
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.recyclerview.widget.RecyclerView
+
+class HomeBannerAdapter(
+ private val bannerLayouts: List,
+ private val onItemClick: (Int) -> Unit
+) : RecyclerView.Adapter() {
+
+ inner class BannerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ init {
+ itemView.setOnClickListener {
+ val position = adapterPosition
+ if (position != RecyclerView.NO_POSITION) {
+ onItemClick(position)
+ }
+ }
+ }
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return bannerLayouts[position]
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(viewType, parent, false)
+ return BannerViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: BannerViewHolder, position: Int) {
+ // 이미지가 레이아웃 파일에 이미 설정되어 있으므로 별도의 바인딩이 필요하지 않을 수 있습니다.
+ // 그러나 필요하다면 여기에 추가적인 바인딩 로직을 구현할 수 있습니다.
+ }
+
+ override fun getItemCount(): Int = bannerLayouts.size
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt
new file mode 100644
index 0000000..fff9aa8
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt
@@ -0,0 +1,201 @@
+package com.example.mission3
+
+
+import android.content.Intent
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import androidx.viewpager2.widget.ViewPager2
+import com.example.mission3.databinding.FragmentHomeBinding
+import java.util.Timer
+import java.util.TimerTask
+
+class HomeFragment : Fragment() {
+
+ private lateinit var homeBannerVp: ViewPager2
+ private lateinit var day6Iv: ImageView
+ private lateinit var idomeIv: ImageView
+ private lateinit var drowningIv: ImageView
+ private lateinit var bannerAdapter: HomeBannerAdapter
+ private lateinit var binding: FragmentHomeBinding
+
+ private lateinit var songViewModel: SongViewModel
+
+
+ private val bannerLayouts = listOf(
+ R.layout.fragment_banner_1,
+ R.layout.fragment_banner_2,
+ R.layout.fragment_banner_3
+ )
+
+ private val songDuration = 191
+ private var currentProcess = 0
+ private var isPlaying = false // 플레이 상태 확인 변수
+ private lateinit var timer: Timer
+ private val handler = Handler(Looper.getMainLooper())
+ private var currentPage = 0
+
+ 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)
+
+ songViewModel = ViewModelProvider(requireActivity())[SongViewModel::class.java]
+
+
+ // Play 버튼 클릭 시 "HAPPY" 노래 설정
+ val playButton1 = view.findViewById(R.id.item_album_play_img_iv)
+ playButton1.setOnClickListener {
+ val day6Song = Song("HAPPY", "DAY6(데이식스)", 0, 190, false, false, R.drawable.happy)
+ songViewModel.currentSong.value = day6Song
+ }
+
+ // day6 ImageView 클릭 시 "DAY6 - Happy" 노래 설정
+ day6Iv = binding.day6Iv
+ day6Iv.setOnClickListener {
+ val day6Song = Song("HAPPY", "DAY6(데이식스)", 0, 190, false, false, R.drawable.happy)
+ songViewModel.currentSong.value = day6Song
+ }
+
+ // Play 버튼 클릭 시 "I DO ME" 노래 설정
+ val playButton2 = view.findViewById(R.id.item_album_play_img_iv2)
+ playButton2.setOnClickListener {
+ val kiiikiiiSong = Song("I DO ME", "KiiiKiii (키키)", 0, 191, false, false, R.drawable.idome)
+ songViewModel.currentSong.value = kiiikiiiSong
+ }
+
+ // idome ImageView 클릭 시 "I DO ME - KiiiKiii" 노래 설정
+ idomeIv = binding.idomeIv
+ idomeIv.setOnClickListener {
+ val kiiikiiiSong = Song("I DO ME", "KiiiKiii (키키)", 0, 191, false, false, R.drawable.idome)
+ songViewModel.currentSong.value = kiiikiiiSong
+ }
+
+ // Play 버튼 클릭 시 "Drowning" 노래 설정
+ val playButton3 = view.findViewById(R.id.item_album_play_img_iv3)
+ playButton3.setOnClickListener {
+ val woodzSong = Song("Drowning", "WOODZ", 0, 245, false, false, R.drawable.drowning)
+ songViewModel.currentSong.value = woodzSong
+ }
+
+ // drowning ImageView 클릭 시 "Drowning - WOODZ" 노래 설정
+ drowningIv = binding.drowningIv
+ drowningIv.setOnClickListener {
+ val woodzSong = Song("Drowning", "WOODZ", 0, 245, false, false, R.drawable.drowning)
+ songViewModel.currentSong.value = woodzSong
+ }
+
+ //val seekBar = binding.miniPlayerSeekBar
+ //seekBar.max = songDuration
+
+ // Play/Pause 버튼 클릭 시 재생/일시 정지 처리
+
+
+ // mainPlayerCl 클릭 시 SongActivity로 이동
+
+
+ // ViewPager2 초기화 및 어댑터 설정
+ homeBannerVp = binding.homeBannerVp
+ bannerAdapter = HomeBannerAdapter(bannerLayouts) { position -> }
+ homeBannerVp.adapter = bannerAdapter
+
+ // 배너 자동 슬라이드 구현
+ startBannerAutoSlide()
+
+ // day6 ImageView 클릭 시 AlbumFragment로 이동
+ day6Iv = binding.day6Iv
+ day6Iv.setOnClickListener {
+ val fragmentAlbum = AlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbum)
+ .addToBackStack(null)
+ .commit()
+ }
+
+ // idome ImageView 클릭 시 IdomeAlbumFragment로 이동
+ idomeIv = binding.idomeIv
+ idomeIv.setOnClickListener {
+ val fragmentAlbumIdome = IdomeAlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbumIdome)
+ .addToBackStack(null)
+ .commit()
+ }
+
+ // drowning ImageView 클릭 시 IdomeAlbumFragment로 이동
+ drowningIv = binding.drowningIv
+ drowningIv.setOnClickListener {
+ val fragmentAlbumDrowning = DrowningAlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbumDrowning)
+ .addToBackStack(null)
+ .commit()
+ }
+ }
+
+
+ // 배너 자동 슬라이드 시작
+ private fun startBannerAutoSlide() {
+ handler.postDelayed(object : Runnable {
+ override fun run() {
+ currentPage = (currentPage + 1) % 3 // 3개의 배너를 순환
+ homeBannerVp.setCurrentItem(currentPage, true)
+ handler.postDelayed(this, 3000) // 3초마다 슬라이드
+ }
+ }, 3000) // 3초 후 시작
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ if (::timer.isInitialized) timer.cancel()
+ }
+
+ // 음악 재생 시작
+ private fun startMusic() {
+ isPlaying = true
+ binding.itemAlbumPlayImgIv.setImageResource(R.drawable.baseline_pause_24) // Pause 아이콘으로 변경
+ //startSeekBar() // SeekBar 업데이트 시작
+ }
+
+
+ // 음악 일시 정지
+ private fun pauseMusic() {
+ isPlaying = false
+ binding.itemAlbumPlayImgIv.setImageResource(R.drawable.baseline_play_24) // Play 아이콘으로 변경
+ if (::timer.isInitialized) timer.cancel() // 타이머 정지
+ }
+
+ fun onItemClicked(song: Song) {
+ song.isPlaying = true
+ songViewModel.currentSong.value = song
+ }
+
+ // SeekBar 업데이트 시작
+// private fun startSeekBar() {
+// timer = Timer()
+// timer.scheduleAtFixedRate(object : TimerTask() {
+// override fun run() {
+// if (currentProcess < songDuration) {
+// currentProcess++
+// handler.post {
+// binding.miniPlayerSeekBar.progress = currentProcess
+// }
+// } else {
+// timer.cancel() // 끝나면 타이머 취소
+// }
+// }
+// }, 0, 1000) // 1초마다 진행
+// }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt
new file mode 100644
index 0000000..b516f6e
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt
@@ -0,0 +1,39 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.example.mission3.databinding.FragmentAlbumIdomeBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class IdomeAlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumIdomeBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumIdomeBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapterIdome(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt
new file mode 100644
index 0000000..cecdd3d
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt
@@ -0,0 +1,23 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+import com.example.mission3.databinding.FragmentSongIdomeBinding
+
+class IdomeSongFragment : Fragment() {
+ lateinit var binding: FragmentSongIdomeBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongIdomeBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt
new file mode 100644
index 0000000..21956a8
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt
@@ -0,0 +1,186 @@
+package com.example.mission3
+
+import android.content.Context.MODE_PRIVATE
+import android.content.Intent
+import android.content.SharedPreferences
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.example.mission3.databinding.ActivityMainBinding
+import com.google.android.material.bottomnavigation.BottomNavigationView
+import kotlinx.coroutines.launch
+import java.util.*
+
+class MainActivity : AppCompatActivity() {
+ private lateinit var binding: ActivityMainBinding
+ private lateinit var sharedPreferences: SharedPreferences
+ private lateinit var bottomNavi: BottomNavigationView
+ private lateinit var dbHelper: SongDatabaseHelper
+ private lateinit var songViewModel: SongViewModel
+
+ private val songList = listOf(
+ Song(id = 1, title = "HAPPY", singer = "DAY6(데이식스)", second = 0, playTime = 190, isPlaying = false, isLike = false, imageRes = R.drawable.happy),
+ Song(id = 2, title = "I DO ME", singer = "KiiiKiii (키키)", second = 0, playTime = 191, isPlaying = false, isLike = false, imageRes = R.drawable.idome),
+ Song(id = 3, title = "Drowning", singer = "WOODZ", second = 0, playTime = 245, isPlaying = false, isLike = false, imageRes = R.drawable.drowning)
+ )
+ private var currentSongIndex = 0
+ private var timer: Timer? = null
+ private var isPlaying = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ songViewModel = ViewModelProvider(this)[SongViewModel::class.java]
+
+ sharedPreferences = getSharedPreferences("MusicApp", MODE_PRIVATE)
+ dbHelper = SongDatabaseHelper(this)
+
+ lifecycleScope.launch {
+ insertDummySongs()
+ }
+
+ if (savedInstanceState == null) {
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commit()
+ }
+
+ window.statusBarColor = resources.getColor(android.R.color.white, theme)
+
+ bottomNavi = binding.bottomNavi
+ bottomNavi.setOnItemSelectedListener { item ->
+ when (item.itemId) {
+ R.id.action_home -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, HomeFragment()).commit()
+ true
+ }
+ R.id.action_audio -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, AudioFrag()).commit()
+ true
+ }
+ R.id.action_search -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, SearchFrag()).commit()
+ true
+ }
+ R.id.action_mymusic -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, MyMusicFragment()).commit()
+ true
+ }
+ R.id.action_menu -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, MenuFrag()).commit()
+ true
+ }
+ else -> false
+ }
+ }
+
+ binding.mainPlayerCl.setOnClickListener {
+ val song = songList[currentSongIndex]
+ val currentTime = binding.miniPlayerSeekbar.progress
+
+ val intent = Intent(this, SongActivity::class.java).apply {
+ putExtra("current_position", binding.miniPlayerSeekbar.progress)
+ putExtra("songTitle", song.title)
+ putExtra("songSinger", song.singer)
+ putExtra("songProgress", currentTime)
+ putExtra("songDuration", song.playTime)
+ putExtra("songImageRes", song.imageRes)
+ }
+ startActivity(intent)
+ }
+
+ binding.prevBtn.setOnClickListener {
+ currentSongIndex = if (currentSongIndex - 1 < 0) songList.size - 1 else currentSongIndex - 1
+ updateMiniPlayer(songList[currentSongIndex])
+ }
+
+ binding.nextBtn.setOnClickListener {
+ currentSongIndex = (currentSongIndex + 1) % songList.size
+ updateMiniPlayer(songList[currentSongIndex])
+ }
+
+ binding.playPauseBtn.setOnClickListener {
+ isPlaying = !isPlaying
+ if (isPlaying) {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_pause_24)
+ startSeekBar(songList[currentSongIndex])
+ } else {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ timer?.cancel()
+ }
+ }
+
+ songViewModel.currentSong.observe(this) { song ->
+ binding.miniPlayerSongTitleTv.text = song.title
+ binding.miniPlayerSingerTv.text = song.singer
+ if (song.isPlaying) {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_pause_24)
+ } else {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ }
+ }
+
+ updateMiniPlayer(songList[currentSongIndex])
+ }
+
+ private fun updateMiniPlayer(song: Song) {
+ binding.miniPlayerSongTitleTv.text = song.title
+ binding.miniPlayerSingerTv.text = song.singer
+ binding.miniPlayerSeekbar.max = song.playTime
+ binding.miniPlayerSeekbar.progress = song.second
+ saveSongId(song.id)
+
+ if (isPlaying) {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_pause_24)
+ startSeekBar(song)
+ } else {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ timer?.cancel()
+ }
+ }
+
+ private fun startSeekBar(song: Song) {
+ timer?.cancel()
+ var progress = binding.miniPlayerSeekbar.progress
+ timer = Timer()
+ timer?.scheduleAtFixedRate(object : TimerTask() {
+ override fun run() {
+ runOnUiThread {
+ if (progress < song.playTime) {
+ progress++
+ binding.miniPlayerSeekbar.progress = progress
+ } else {
+ timer?.cancel()
+ isPlaying = false
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ }
+ }
+ }
+ }, 1000, 1000)
+ }
+
+ private suspend fun insertDummySongs() {
+ for (song in songList) {
+ dbHelper.insertSong(song)
+ }
+ }
+
+ private fun saveSongId(songId: Int) {
+ val editor = sharedPreferences.edit()
+ editor.putInt("songId", songId)
+ editor.putInt("songTime", binding.miniPlayerSeekbar.progress)
+ editor.apply()
+ }
+
+ private fun getSongIdFromPreferences(): Int {
+ return sharedPreferences.getInt("songId", 0)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ timer?.cancel()
+ }
+}
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt
new file mode 100644
index 0000000..52d5fd8
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragMenuBinding
+import com.example.mission3.databinding.FragMymusicBinding
+
+class MenuFrag : Fragment() {
+ private var _binding: FragMenuBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragMenuBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt
new file mode 100644
index 0000000..dfcd9f4
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt
@@ -0,0 +1,19 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentMusicFileBinding
+
+class MusicFileFragment: Fragment() {
+
+ lateinit var binding: FragmentMusicFileBinding
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ binding = FragmentMusicFileBinding.inflate(inflater, container, false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt
new file mode 100644
index 0000000..a2e13b5
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt
@@ -0,0 +1,38 @@
+package com.example.mission3
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.mission3.databinding.ItemMymusicAlbumBinding
+
+class MyMusicAlbumRVAdapter(private val albumList: ArrayList) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = ItemMymusicAlbumBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bind(albumList[position])
+ holder.binding.itemMymusicAlbumMoreIv.setOnClickListener {
+ // 클릭 시 해당 아이템 삭제
+ removeItem(position)
+ }
+ }
+
+ override fun getItemCount(): Int = albumList.size
+
+ fun removeItem(position: Int) {
+ albumList.removeAt(position) // 해당 아이템 제거
+ notifyItemRemoved(position) // 아이템 제거 후 갱신
+ notifyItemRangeChanged(position, albumList.size) // 나머지 아이템 갱신
+ }
+
+ inner class ViewHolder(val binding: ItemMymusicAlbumBinding) : RecyclerView.ViewHolder(binding.root) {
+ fun bind(album: Album) {
+ binding.itemMymusicAlbumTitleTv.text = album.title
+ binding.itemMymusicAlbumSingerTv.text = album.singer
+ binding.itemMymusicAlbumCoverImgIv.setImageResource(album.coverImage)
+ }
+ }
+}
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt
new file mode 100644
index 0000000..5f61e75
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt
@@ -0,0 +1,30 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.google.android.material.tabs.TabLayoutMediator
+import com.example.mission3.databinding.FragMymusicBinding
+
+class MyMusicFragment : Fragment() {
+ private lateinit var binding: FragMymusicBinding
+ private val information = arrayListOf("저장한곡", "음악파일")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = FragMymusicBinding.inflate(inflater, container, false)
+
+ val lockerAdapter = MyMusicVPAdapter(this)
+ binding.mymusicContentVp.adapter = lockerAdapter
+ TabLayoutMediator(binding.mymusicContentTb, binding.mymusicContentVp) { tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt
new file mode 100644
index 0000000..b1771db
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt
@@ -0,0 +1,15 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class MyMusicVPAdapter (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount() : Int = 2
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> SavedSongFragment()
+ else -> MusicFileFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt
new file mode 100644
index 0000000..6222cb8
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt
@@ -0,0 +1,29 @@
+package com.example.mission3
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.mission3.databinding.RecyclerviewItemBinding
+
+class RVAdapter(private val items: MutableList) : RecyclerView.Adapter(){
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding: RecyclerviewItemBinding = RecyclerviewItemBinding
+ .inflate(LayoutInflater.from(parent.context), parent, false)
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bindItems(items[position])
+ }
+
+ override fun getItemCount(): Int = items.size
+
+ // ViewHolder 내부 클래스 정의
+ inner class ViewHolder(private val binding: RecyclerviewItemBinding) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bindItems(item: String) {
+ binding.itemAlbumTitleTv.text = item
+ }
+ }
+}
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt
new file mode 100644
index 0000000..cd95c84
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt
@@ -0,0 +1,53 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.example.mission3.databinding.FragmentSavedSongBinding
+
+class SavedSongFragment : Fragment() {
+
+ private var albumDatas = ArrayList()
+ lateinit var binding: FragmentSavedSongBinding
+ private lateinit var songViewModel: SongViewModel
+
+ private fun convertSongToAlbum(song: Song): Album {
+ return Album(
+ title = song.title,
+ singer = song.singer,
+ coverImage = song.imageRes
+ )
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSavedSongBinding.inflate(inflater, container, false)
+
+ // ViewModel 연결
+ songViewModel = ViewModelProvider(requireActivity())[SongViewModel::class.java]
+
+ val sharedPreferences = requireActivity().getSharedPreferences("song_prefs", android.content.Context.MODE_PRIVATE)
+
+ albumDatas.clear()
+ for (song in songViewModel.songList) {
+ val key = "${song.title}-${song.singer}"
+ val isLiked = sharedPreferences.getBoolean(key, false)
+ if (isLiked) {
+ albumDatas.add(convertSongToAlbum(song))
+ }
+ }
+
+ val adapter = MyMusicAlbumRVAdapter(albumDatas)
+ binding.mymusicMusicAlbumRv.adapter = adapter
+ binding.mymusicMusicAlbumRv.layoutManager = LinearLayoutManager(requireActivity())
+
+ return binding.root
+ }
+}
+
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/SavedSongsFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/SavedSongsFragment.kt
new file mode 100644
index 0000000..0fa2f67
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/SavedSongsFragment.kt
@@ -0,0 +1,4 @@
+package com.example.mission3
+
+class SavedSongsFragment {
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt
new file mode 100644
index 0000000..61c15ea
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragMymusicBinding
+import com.example.mission3.databinding.FragSearchBinding
+
+class SearchFrag : Fragment() {
+ private var _binding: FragSearchBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragSearchBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/Song.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/Song.kt
new file mode 100644
index 0000000..a6ec32e
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/Song.kt
@@ -0,0 +1,12 @@
+package com.example.mission3
+
+data class Song(
+ val title: String = "",
+ val singer: String = "",
+ var second: Int = 0,
+ var playTime: Int = 60,
+ var isPlaying: Boolean = false,
+ var isLike: Boolean = false, // 좋아요 상태 추가
+ val id: Int = 0, // Primary key를 수동으로 관리
+ val imageRes: Int = 0 // 이미지 리소스를 추가 (이미지 리소스 ID)
+)
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt
new file mode 100644
index 0000000..5ad6051
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt
@@ -0,0 +1,255 @@
+package com.example.mission3
+
+import android.content.Context.MODE_PRIVATE
+import android.content.SharedPreferences
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.os.Handler
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.edit
+import com.example.mission3.databinding.ActivitySongBinding
+
+class SongActivity : AppCompatActivity() {
+ private lateinit var binding: ActivitySongBinding
+ private lateinit var song: Song
+ private var isPlaying = false
+ private var currentTime = 0 // 현재 재생 시간 (초 단위)
+ private lateinit var sharedPreferences: SharedPreferences
+ private var isFavorite = false
+ private var songList: List = listOf() // 곡 리스트
+ private var currentSongIndex: Int = 0 // 현재 곡 인덱스
+
+
+ private val handler = Handler()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivitySongBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ sharedPreferences = getSharedPreferences("MyMusicApp", MODE_PRIVATE)
+
+ // Intent에서 받은 데이터를 기반으로 초기화
+ val songTitle = intent.getStringExtra("songTitle")
+ val songSinger = intent.getStringExtra("songSinger")
+ currentTime = intent.getIntExtra("songProgress", 0)
+ val songDuration = intent.getIntExtra("songDuration", 0)
+ val key = "$songTitle-$songSinger"
+ val imageResFromPrefs = sharedPreferences.getInt("${key}_imageRes", -1)
+ val imageRes = if (imageResFromPrefs != -1) imageResFromPrefs else {
+ intent.getIntExtra("songImageRes", R.drawable.happy)
+ }
+
+ // Song 객체 초기화
+ song = Song(
+ title = songTitle ?: "",
+ singer = songSinger ?: "",
+ second = currentTime,
+ playTime = songDuration,
+ isPlaying = false,
+ isLike = false,
+ id = 0,
+ imageRes = imageRes
+ )
+
+
+ songList = listOf(
+ Song("HAPPY", "DAY6(데이식스)", 0, 190, false, imageRes = R.drawable.happy),
+ Song("I DO ME", "KiiiKiii (키키)", 0, 191, false, imageRes = R.drawable.idome),
+ Song("Drowning", "WOODZ", 0, 245, false, imageRes = R.drawable.drowning)
+ )
+ currentSongIndex = songList.indexOf(song) // song에 맞는 인덱스를 찾습니다.
+
+ setPlayer(song) // 플레이어 설정
+
+ // 즐겨찾기 상태 로드
+ loadFavoriteStatus()
+ updateFavoriteButton()
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ window.statusBarColor = Color.parseColor("#FFFFFF")
+ }
+
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ binding.songSettingIb.setOnClickListener {
+ finish()
+ }
+
+ binding.playPauseButton.setOnClickListener {
+ if (isPlaying) {
+ pauseSong()
+ } else {
+ playSong()
+ }
+ }
+
+ // 즐겨찾기 버튼 클릭 리스너
+ binding.favoriteButton.setOnClickListener {
+ isFavorite = !isFavorite
+ updateFavoriteButton()
+ saveFavoriteStatus()
+ }
+
+ // 이전 곡 버튼 클릭 리스너
+ binding.skipPrevious.setOnClickListener {
+ goToPreviousSong()
+ }
+
+ // 다음 곡 버튼 클릭 리스너
+ binding.songNextIv.setOnClickListener {
+ goToNextSong()
+ }
+ }
+
+ private fun setPlayer(song: Song) {
+ binding.songTitleTv.text = song.title
+ binding.songSingerTv.text = song.singer
+ binding.songStartTimeTv.text = String.format("%02d:%02d", song.second / 60, song.second % 60)
+ binding.songEndTimeTv.text = String.format("%02d:%02d", song.playTime / 60, song.playTime % 60)
+
+ binding.songAlbumIv.setImageResource(song.imageRes)
+
+ binding.songProgressbarView.max = song.playTime * 1000
+ binding.songProgressbarView.progress = song.second * 1000
+
+ setPlayerStatus(song.isPlaying)
+ }
+
+ private fun setPlayerStatus(isPlaying: Boolean) {
+ if (isPlaying) {
+ binding.playPauseButton.setImageResource(R.drawable.baseline_pause_24)
+ binding.songProgressbarView.progressTintList = ColorStateList.valueOf(Color.parseColor("#81BEF7"))
+ startTimer() // 타이머 시작
+ } else {
+ binding.playPauseButton.setImageResource(R.drawable.baseline_play_24)
+ binding.songProgressbarView.progressTintList = ColorStateList.valueOf(Color.GRAY)
+ }
+ }
+
+ private fun startTimer() {
+ handler.postDelayed(object : Runnable {
+ override fun run() {
+ if (isPlaying) {
+ currentTime++
+ updateSeekBar() // SeekBar 업데이트
+ updateTimeDisplay() // 시간 텍스트 업데이트
+ if (currentTime < song.playTime) {
+ handler.postDelayed(this, 1000) // 1초 후에 다시 실행
+ }
+ }
+ }
+ }, 1000)
+ }
+
+ private fun updateSeekBar() {
+ binding.songProgressbarView.progress = currentTime * 1000
+ }
+
+ private fun updateTimeDisplay() {
+ val minutes = currentTime / 60
+ val seconds = currentTime % 60
+ binding.songStartTimeTv.text = String.format("%02d:%02d", minutes, seconds)
+
+ val remainingTime = song.playTime - currentTime
+ val endMinutes = remainingTime / 60
+ val endSeconds = remainingTime % 60
+ binding.songEndTimeTv.text = String.format("-%02d:%02d", endMinutes, endSeconds)
+ }
+
+ private fun playSong() {
+ isPlaying = true
+ setPlayerStatus(isPlaying)
+ }
+
+ private fun pauseSong() {
+ isPlaying = false
+ handler.removeCallbacksAndMessages(null) // 타이머 취소
+ setPlayerStatus(isPlaying)
+ }
+
+ private fun updateFavoriteButton() {
+ if (isFavorite) {
+ binding.favoriteButton.setImageResource(R.drawable.baseline_favorite_24)
+ } else {
+ binding.favoriteButton.setImageResource(R.drawable.baseline_favorite_border_24)
+ }
+ }
+
+ private fun saveFavoriteStatus() {
+ val key = "${song.title}-${song.singer}"
+ sharedPreferences.edit {
+ putBoolean(key, isFavorite)
+ putInt("${key}_imageRes", song.imageRes) // 이미지 리소스 ID 저장
+ }
+ }
+
+ private fun loadFavoriteStatus() {
+ val key = "${song.title}-${song.singer}"
+ isFavorite = sharedPreferences.getBoolean(key, false)
+ }
+
+ private fun goToPreviousSong() {
+ if (currentSongIndex > 0) {
+ currentSongIndex--
+ song = songList[currentSongIndex]
+ setPlayer(song)
+ stopSong()
+ playSong()
+
+ sharedPreferences.edit {
+ putInt("current_song_index", currentSongIndex)
+ }
+ }
+ }
+
+ private fun goToNextSong() {
+ if (currentSongIndex < songList.size - 1) {
+ currentSongIndex++
+ song = songList[currentSongIndex]
+ currentTime = 0 // 시간 초기화
+ setPlayer(song)
+ stopSong()
+ playSong()
+
+ sharedPreferences.edit {
+ putInt("current_song_index", currentSongIndex)
+ }
+ }
+ }
+
+ private fun stopSong() {
+ // 곡 멈추기
+ isPlaying = false
+ handler.removeCallbacksAndMessages(null)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ // 타이머는 멈추지 않고 상태 유지
+ }
+
+ override fun onResume() {
+ super.onResume()
+ // 화면이 다시 보여질 때 타이머가 계속 진행되도록 설정
+ if (isPlaying) {
+ startTimer() // 타이머 다시 시작
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ handler.removeCallbacksAndMessages(null) // 화면 종료 시 타이머 정지
+ }
+
+ override fun onSupportNavigateUp(): Boolean {
+ onBackPressed()
+ return true
+ }
+}
+
+
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt
new file mode 100644
index 0000000..56317b3
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt
@@ -0,0 +1,146 @@
+package com.example.mission3
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import android.database.Cursor
+import android.content.ContentValues
+import android.database.SQLException
+import android.database.sqlite.SQLiteOpenHelper
+
+
+class SongDatabaseHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
+
+ companion object {
+ private const val DATABASE_NAME = "songs.db"
+ private const val DATABASE_VERSION = 1
+
+ // 테이블 및 컬럼 이름
+ const val TABLE_SONGS = "songs"
+ const val COLUMN_ID = "id"
+ const val COLUMN_TITLE = "title"
+ const val COLUMN_SINGER = "singer"
+ const val COLUMN_SECOND = "second"
+ const val COLUMN_PLAYTIME = "playTime"
+ const val COLUMN_ISPLAYING = "isPlaying"
+ const val COLUMN_ISLIKE = "isLike"
+ }
+
+ override fun onCreate(db: SQLiteDatabase?) {
+ val createTableQuery = """
+ CREATE TABLE $TABLE_SONGS (
+ $COLUMN_ID INTEGER PRIMARY KEY AUTOINCREMENT,
+ $COLUMN_TITLE TEXT,
+ $COLUMN_SINGER TEXT,
+ $COLUMN_SECOND INTEGER,
+ $COLUMN_PLAYTIME INTEGER,
+ $COLUMN_ISPLAYING INTEGER,
+ $COLUMN_ISLIKE INTEGER
+ )
+ """
+ db?.execSQL(createTableQuery)
+ }
+
+ override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
+ db?.execSQL("DROP TABLE IF EXISTS $TABLE_SONGS")
+ onCreate(db)
+ }
+
+ // Song 삽입 메서드
+ fun insertSong(song: Song): Long {
+ val db = writableDatabase
+ val values = ContentValues().apply {
+ put(COLUMN_TITLE, song.title)
+ put(COLUMN_SINGER, song.singer)
+ put(COLUMN_SECOND, song.second)
+ put(COLUMN_PLAYTIME, song.playTime)
+ put(COLUMN_ISPLAYING, if (song.isPlaying) 1 else 0)
+ put(COLUMN_ISLIKE, if (song.isLike) 1 else 0)
+ }
+
+ return db.insert(TABLE_SONGS, null, values)
+ }
+
+ // Song 업데이트 메서드
+ fun updateSong(song: Song) {
+ val db = writableDatabase
+ val values = ContentValues().apply {
+ put(COLUMN_TITLE, song.title)
+ put(COLUMN_SINGER, song.singer)
+ put(COLUMN_SECOND, song.second)
+ put(COLUMN_PLAYTIME, song.playTime)
+ put(COLUMN_ISPLAYING, if (song.isPlaying) 1 else 0)
+ put(COLUMN_ISLIKE, if (song.isLike) 1 else 0)
+ }
+
+ db.update(TABLE_SONGS, values, "$COLUMN_ID = ?", arrayOf(song.id.toString()))
+ }
+
+ // ID로 Song 조회 메서드
+ @SuppressLint("Range")
+ fun getSongById(id: Int): Song? {
+ val db = readableDatabase
+ val cursor: Cursor = db.query(
+ TABLE_SONGS,
+ null,
+ "$COLUMN_ID = ?",
+ arrayOf(id.toString()),
+ null,
+ null,
+ null
+ )
+
+ return if (cursor.moveToFirst()) {
+ val title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE))
+ val singer = cursor.getString(cursor.getColumnIndex(COLUMN_SINGER))
+ val second = cursor.getInt(cursor.getColumnIndex(COLUMN_SECOND))
+ val playTime = cursor.getInt(cursor.getColumnIndex(COLUMN_PLAYTIME))
+ val isPlaying = cursor.getInt(cursor.getColumnIndex(COLUMN_ISPLAYING)) == 1
+ val isLike = cursor.getInt(cursor.getColumnIndex(COLUMN_ISLIKE)) == 1
+ val songId = cursor.getInt(cursor.getColumnIndex(COLUMN_ID))
+
+ Song(title, singer, second, playTime, isPlaying, isLike, songId)
+ } else {
+ null
+ }
+ }
+
+ // 모든 Song 조회 메서드
+ @SuppressLint("Range")
+ fun getAllSongs(): List {
+ val songList = mutableListOf()
+ val db = readableDatabase
+ val cursor: Cursor = db.query(
+ TABLE_SONGS,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+
+ if (cursor.moveToFirst()) {
+ do {
+ val title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE))
+ val singer = cursor.getString(cursor.getColumnIndex(COLUMN_SINGER))
+ val second = cursor.getInt(cursor.getColumnIndex(COLUMN_SECOND))
+ val playTime = cursor.getInt(cursor.getColumnIndex(COLUMN_PLAYTIME))
+ val isPlaying = cursor.getInt(cursor.getColumnIndex(COLUMN_ISPLAYING)) == 1
+ val isLike = cursor.getInt(cursor.getColumnIndex(COLUMN_ISLIKE)) == 1
+ val songId = cursor.getInt(cursor.getColumnIndex(COLUMN_ID))
+
+ songList.add(Song(title, singer, second, playTime, isPlaying, isLike, songId))
+ } while (cursor.moveToNext())
+ }
+
+ cursor.close()
+ return songList
+ }
+
+ // Song 삭제 메서드
+ fun deleteSong(id: Int) {
+ val db = writableDatabase
+ db.delete(TABLE_SONGS, "$COLUMN_ID = ?", arrayOf(id.toString()))
+ }
+}
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt
new file mode 100644
index 0000000..56f6e2a
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+
+class SongFragment : Fragment() {
+ lateinit var binding: FragmentSongBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/SongViewModel.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/SongViewModel.kt
new file mode 100644
index 0000000..6bd5fad
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/SongViewModel.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+
+class SongViewModel : ViewModel() {
+ val currentSong = MutableLiveData()
+
+ // 노래 목록 관리용 (필요 시)
+ val songList = listOf(
+ Song("Happy", "DAY6(데이식스)", 0, 190, false, false, R.drawable.happy),
+ Song("I DO ME", "KiiiKiii (키키)", 0, 191, false, false, R.drawable.idome),
+ Song("Drowning", "WOODZ", 0, 245, false, false, R.drawable.drowning)
+ )
+}
+
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt
new file mode 100644
index 0000000..9314d0f
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner3Binding
+
+class ThreeBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner3Binding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner3Binding.inflate(inflater,container,false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt
new file mode 100644
index 0000000..879e2d7
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner2Binding
+
+class TwoBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner2Binding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner2Binding.inflate(inflater,container,false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt b/Work6/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt
new file mode 100644
index 0000000..cb0b9b0
--- /dev/null
+++ b/Work6/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+
+import com.example.mission3.databinding.FragmentVideoBinding
+
+class ViedoFragment : Fragment() {
+ lateinit var binding: FragmentVideoBinding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentVideoBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/drawable/banner1.jpg b/Work6/Mission3/app/src/main/res/drawable/banner1.jpg
new file mode 100644
index 0000000..81524e1
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/drawable/banner1.jpg differ
diff --git a/Work6/Mission3/app/src/main/res/drawable/banner2.jpg b/Work6/Mission3/app/src/main/res/drawable/banner2.jpg
new file mode 100644
index 0000000..bc20bf4
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/drawable/banner2.jpg differ
diff --git a/Work6/Mission3/app/src/main/res/drawable/banner3.jpg b/Work6/Mission3/app/src/main/res/drawable/banner3.jpg
new file mode 100644
index 0000000..8b55d5f
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/drawable/banner3.jpg differ
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml
new file mode 100644
index 0000000..99f85de
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml
new file mode 100644
index 0000000..1a69b23
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml
new file mode 100644
index 0000000..6e3d747
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_audio_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_audio_24.xml
new file mode 100644
index 0000000..82ea4d3
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_audio_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_check_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_check_24.xml
new file mode 100644
index 0000000..356e998
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_check_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml
new file mode 100644
index 0000000..badf5ea
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml
new file mode 100644
index 0000000..2acceab
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_home_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_home_24.xml
new file mode 100644
index 0000000..20cb4d6
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_home_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml
new file mode 100644
index 0000000..0e5587b
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml
new file mode 100644
index 0000000..1146d4c
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml
new file mode 100644
index 0000000..a7912d8
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_menu_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_menu_24.xml
new file mode 100644
index 0000000..75c361f
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_menu_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml
new file mode 100644
index 0000000..52ede6a
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml
new file mode 100644
index 0000000..c9c2ad9
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_next_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_next_24.xml
new file mode 100644
index 0000000..4904368
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_next_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_pause_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_pause_24.xml
new file mode 100644
index 0000000..ae853f2
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_pause_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml
new file mode 100644
index 0000000..1e24cf3
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_play_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_play_24.xml
new file mode 100644
index 0000000..b176182
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_play_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_play_more24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_play_more24.xml
new file mode 100644
index 0000000..5ffb98a
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_play_more24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml
new file mode 100644
index 0000000..c7d89f1
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml
new file mode 100644
index 0000000..151a3e1
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_search_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_search_24.xml
new file mode 100644
index 0000000..d29c6ea
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_search_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml
new file mode 100644
index 0000000..5a79f5e
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml
new file mode 100644
index 0000000..7951d71
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_star_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_star_24.xml
new file mode 100644
index 0000000..925b973
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_star_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml
new file mode 100644
index 0000000..f775f11
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/baseline_volume_24.xml b/Work6/Mission3/app/src/main/res/drawable/baseline_volume_24.xml
new file mode 100644
index 0000000..a53186e
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/baseline_volume_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/drowning.jpg b/Work6/Mission3/app/src/main/res/drawable/drowning.jpg
new file mode 100644
index 0000000..97fa652
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/drawable/drowning.jpg differ
diff --git a/Work6/Mission3/app/src/main/res/drawable/happy.jpg b/Work6/Mission3/app/src/main/res/drawable/happy.jpg
new file mode 100644
index 0000000..6b24b63
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/drawable/happy.jpg differ
diff --git a/Work6/Mission3/app/src/main/res/drawable/ic_launcher_background.xml b/Work6/Mission3/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml b/Work6/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/drawable/idome.jpg b/Work6/Mission3/app/src/main/res/drawable/idome.jpg
new file mode 100644
index 0000000..b40b38f
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/drawable/idome.jpg differ
diff --git a/Work6/Mission3/app/src/main/res/layout/activity_main.xml b/Work6/Mission3/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..dded351
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/layout/activity_song.xml b/Work6/Mission3/app/src/main/res/layout/activity_song.xml
new file mode 100644
index 0000000..6be6395
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/activity_song.xml
@@ -0,0 +1,283 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/frag_audio.xml b/Work6/Mission3/app/src/main/res/layout/frag_audio.xml
new file mode 100644
index 0000000..ae66603
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/frag_audio.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/frag_menu.xml b/Work6/Mission3/app/src/main/res/layout/frag_menu.xml
new file mode 100644
index 0000000..d6811d0
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/frag_menu.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/frag_mymusic.xml b/Work6/Mission3/app/src/main/res/layout/frag_mymusic.xml
new file mode 100644
index 0000000..7f4cef8
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/frag_mymusic.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/frag_search.xml b/Work6/Mission3/app/src/main/res/layout/frag_search.xml
new file mode 100644
index 0000000..d523e6e
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/frag_search.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_album.xml b/Work6/Mission3/app/src/main/res/layout/fragment_album.xml
new file mode 100644
index 0000000..825ab0d
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_album.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_album_drowning.xml b/Work6/Mission3/app/src/main/res/layout/fragment_album_drowning.xml
new file mode 100644
index 0000000..e341853
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_album_drowning.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_album_idome.xml b/Work6/Mission3/app/src/main/res/layout/fragment_album_idome.xml
new file mode 100644
index 0000000..6792827
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_album_idome.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_banner_1.xml b/Work6/Mission3/app/src/main/res/layout/fragment_banner_1.xml
new file mode 100644
index 0000000..142a6b8
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_banner_1.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_banner_2.xml b/Work6/Mission3/app/src/main/res/layout/fragment_banner_2.xml
new file mode 100644
index 0000000..f194ac2
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_banner_2.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_banner_3.xml b/Work6/Mission3/app/src/main/res/layout/fragment_banner_3.xml
new file mode 100644
index 0000000..5923f27
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_banner_3.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_detail.xml b/Work6/Mission3/app/src/main/res/layout/fragment_detail.xml
new file mode 100644
index 0000000..413125c
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_detail.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_home.xml b/Work6/Mission3/app/src/main/res/layout/fragment_home.xml
new file mode 100644
index 0000000..859952e
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_home.xml
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_music_file.xml b/Work6/Mission3/app/src/main/res/layout/fragment_music_file.xml
new file mode 100644
index 0000000..77d9ef6
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_music_file.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_saved_song.xml b/Work6/Mission3/app/src/main/res/layout/fragment_saved_song.xml
new file mode 100644
index 0000000..6130fb1
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_saved_song.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_saved_songs.xml b/Work6/Mission3/app/src/main/res/layout/fragment_saved_songs.xml
new file mode 100644
index 0000000..8fb800d
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_saved_songs.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_song.xml b/Work6/Mission3/app/src/main/res/layout/fragment_song.xml
new file mode 100644
index 0000000..7da782e
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_song.xml
@@ -0,0 +1,422 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_song_drowning.xml b/Work6/Mission3/app/src/main/res/layout/fragment_song_drowning.xml
new file mode 100644
index 0000000..6566743
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_song_drowning.xml
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_song_idome.xml b/Work6/Mission3/app/src/main/res/layout/fragment_song_idome.xml
new file mode 100644
index 0000000..e92ec6f
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_song_idome.xml
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/fragment_video.xml b/Work6/Mission3/app/src/main/res/layout/fragment_video.xml
new file mode 100644
index 0000000..e86dad1
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/fragment_video.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/item_mymusic_album.xml b/Work6/Mission3/app/src/main/res/layout/item_mymusic_album.xml
new file mode 100644
index 0000000..b515f94
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/item_mymusic_album.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/layout/recyclerview_item.xml b/Work6/Mission3/app/src/main/res/layout/recyclerview_item.xml
new file mode 100644
index 0000000..30c304a
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/layout/recyclerview_item.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/menu/menu.xml b/Work6/Mission3/app/src/main/res/menu/menu.xml
new file mode 100644
index 0000000..4472d4b
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/menu/menu.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Work6/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Work6/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Work6/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Work6/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Work6/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Work6/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Work6/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Work6/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Work6/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Work6/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Work6/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Work6/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Work6/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Work6/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Work6/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Work6/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Work6/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Work6/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Work6/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Work6/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Work6/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/Work6/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Work6/Mission3/app/src/main/res/values-night/themes.xml b/Work6/Mission3/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..ebeb9cd
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/values/colors.xml b/Work6/Mission3/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..aacedae
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/values/strings.xml b/Work6/Mission3/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..90c25e1
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/values/strings.xml
@@ -0,0 +1,12 @@
+
+ Mission3
+ NewJeans 이미지
+ 배너 이미지
+ Home
+ Album
+ Audio
+ Search
+ My Music
+ Menu
+ Play/Pause
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/values/themes.xml b/Work6/Mission3/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..66e5370
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/values/themes.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/xml/backup_rules.xml b/Work6/Mission3/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/main/res/xml/data_extraction_rules.xml b/Work6/Mission3/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/Work6/Mission3/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt b/Work6/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt
new file mode 100644
index 0000000..6c8895e
--- /dev/null
+++ b/Work6/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.mission3
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt b/Work6/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt
new file mode 100644
index 0000000..49f80b4
--- /dev/null
+++ b/Work6/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.missionn3
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt b/Work6/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt
new file mode 100644
index 0000000..e500fb8
--- /dev/null
+++ b/Work6/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.myapplication
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work6/Mission3/build.gradle.kts b/Work6/Mission3/build.gradle.kts
new file mode 100644
index 0000000..922f551
--- /dev/null
+++ b/Work6/Mission3/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+}
\ No newline at end of file
diff --git a/Work6/Mission3/gradle.properties b/Work6/Mission3/gradle.properties
new file mode 100644
index 0000000..20e2a01
--- /dev/null
+++ b/Work6/Mission3/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Work6/Mission3/gradle/libs.versions.toml b/Work6/Mission3/gradle/libs.versions.toml
new file mode 100644
index 0000000..0b1b772
--- /dev/null
+++ b/Work6/Mission3/gradle/libs.versions.toml
@@ -0,0 +1,32 @@
+[versions]
+agp = "8.6.0"
+kotlin = "1.9.0"
+coreKtx = "1.13.1"
+junit = "4.13.2"
+junitVersion = "1.2.1"
+espressoCore = "3.6.1"
+appcompat = "1.7.0"
+material = "1.12.0"
+activity = "1.9.2"
+constraintlayout = "2.1.4"
+roomCommon = "2.6.1"
+roomKtx = "2.6.1"
+supportAnnotations = "28.0.0"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+androidx-room-common = { group = "androidx.room", name = "room-common", version.ref = "roomCommon" }
+androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "roomKtx" }
+support-annotations = { group = "com.android.support", name = "support-annotations", version.ref = "supportAnnotations" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+
diff --git a/Work6/Mission3/gradle/wrapper/gradle-wrapper.jar b/Work6/Mission3/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/Work6/Mission3/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Work6/Mission3/gradle/wrapper/gradle-wrapper.properties b/Work6/Mission3/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..e9384f5
--- /dev/null
+++ b/Work6/Mission3/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Oct 11 15:46:02 KST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Work6/Mission3/gradlew b/Work6/Mission3/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/Work6/Mission3/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Work6/Mission3/gradlew.bat b/Work6/Mission3/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/Work6/Mission3/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Work6/Mission3/settings.gradle.kts b/Work6/Mission3/settings.gradle.kts
new file mode 100644
index 0000000..f1d91db
--- /dev/null
+++ b/Work6/Mission3/settings.gradle.kts
@@ -0,0 +1,26 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "Mission3"
+include(":app")
+include(":app")
+include(":app")
+
\ No newline at end of file
diff --git a/Work7/Mission3/.gitignore b/Work7/Mission3/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/Work7/Mission3/.gitignore
@@ -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
diff --git a/Work7/Mission3/.idea/.gitignore b/Work7/Mission3/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Work7/Mission3/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Work7/Mission3/.idea/compiler.xml b/Work7/Mission3/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/Work7/Mission3/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/.idea/deploymentTargetSelector.xml b/Work7/Mission3/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/Work7/Mission3/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/.idea/gradle.xml b/Work7/Mission3/.idea/gradle.xml
new file mode 100644
index 0000000..7b3006b
--- /dev/null
+++ b/Work7/Mission3/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/.idea/kotlinc.xml b/Work7/Mission3/.idea/kotlinc.xml
new file mode 100644
index 0000000..fdf8d99
--- /dev/null
+++ b/Work7/Mission3/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/.idea/migrations.xml b/Work7/Mission3/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/Work7/Mission3/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/.idea/misc.xml b/Work7/Mission3/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/Work7/Mission3/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/.idea/runConfigurations.xml b/Work7/Mission3/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/Work7/Mission3/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/.gitignore b/Work7/Mission3/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Work7/Mission3/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Work7/Mission3/app/build.gradle.kts b/Work7/Mission3/app/build.gradle.kts
new file mode 100644
index 0000000..5826818
--- /dev/null
+++ b/Work7/Mission3/app/build.gradle.kts
@@ -0,0 +1,56 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.mission3"
+ compileSdk = 34
+
+ viewBinding {
+ enable=true
+ }
+
+ defaultConfig {
+ applicationId = "com.example.mission3"
+ minSdk = 24
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+
+dependencies {
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.activity)
+ implementation(libs.androidx.constraintlayout)
+ implementation(libs.androidx.room.common)
+ implementation(libs.androidx.room.ktx) // Room의 공통 라이브러리
+
+
+
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/proguard-rules.pro b/Work7/Mission3/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Work7/Mission3/app/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/AndroidManifest.xml b/Work7/Mission3/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9624502
--- /dev/null
+++ b/Work7/Mission3/app/src/main/AndroidManifest.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/Album.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/Album.kt
new file mode 100644
index 0000000..aa1736b
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/Album.kt
@@ -0,0 +1,8 @@
+package com.example.mission3
+
+data class Album(
+ val title: String,
+ val singer: String,
+ val imageRes: Int
+
+)
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt
new file mode 100644
index 0000000..98a2f11
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumFragment.kt
@@ -0,0 +1,38 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class AlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapter(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt
new file mode 100644
index 0000000..e6ccd88
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapter.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapter (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> SongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt
new file mode 100644
index 0000000..6d4ba64
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterDrowning.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapterDrowning (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> DrowningSongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt
new file mode 100644
index 0000000..e2b4f78
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/AlbumVPAdapterIdome.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class AlbumVPAdapterIdome (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> IdomeSongFragment()
+ 1 -> DetailFragment()
+ else -> ViedoFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt
new file mode 100644
index 0000000..16d14b0
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/AllBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner1Binding
+
+class AllBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner1Binding // 이름 변경
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner1Binding.inflate(inflater, container, false) // 이름 변경
+ return binding.root
+ }
+}
+
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/AppDatabase.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/AppDatabase.kt
new file mode 100644
index 0000000..53e6e32
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/AppDatabase.kt
@@ -0,0 +1,26 @@
+package com.example.mission3
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+
+@Database(entities = [LikedSong::class], version = 1)
+abstract class AppDatabase : RoomDatabase() {
+ abstract fun likedSongDao(): LikedSongDao
+
+ companion object {
+ @Volatile private var INSTANCE: AppDatabase? = null
+
+ fun getDatabase(context: Context): AppDatabase {
+ return INSTANCE ?: synchronized(this) {
+ Room.databaseBuilder(
+ context.applicationContext,
+ AppDatabase::class.java,
+ "liked_song_database"
+ ).build().also { INSTANCE = it }
+ }
+ }
+ }
+}
+
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt
new file mode 100644
index 0000000..ec7814b
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/AudioFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragAudioBinding
+import com.example.mission3.databinding.FragMymusicBinding
+
+class AudioFrag : Fragment() {
+ private var _binding: FragAudioBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragAudioBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt
new file mode 100644
index 0000000..a1141c2
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/BannerViewPagerAdapter.kt
@@ -0,0 +1,18 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class BannerViewPagerAdapter(fragment : Fragment) : FragmentStateAdapter(fragment) {
+
+ override fun getItemCount(): Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position){
+ 0 -> AllBannerFragment()
+ 1 -> TwoBannerFragment()
+ else -> ThreeBannerFragment()
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt
new file mode 100644
index 0000000..49ef847
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/DetailFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentDetailBinding
+
+class DetailFragment : Fragment() {
+ lateinit var binding: FragmentDetailBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentDetailBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt
new file mode 100644
index 0000000..aa24713
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/DrowningAlbumFragment.kt
@@ -0,0 +1,40 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.example.mission3.databinding.FragmentAlbumDrowningBinding
+import com.example.mission3.databinding.FragmentAlbumIdomeBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class DrowningAlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumDrowningBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumDrowningBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapterDrowning(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt
new file mode 100644
index 0000000..45e7322
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/DrowningSongFragment.kt
@@ -0,0 +1,24 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+import com.example.mission3.databinding.FragmentSongDrowningBinding
+import com.example.mission3.databinding.FragmentSongIdomeBinding
+
+class DrowningSongFragment : Fragment() {
+ lateinit var binding: FragmentSongDrowningBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongDrowningBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/FavoriteSongsAdapter.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/FavoriteSongsAdapter.kt
new file mode 100644
index 0000000..381fe7c
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/FavoriteSongsAdapter.kt
@@ -0,0 +1,4 @@
+package com.example.mission3
+
+class FavoriteSongsAdapter {
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt
new file mode 100644
index 0000000..47d711d
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/HomeAdapter.kt
@@ -0,0 +1,4 @@
+package com.example.mission3
+
+class HomeAdapter {
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt
new file mode 100644
index 0000000..e0ff126
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/HomeBannerAdapter.kt
@@ -0,0 +1,45 @@
+package com.example.mission3
+
+// HomeBannerAdapter.kt
+
+
+import android.media.Image
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.recyclerview.widget.RecyclerView
+
+class HomeBannerAdapter(
+ private val bannerLayouts: List,
+ private val onItemClick: (Int) -> Unit
+) : RecyclerView.Adapter() {
+
+ inner class BannerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ init {
+ itemView.setOnClickListener {
+ val position = adapterPosition
+ if (position != RecyclerView.NO_POSITION) {
+ onItemClick(position)
+ }
+ }
+ }
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return bannerLayouts[position]
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(viewType, parent, false)
+ return BannerViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: BannerViewHolder, position: Int) {
+ // 이미지가 레이아웃 파일에 이미 설정되어 있으므로 별도의 바인딩이 필요하지 않을 수 있습니다.
+ // 그러나 필요하다면 여기에 추가적인 바인딩 로직을 구현할 수 있습니다.
+ }
+
+ override fun getItemCount(): Int = bannerLayouts.size
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt
new file mode 100644
index 0000000..fff9aa8
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/HomeFragment.kt
@@ -0,0 +1,201 @@
+package com.example.mission3
+
+
+import android.content.Intent
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import androidx.viewpager2.widget.ViewPager2
+import com.example.mission3.databinding.FragmentHomeBinding
+import java.util.Timer
+import java.util.TimerTask
+
+class HomeFragment : Fragment() {
+
+ private lateinit var homeBannerVp: ViewPager2
+ private lateinit var day6Iv: ImageView
+ private lateinit var idomeIv: ImageView
+ private lateinit var drowningIv: ImageView
+ private lateinit var bannerAdapter: HomeBannerAdapter
+ private lateinit var binding: FragmentHomeBinding
+
+ private lateinit var songViewModel: SongViewModel
+
+
+ private val bannerLayouts = listOf(
+ R.layout.fragment_banner_1,
+ R.layout.fragment_banner_2,
+ R.layout.fragment_banner_3
+ )
+
+ private val songDuration = 191
+ private var currentProcess = 0
+ private var isPlaying = false // 플레이 상태 확인 변수
+ private lateinit var timer: Timer
+ private val handler = Handler(Looper.getMainLooper())
+ private var currentPage = 0
+
+ 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)
+
+ songViewModel = ViewModelProvider(requireActivity())[SongViewModel::class.java]
+
+
+ // Play 버튼 클릭 시 "HAPPY" 노래 설정
+ val playButton1 = view.findViewById(R.id.item_album_play_img_iv)
+ playButton1.setOnClickListener {
+ val day6Song = Song("HAPPY", "DAY6(데이식스)", 0, 190, false, false, R.drawable.happy)
+ songViewModel.currentSong.value = day6Song
+ }
+
+ // day6 ImageView 클릭 시 "DAY6 - Happy" 노래 설정
+ day6Iv = binding.day6Iv
+ day6Iv.setOnClickListener {
+ val day6Song = Song("HAPPY", "DAY6(데이식스)", 0, 190, false, false, R.drawable.happy)
+ songViewModel.currentSong.value = day6Song
+ }
+
+ // Play 버튼 클릭 시 "I DO ME" 노래 설정
+ val playButton2 = view.findViewById(R.id.item_album_play_img_iv2)
+ playButton2.setOnClickListener {
+ val kiiikiiiSong = Song("I DO ME", "KiiiKiii (키키)", 0, 191, false, false, R.drawable.idome)
+ songViewModel.currentSong.value = kiiikiiiSong
+ }
+
+ // idome ImageView 클릭 시 "I DO ME - KiiiKiii" 노래 설정
+ idomeIv = binding.idomeIv
+ idomeIv.setOnClickListener {
+ val kiiikiiiSong = Song("I DO ME", "KiiiKiii (키키)", 0, 191, false, false, R.drawable.idome)
+ songViewModel.currentSong.value = kiiikiiiSong
+ }
+
+ // Play 버튼 클릭 시 "Drowning" 노래 설정
+ val playButton3 = view.findViewById(R.id.item_album_play_img_iv3)
+ playButton3.setOnClickListener {
+ val woodzSong = Song("Drowning", "WOODZ", 0, 245, false, false, R.drawable.drowning)
+ songViewModel.currentSong.value = woodzSong
+ }
+
+ // drowning ImageView 클릭 시 "Drowning - WOODZ" 노래 설정
+ drowningIv = binding.drowningIv
+ drowningIv.setOnClickListener {
+ val woodzSong = Song("Drowning", "WOODZ", 0, 245, false, false, R.drawable.drowning)
+ songViewModel.currentSong.value = woodzSong
+ }
+
+ //val seekBar = binding.miniPlayerSeekBar
+ //seekBar.max = songDuration
+
+ // Play/Pause 버튼 클릭 시 재생/일시 정지 처리
+
+
+ // mainPlayerCl 클릭 시 SongActivity로 이동
+
+
+ // ViewPager2 초기화 및 어댑터 설정
+ homeBannerVp = binding.homeBannerVp
+ bannerAdapter = HomeBannerAdapter(bannerLayouts) { position -> }
+ homeBannerVp.adapter = bannerAdapter
+
+ // 배너 자동 슬라이드 구현
+ startBannerAutoSlide()
+
+ // day6 ImageView 클릭 시 AlbumFragment로 이동
+ day6Iv = binding.day6Iv
+ day6Iv.setOnClickListener {
+ val fragmentAlbum = AlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbum)
+ .addToBackStack(null)
+ .commit()
+ }
+
+ // idome ImageView 클릭 시 IdomeAlbumFragment로 이동
+ idomeIv = binding.idomeIv
+ idomeIv.setOnClickListener {
+ val fragmentAlbumIdome = IdomeAlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbumIdome)
+ .addToBackStack(null)
+ .commit()
+ }
+
+ // drowning ImageView 클릭 시 IdomeAlbumFragment로 이동
+ drowningIv = binding.drowningIv
+ drowningIv.setOnClickListener {
+ val fragmentAlbumDrowning = DrowningAlbumFragment()
+ parentFragmentManager.beginTransaction()
+ .replace(R.id.main, fragmentAlbumDrowning)
+ .addToBackStack(null)
+ .commit()
+ }
+ }
+
+
+ // 배너 자동 슬라이드 시작
+ private fun startBannerAutoSlide() {
+ handler.postDelayed(object : Runnable {
+ override fun run() {
+ currentPage = (currentPage + 1) % 3 // 3개의 배너를 순환
+ homeBannerVp.setCurrentItem(currentPage, true)
+ handler.postDelayed(this, 3000) // 3초마다 슬라이드
+ }
+ }, 3000) // 3초 후 시작
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ if (::timer.isInitialized) timer.cancel()
+ }
+
+ // 음악 재생 시작
+ private fun startMusic() {
+ isPlaying = true
+ binding.itemAlbumPlayImgIv.setImageResource(R.drawable.baseline_pause_24) // Pause 아이콘으로 변경
+ //startSeekBar() // SeekBar 업데이트 시작
+ }
+
+
+ // 음악 일시 정지
+ private fun pauseMusic() {
+ isPlaying = false
+ binding.itemAlbumPlayImgIv.setImageResource(R.drawable.baseline_play_24) // Play 아이콘으로 변경
+ if (::timer.isInitialized) timer.cancel() // 타이머 정지
+ }
+
+ fun onItemClicked(song: Song) {
+ song.isPlaying = true
+ songViewModel.currentSong.value = song
+ }
+
+ // SeekBar 업데이트 시작
+// private fun startSeekBar() {
+// timer = Timer()
+// timer.scheduleAtFixedRate(object : TimerTask() {
+// override fun run() {
+// if (currentProcess < songDuration) {
+// currentProcess++
+// handler.post {
+// binding.miniPlayerSeekBar.progress = currentProcess
+// }
+// } else {
+// timer.cancel() // 끝나면 타이머 취소
+// }
+// }
+// }, 0, 1000) // 1초마다 진행
+// }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt
new file mode 100644
index 0000000..b516f6e
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/IdomeAlbumFragment.kt
@@ -0,0 +1,39 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentAlbumBinding
+import com.example.mission3.databinding.FragmentAlbumIdomeBinding
+import com.google.android.material.tabs.TabLayoutMediator
+
+class IdomeAlbumFragment : Fragment() {
+
+ lateinit var binding: FragmentAlbumIdomeBinding
+
+ private val information = arrayListOf("수록곡", "상세정보", "영상")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentAlbumIdomeBinding.inflate(inflater, container, false)
+
+ binding.albumBackIv.setOnClickListener {
+ (context as MainActivity).supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commitAllowingStateLoss()
+ }
+ val albumAdapter = AlbumVPAdapterIdome(this)
+ binding.albumContentVp.adapter=albumAdapter
+ TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) {
+ tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt
new file mode 100644
index 0000000..cecdd3d
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/IdomeSongFragment.kt
@@ -0,0 +1,23 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+import com.example.mission3.databinding.FragmentSongIdomeBinding
+
+class IdomeSongFragment : Fragment() {
+ lateinit var binding: FragmentSongIdomeBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongIdomeBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/LikeAdapter.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/LikeAdapter.kt
new file mode 100644
index 0000000..4374509
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/LikeAdapter.kt
@@ -0,0 +1,32 @@
+package com.example.mission3
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.mission3.databinding.ItemLikedSongBinding
+
+class LikeAdapter(private val likedSongs: List) :
+ RecyclerView.Adapter() {
+
+ inner class LikeViewHolder(private val binding: ItemLikedSongBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+ fun bind(song: LikedSong) {
+ binding.titleTextView.text = song.title
+ binding.singerTextView.text = song.singer
+ binding.imageView.setImageResource(song.imageRes)
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LikeViewHolder {
+ val binding = ItemLikedSongBinding.inflate(
+ LayoutInflater.from(parent.context), parent, false
+ )
+ return LikeViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: LikeViewHolder, position: Int) {
+ holder.bind(likedSongs[position])
+ }
+
+ override fun getItemCount(): Int = likedSongs.size
+}
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/LikeFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/LikeFragment.kt
new file mode 100644
index 0000000..6923519
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/LikeFragment.kt
@@ -0,0 +1,55 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.example.mission3.databinding.FragmentLikeBinding
+import com.example.mission3.databinding.FragmentSavedSongBinding
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+class LikeFragment : Fragment() {
+
+ private lateinit var db: AppDatabase
+ private lateinit var likedSongDao: LikedSongDao
+
+ private lateinit var binding: FragmentLikeBinding
+ private val likedSongs = arrayListOf()
+ private lateinit var adapter: LikeAdapter // RecyclerView 어댑터
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentLikeBinding.inflate(inflater, container, false)
+
+ db = AppDatabase.getDatabase(requireContext())
+ likedSongDao = db.likedSongDao()
+
+ adapter = LikeAdapter(likedSongs)
+ binding.recyclerView.adapter = adapter
+ binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
+
+ loadLikedSongs()
+
+ return binding.root
+ }
+
+ private fun loadLikedSongs() {
+ lifecycleScope.launch {
+ val songs = likedSongDao.getAllLikedSongs()
+ likedSongs.clear()
+ likedSongs.addAll(songs)
+ withContext(Dispatchers.Main) {
+ adapter.notifyDataSetChanged()
+ }
+ }
+ }
+}
+
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/LikedSong.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/LikedSong.kt
new file mode 100644
index 0000000..f33c989
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/LikedSong.kt
@@ -0,0 +1,13 @@
+package com.example.mission3
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity
+data class LikedSong(
+ @PrimaryKey(autoGenerate = true) val id: Int = 0,
+ val title: String,
+ val singer: String,
+ val imageRes: Int,
+ val isLike: Boolean
+)
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/LikedSongDao.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/LikedSongDao.kt
new file mode 100644
index 0000000..8155c2a
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/LikedSongDao.kt
@@ -0,0 +1,23 @@
+package com.example.mission3
+
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+
+@Dao
+interface LikedSongDao {
+
+ @Query("SELECT * FROM LikedSong")
+ suspend fun getAllLikedSongs(): List
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun insert(song: LikedSong)
+
+ // 필요한 경우 삭제 메서드도 추가할 수 있음
+ @Delete
+ suspend fun delete(song: LikedSong)
+}
+
+
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt
new file mode 100644
index 0000000..21956a8
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/MainActivity.kt
@@ -0,0 +1,186 @@
+package com.example.mission3
+
+import android.content.Context.MODE_PRIVATE
+import android.content.Intent
+import android.content.SharedPreferences
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.example.mission3.databinding.ActivityMainBinding
+import com.google.android.material.bottomnavigation.BottomNavigationView
+import kotlinx.coroutines.launch
+import java.util.*
+
+class MainActivity : AppCompatActivity() {
+ private lateinit var binding: ActivityMainBinding
+ private lateinit var sharedPreferences: SharedPreferences
+ private lateinit var bottomNavi: BottomNavigationView
+ private lateinit var dbHelper: SongDatabaseHelper
+ private lateinit var songViewModel: SongViewModel
+
+ private val songList = listOf(
+ Song(id = 1, title = "HAPPY", singer = "DAY6(데이식스)", second = 0, playTime = 190, isPlaying = false, isLike = false, imageRes = R.drawable.happy),
+ Song(id = 2, title = "I DO ME", singer = "KiiiKiii (키키)", second = 0, playTime = 191, isPlaying = false, isLike = false, imageRes = R.drawable.idome),
+ Song(id = 3, title = "Drowning", singer = "WOODZ", second = 0, playTime = 245, isPlaying = false, isLike = false, imageRes = R.drawable.drowning)
+ )
+ private var currentSongIndex = 0
+ private var timer: Timer? = null
+ private var isPlaying = false
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ songViewModel = ViewModelProvider(this)[SongViewModel::class.java]
+
+ sharedPreferences = getSharedPreferences("MusicApp", MODE_PRIVATE)
+ dbHelper = SongDatabaseHelper(this)
+
+ lifecycleScope.launch {
+ insertDummySongs()
+ }
+
+ if (savedInstanceState == null) {
+ supportFragmentManager.beginTransaction()
+ .replace(R.id.main, HomeFragment())
+ .commit()
+ }
+
+ window.statusBarColor = resources.getColor(android.R.color.white, theme)
+
+ bottomNavi = binding.bottomNavi
+ bottomNavi.setOnItemSelectedListener { item ->
+ when (item.itemId) {
+ R.id.action_home -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, HomeFragment()).commit()
+ true
+ }
+ R.id.action_audio -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, AudioFrag()).commit()
+ true
+ }
+ R.id.action_search -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, SearchFrag()).commit()
+ true
+ }
+ R.id.action_mymusic -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, MyMusicFragment()).commit()
+ true
+ }
+ R.id.action_menu -> {
+ supportFragmentManager.beginTransaction().replace(R.id.main, MenuFrag()).commit()
+ true
+ }
+ else -> false
+ }
+ }
+
+ binding.mainPlayerCl.setOnClickListener {
+ val song = songList[currentSongIndex]
+ val currentTime = binding.miniPlayerSeekbar.progress
+
+ val intent = Intent(this, SongActivity::class.java).apply {
+ putExtra("current_position", binding.miniPlayerSeekbar.progress)
+ putExtra("songTitle", song.title)
+ putExtra("songSinger", song.singer)
+ putExtra("songProgress", currentTime)
+ putExtra("songDuration", song.playTime)
+ putExtra("songImageRes", song.imageRes)
+ }
+ startActivity(intent)
+ }
+
+ binding.prevBtn.setOnClickListener {
+ currentSongIndex = if (currentSongIndex - 1 < 0) songList.size - 1 else currentSongIndex - 1
+ updateMiniPlayer(songList[currentSongIndex])
+ }
+
+ binding.nextBtn.setOnClickListener {
+ currentSongIndex = (currentSongIndex + 1) % songList.size
+ updateMiniPlayer(songList[currentSongIndex])
+ }
+
+ binding.playPauseBtn.setOnClickListener {
+ isPlaying = !isPlaying
+ if (isPlaying) {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_pause_24)
+ startSeekBar(songList[currentSongIndex])
+ } else {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ timer?.cancel()
+ }
+ }
+
+ songViewModel.currentSong.observe(this) { song ->
+ binding.miniPlayerSongTitleTv.text = song.title
+ binding.miniPlayerSingerTv.text = song.singer
+ if (song.isPlaying) {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_pause_24)
+ } else {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ }
+ }
+
+ updateMiniPlayer(songList[currentSongIndex])
+ }
+
+ private fun updateMiniPlayer(song: Song) {
+ binding.miniPlayerSongTitleTv.text = song.title
+ binding.miniPlayerSingerTv.text = song.singer
+ binding.miniPlayerSeekbar.max = song.playTime
+ binding.miniPlayerSeekbar.progress = song.second
+ saveSongId(song.id)
+
+ if (isPlaying) {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_pause_24)
+ startSeekBar(song)
+ } else {
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ timer?.cancel()
+ }
+ }
+
+ private fun startSeekBar(song: Song) {
+ timer?.cancel()
+ var progress = binding.miniPlayerSeekbar.progress
+ timer = Timer()
+ timer?.scheduleAtFixedRate(object : TimerTask() {
+ override fun run() {
+ runOnUiThread {
+ if (progress < song.playTime) {
+ progress++
+ binding.miniPlayerSeekbar.progress = progress
+ } else {
+ timer?.cancel()
+ isPlaying = false
+ binding.playPauseBtn.setImageResource(R.drawable.baseline_play_24)
+ }
+ }
+ }
+ }, 1000, 1000)
+ }
+
+ private suspend fun insertDummySongs() {
+ for (song in songList) {
+ dbHelper.insertSong(song)
+ }
+ }
+
+ private fun saveSongId(songId: Int) {
+ val editor = sharedPreferences.edit()
+ editor.putInt("songId", songId)
+ editor.putInt("songTime", binding.miniPlayerSeekbar.progress)
+ editor.apply()
+ }
+
+ private fun getSongIdFromPreferences(): Int {
+ return sharedPreferences.getInt("songId", 0)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ timer?.cancel()
+ }
+}
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt
new file mode 100644
index 0000000..52d5fd8
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/MenuFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragMenuBinding
+import com.example.mission3.databinding.FragMymusicBinding
+
+class MenuFrag : Fragment() {
+ private var _binding: FragMenuBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragMenuBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt
new file mode 100644
index 0000000..dfcd9f4
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/MusicFileFragment.kt
@@ -0,0 +1,19 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentMusicFileBinding
+
+class MusicFileFragment: Fragment() {
+
+ lateinit var binding: FragmentMusicFileBinding
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ binding = FragmentMusicFileBinding.inflate(inflater, container, false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt
new file mode 100644
index 0000000..7201acc
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/MyMusicAlbumRVAdapter.kt
@@ -0,0 +1,39 @@
+package com.example.mission3
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.mission3.databinding.ItemMymusicAlbumBinding
+
+class MyMusicAlbumRVAdapter(private val songList: MutableList) :
+ RecyclerView.Adapter() {
+
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = ItemMymusicAlbumBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bind(songList[position])
+ holder.binding.itemMymusicAlbumMoreIv.setOnClickListener {
+ removeItem(position)
+ }
+ }
+
+ override fun getItemCount(): Int = songList.size
+
+ fun removeItem(position: Int) {
+ songList.removeAt(position)
+ notifyItemRemoved(position)
+ notifyItemRangeChanged(position, songList.size)
+ }
+
+ inner class ViewHolder(val binding: ItemMymusicAlbumBinding) : RecyclerView.ViewHolder(binding.root) {
+ fun bind(song: Song) {
+ binding.itemMymusicAlbumTitleTv.text = song.title
+ binding.itemMymusicAlbumSingerTv.text = song.singer
+ binding.itemMymusicAlbumCoverImgIv.setImageResource(song.imageRes)
+ }
+ }
+}
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt
new file mode 100644
index 0000000..6dd03c7
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/MyMusicFragment.kt
@@ -0,0 +1,30 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.google.android.material.tabs.TabLayoutMediator
+import com.example.mission3.databinding.FragMymusicBinding
+
+class MyMusicFragment : Fragment() {
+ private lateinit var binding: FragMymusicBinding
+ private val information = arrayListOf("저장한곡", "음악파일", "좋아요")
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ binding = FragMymusicBinding.inflate(inflater, container, false)
+
+ val lockerAdapter = MyMusicVPAdapter(this)
+ binding.mymusicContentVp.adapter = lockerAdapter
+ TabLayoutMediator(binding.mymusicContentTb, binding.mymusicContentVp) { tab, position ->
+ tab.text = information[position]
+ }.attach()
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt
new file mode 100644
index 0000000..32dc780
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/MyMusicVPAdapter.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.fragment.app.Fragment
+import androidx.viewpager2.adapter.FragmentStateAdapter
+
+class MyMusicVPAdapter (fragment: Fragment) : FragmentStateAdapter(fragment) {
+ override fun getItemCount() : Int = 3
+
+ override fun createFragment(position: Int): Fragment {
+ return when(position) {
+ 0 -> SavedSongFragment()
+ 1 -> MusicFileFragment()
+ else -> LikeFragment()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt
new file mode 100644
index 0000000..6222cb8
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/RVAdapter.kt
@@ -0,0 +1,29 @@
+package com.example.mission3
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.example.mission3.databinding.RecyclerviewItemBinding
+
+class RVAdapter(private val items: MutableList) : RecyclerView.Adapter(){
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding: RecyclerviewItemBinding = RecyclerviewItemBinding
+ .inflate(LayoutInflater.from(parent.context), parent, false)
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ holder.bindItems(items[position])
+ }
+
+ override fun getItemCount(): Int = items.size
+
+ // ViewHolder 내부 클래스 정의
+ inner class ViewHolder(private val binding: RecyclerviewItemBinding) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bindItems(item: String) {
+ binding.itemAlbumTitleTv.text = item
+ }
+ }
+}
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt
new file mode 100644
index 0000000..3eb2990
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/SavedSongFragment.kt
@@ -0,0 +1,35 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.example.mission3.databinding.FragmentSavedSongBinding
+
+class SavedSongFragment : Fragment() {
+
+ //private var albumDatas = ArrayList()
+ lateinit var binding: FragmentSavedSongBinding
+ private lateinit var songViewModel: SongViewModel
+
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSavedSongBinding.inflate(inflater, container, false)
+
+ // ViewModel 연결
+ songViewModel = ViewModelProvider(requireActivity())[SongViewModel::class.java]
+
+ val adapter = MyMusicAlbumRVAdapter(songViewModel.songList.toMutableList())
+ binding.mymusicMusicAlbumRv.adapter = adapter
+ binding.mymusicMusicAlbumRv.layoutManager = LinearLayoutManager(requireActivity())
+
+ return binding.root
+ }
+}
+
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/SavedSongsFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/SavedSongsFragment.kt
new file mode 100644
index 0000000..0fa2f67
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/SavedSongsFragment.kt
@@ -0,0 +1,4 @@
+package com.example.mission3
+
+class SavedSongsFragment {
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt
new file mode 100644
index 0000000..61c15ea
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/SearchFrag.kt
@@ -0,0 +1,27 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragMymusicBinding
+import com.example.mission3.databinding.FragSearchBinding
+
+class SearchFrag : Fragment() {
+ private var _binding: FragSearchBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragSearchBinding.inflate(inflater, container, false)
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/Song.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/Song.kt
new file mode 100644
index 0000000..a6ec32e
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/Song.kt
@@ -0,0 +1,12 @@
+package com.example.mission3
+
+data class Song(
+ val title: String = "",
+ val singer: String = "",
+ var second: Int = 0,
+ var playTime: Int = 60,
+ var isPlaying: Boolean = false,
+ var isLike: Boolean = false, // 좋아요 상태 추가
+ val id: Int = 0, // Primary key를 수동으로 관리
+ val imageRes: Int = 0 // 이미지 리소스를 추가 (이미지 리소스 ID)
+)
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt
new file mode 100644
index 0000000..2f4bff3
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/SongActivity.kt
@@ -0,0 +1,286 @@
+package com.example.mission3
+
+import android.content.Context.MODE_PRIVATE
+import android.content.SharedPreferences
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.os.CountDownTimer
+import android.os.Handler
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.edit
+import androidx.lifecycle.lifecycleScope
+import com.example.mission3.databinding.ActivitySongBinding
+import kotlinx.coroutines.launch
+
+class SongActivity : AppCompatActivity() {
+ private lateinit var binding: ActivitySongBinding
+ private lateinit var song: Song
+ private var isPlaying = false
+ private var currentTime = 0 // 현재 재생 시간 (초 단위)
+ private lateinit var sharedPreferences: SharedPreferences
+ private var isFavorite = false
+ private var songList: List = listOf() // 곡 리스트
+ private var currentSongIndex: Int = 0 // 현재 곡 인덱스
+
+ private lateinit var db: AppDatabase
+ private lateinit var likedSongDao: LikedSongDao
+
+
+ private val handler = Handler()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivitySongBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ db = AppDatabase.getDatabase(this)
+ likedSongDao = db.likedSongDao()
+
+
+ sharedPreferences = getSharedPreferences("MyMusicApp", MODE_PRIVATE)
+
+ // Intent에서 받은 데이터를 기반으로 초기화
+ val songTitle = intent.getStringExtra("songTitle")
+ val songSinger = intent.getStringExtra("songSinger")
+ currentTime = intent.getIntExtra("songProgress", 0)
+ val songDuration = intent.getIntExtra("songDuration", 0)
+ val key = "$songTitle-$songSinger"
+ val imageResFromPrefs = sharedPreferences.getInt("${key}_imageRes", -1)
+ val imageRes = if (imageResFromPrefs != -1) imageResFromPrefs else {
+ intent.getIntExtra("songImageRes", R.drawable.happy)
+ }
+
+ // Song 객체 초기화
+ song = Song(
+ title = songTitle ?: "",
+ singer = songSinger ?: "",
+ second = currentTime,
+ playTime = songDuration,
+ isPlaying = false,
+ isLike = false,
+ id = 0,
+ imageRes = imageRes
+ )
+
+
+ songList = listOf(
+ Song("HAPPY", "DAY6(데이식스)", 0, 190, false, imageRes = R.drawable.happy),
+ Song("I DO ME", "KiiiKiii (키키)", 0, 191, false, imageRes = R.drawable.idome),
+ Song("Drowning", "WOODZ", 0, 245, false, imageRes = R.drawable.drowning)
+ )
+ currentSongIndex = songList.indexOf(song) // song에 맞는 인덱스를 찾습니다.
+
+ setPlayer(song) // 플레이어 설정
+
+ // 즐겨찾기 상태 로드
+ loadFavoriteStatus()
+ updateFavoriteButton()
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ window.statusBarColor = Color.parseColor("#FFFFFF")
+ }
+
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ binding.songSettingIb.setOnClickListener {
+ finish()
+ }
+
+ binding.playPauseButton.setOnClickListener {
+ if (isPlaying) {
+ pauseSong()
+ } else {
+ playSong()
+ }
+ }
+
+ // 즐겨찾기 버튼 클릭 리스너
+ binding.favoriteButton.setOnClickListener {
+ isFavorite = !isFavorite
+ updateFavoriteButton()
+
+ lifecycleScope.launch {
+ val likedSong = LikedSong(
+ title = song.title,
+ singer = song.singer,
+ imageRes = song.imageRes,
+ isLike = isFavorite
+ )
+
+ if (isFavorite) {
+ likedSongDao.insert(likedSong)
+ runOnUiThread {
+ Toast.makeText(this@SongActivity, "좋아요 저장 완료", Toast.LENGTH_SHORT).show()
+ }
+ } else {
+ likedSongDao.delete(likedSong)
+ runOnUiThread {
+ Toast.makeText(this@SongActivity, "좋아요 취소", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+ // SharedPreferences도 함께 저장
+ saveFavoriteStatus()
+ }
+
+ // 이전 곡 버튼 클릭 리스너
+ binding.skipPrevious.setOnClickListener {
+ goToPreviousSong()
+ }
+
+ // 다음 곡 버튼 클릭 리스너
+ binding.songNextIv.setOnClickListener {
+ goToNextSong()
+ }
+ }
+
+ private fun setPlayer(song: Song) {
+ binding.songTitleTv.text = song.title
+ binding.songSingerTv.text = song.singer
+ binding.songStartTimeTv.text = String.format("%02d:%02d", song.second / 60, song.second % 60)
+ binding.songEndTimeTv.text = String.format("%02d:%02d", song.playTime / 60, song.playTime % 60)
+
+ binding.songAlbumIv.setImageResource(song.imageRes)
+
+ binding.songProgressbarView.max = song.playTime * 1000
+ binding.songProgressbarView.progress = song.second * 1000
+
+ setPlayerStatus(song.isPlaying)
+ }
+
+ private fun setPlayerStatus(isPlaying: Boolean) {
+ if (isPlaying) {
+ binding.playPauseButton.setImageResource(R.drawable.baseline_pause_24)
+ binding.songProgressbarView.progressTintList = ColorStateList.valueOf(Color.parseColor("#81BEF7"))
+ startTimer() // 타이머 시작
+ } else {
+ binding.playPauseButton.setImageResource(R.drawable.baseline_play_24)
+ binding.songProgressbarView.progressTintList = ColorStateList.valueOf(Color.GRAY)
+ }
+ }
+
+ private fun startTimer() {
+ handler.postDelayed(object : Runnable {
+ override fun run() {
+ if (isPlaying) {
+ currentTime++
+ updateSeekBar() // SeekBar 업데이트
+ updateTimeDisplay() // 시간 텍스트 업데이트
+ if (currentTime < song.playTime) {
+ handler.postDelayed(this, 1000) // 1초 후에 다시 실행
+ }
+ }
+ }
+ }, 1000)
+ }
+
+ private fun updateSeekBar() {
+ binding.songProgressbarView.progress = currentTime * 1000
+ }
+
+ private fun updateTimeDisplay() {
+ val minutes = currentTime / 60
+ val seconds = currentTime % 60
+ binding.songStartTimeTv.text = String.format("%02d:%02d", minutes, seconds)
+
+ val remainingTime = song.playTime - currentTime
+ val endMinutes = remainingTime / 60
+ val endSeconds = remainingTime % 60
+ binding.songEndTimeTv.text = String.format("-%02d:%02d", endMinutes, endSeconds)
+ }
+
+ private fun playSong() {
+ isPlaying = true
+ setPlayerStatus(isPlaying)
+ }
+
+ private fun pauseSong() {
+ isPlaying = false
+ handler.removeCallbacksAndMessages(null) // 타이머 취소
+ setPlayerStatus(isPlaying)
+ }
+
+ private fun updateFavoriteButton() {
+ if (isFavorite) {
+ binding.favoriteButton.setImageResource(R.drawable.baseline_favorite_24)
+ } else {
+ binding.favoriteButton.setImageResource(R.drawable.baseline_favorite_border_24)
+ }
+ }
+
+ private fun saveFavoriteStatus() {
+ val key = "${song.title}-${song.singer}"
+ sharedPreferences.edit {
+ putBoolean(key, isFavorite)
+ putInt("${key}_imageRes", song.imageRes) // 이미지 리소스 ID 저장
+ }
+ }
+
+ private fun loadFavoriteStatus() {
+ val key = "${song.title}-${song.singer}"
+ isFavorite = sharedPreferences.getBoolean(key, false)
+ }
+
+ private fun goToPreviousSong() {
+ if (currentSongIndex > 0) {
+ currentSongIndex--
+ song = songList[currentSongIndex]
+ setPlayer(song)
+ stopSong()
+ playSong()
+
+ sharedPreferences.edit {
+ putInt("current_song_index", currentSongIndex)
+ }
+ }
+ }
+
+ private fun goToNextSong() {
+ if (currentSongIndex < songList.size - 1) {
+ currentSongIndex++
+ song = songList[currentSongIndex]
+ currentTime = 0 // 시간 초기화
+ setPlayer(song)
+ stopSong()
+ playSong()
+
+ sharedPreferences.edit {
+ putInt("current_song_index", currentSongIndex)
+ }
+ }
+ }
+
+ private fun stopSong() {
+ // 곡 멈추기
+ isPlaying = false
+ handler.removeCallbacksAndMessages(null)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ // 타이머는 멈추지 않고 상태 유지
+ }
+
+ override fun onResume() {
+ super.onResume()
+ // 화면이 다시 보여질 때 타이머가 계속 진행되도록 설정
+ if (isPlaying) {
+ startTimer() // 타이머 다시 시작
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ handler.removeCallbacksAndMessages(null) // 화면 종료 시 타이머 정지
+ }
+
+ override fun onSupportNavigateUp(): Boolean {
+ onBackPressed()
+ return true
+ }
+}
+
+
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt
new file mode 100644
index 0000000..56317b3
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/SongDatabaseHelper.kt
@@ -0,0 +1,146 @@
+package com.example.mission3
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.database.sqlite.SQLiteDatabase
+import android.database.Cursor
+import android.content.ContentValues
+import android.database.SQLException
+import android.database.sqlite.SQLiteOpenHelper
+
+
+class SongDatabaseHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
+
+ companion object {
+ private const val DATABASE_NAME = "songs.db"
+ private const val DATABASE_VERSION = 1
+
+ // 테이블 및 컬럼 이름
+ const val TABLE_SONGS = "songs"
+ const val COLUMN_ID = "id"
+ const val COLUMN_TITLE = "title"
+ const val COLUMN_SINGER = "singer"
+ const val COLUMN_SECOND = "second"
+ const val COLUMN_PLAYTIME = "playTime"
+ const val COLUMN_ISPLAYING = "isPlaying"
+ const val COLUMN_ISLIKE = "isLike"
+ }
+
+ override fun onCreate(db: SQLiteDatabase?) {
+ val createTableQuery = """
+ CREATE TABLE $TABLE_SONGS (
+ $COLUMN_ID INTEGER PRIMARY KEY AUTOINCREMENT,
+ $COLUMN_TITLE TEXT,
+ $COLUMN_SINGER TEXT,
+ $COLUMN_SECOND INTEGER,
+ $COLUMN_PLAYTIME INTEGER,
+ $COLUMN_ISPLAYING INTEGER,
+ $COLUMN_ISLIKE INTEGER
+ )
+ """
+ db?.execSQL(createTableQuery)
+ }
+
+ override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
+ db?.execSQL("DROP TABLE IF EXISTS $TABLE_SONGS")
+ onCreate(db)
+ }
+
+ // Song 삽입 메서드
+ fun insertSong(song: Song): Long {
+ val db = writableDatabase
+ val values = ContentValues().apply {
+ put(COLUMN_TITLE, song.title)
+ put(COLUMN_SINGER, song.singer)
+ put(COLUMN_SECOND, song.second)
+ put(COLUMN_PLAYTIME, song.playTime)
+ put(COLUMN_ISPLAYING, if (song.isPlaying) 1 else 0)
+ put(COLUMN_ISLIKE, if (song.isLike) 1 else 0)
+ }
+
+ return db.insert(TABLE_SONGS, null, values)
+ }
+
+ // Song 업데이트 메서드
+ fun updateSong(song: Song) {
+ val db = writableDatabase
+ val values = ContentValues().apply {
+ put(COLUMN_TITLE, song.title)
+ put(COLUMN_SINGER, song.singer)
+ put(COLUMN_SECOND, song.second)
+ put(COLUMN_PLAYTIME, song.playTime)
+ put(COLUMN_ISPLAYING, if (song.isPlaying) 1 else 0)
+ put(COLUMN_ISLIKE, if (song.isLike) 1 else 0)
+ }
+
+ db.update(TABLE_SONGS, values, "$COLUMN_ID = ?", arrayOf(song.id.toString()))
+ }
+
+ // ID로 Song 조회 메서드
+ @SuppressLint("Range")
+ fun getSongById(id: Int): Song? {
+ val db = readableDatabase
+ val cursor: Cursor = db.query(
+ TABLE_SONGS,
+ null,
+ "$COLUMN_ID = ?",
+ arrayOf(id.toString()),
+ null,
+ null,
+ null
+ )
+
+ return if (cursor.moveToFirst()) {
+ val title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE))
+ val singer = cursor.getString(cursor.getColumnIndex(COLUMN_SINGER))
+ val second = cursor.getInt(cursor.getColumnIndex(COLUMN_SECOND))
+ val playTime = cursor.getInt(cursor.getColumnIndex(COLUMN_PLAYTIME))
+ val isPlaying = cursor.getInt(cursor.getColumnIndex(COLUMN_ISPLAYING)) == 1
+ val isLike = cursor.getInt(cursor.getColumnIndex(COLUMN_ISLIKE)) == 1
+ val songId = cursor.getInt(cursor.getColumnIndex(COLUMN_ID))
+
+ Song(title, singer, second, playTime, isPlaying, isLike, songId)
+ } else {
+ null
+ }
+ }
+
+ // 모든 Song 조회 메서드
+ @SuppressLint("Range")
+ fun getAllSongs(): List {
+ val songList = mutableListOf()
+ val db = readableDatabase
+ val cursor: Cursor = db.query(
+ TABLE_SONGS,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null
+ )
+
+ if (cursor.moveToFirst()) {
+ do {
+ val title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE))
+ val singer = cursor.getString(cursor.getColumnIndex(COLUMN_SINGER))
+ val second = cursor.getInt(cursor.getColumnIndex(COLUMN_SECOND))
+ val playTime = cursor.getInt(cursor.getColumnIndex(COLUMN_PLAYTIME))
+ val isPlaying = cursor.getInt(cursor.getColumnIndex(COLUMN_ISPLAYING)) == 1
+ val isLike = cursor.getInt(cursor.getColumnIndex(COLUMN_ISLIKE)) == 1
+ val songId = cursor.getInt(cursor.getColumnIndex(COLUMN_ID))
+
+ songList.add(Song(title, singer, second, playTime, isPlaying, isLike, songId))
+ } while (cursor.moveToNext())
+ }
+
+ cursor.close()
+ return songList
+ }
+
+ // Song 삭제 메서드
+ fun deleteSong(id: Int) {
+ val db = writableDatabase
+ db.delete(TABLE_SONGS, "$COLUMN_ID = ?", arrayOf(id.toString()))
+ }
+}
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt
new file mode 100644
index 0000000..56f6e2a
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/SongFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.example.mission3.databinding.FragmentSongBinding
+
+class SongFragment : Fragment() {
+ lateinit var binding: FragmentSongBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentSongBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/SongViewModel.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/SongViewModel.kt
new file mode 100644
index 0000000..6bd5fad
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/SongViewModel.kt
@@ -0,0 +1,16 @@
+package com.example.mission3
+
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+
+class SongViewModel : ViewModel() {
+ val currentSong = MutableLiveData()
+
+ // 노래 목록 관리용 (필요 시)
+ val songList = listOf(
+ Song("Happy", "DAY6(데이식스)", 0, 190, false, false, R.drawable.happy),
+ Song("I DO ME", "KiiiKiii (키키)", 0, 191, false, false, R.drawable.idome),
+ Song("Drowning", "WOODZ", 0, 245, false, false, R.drawable.drowning)
+ )
+}
+
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt
new file mode 100644
index 0000000..9314d0f
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/ThreeBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner3Binding
+
+class ThreeBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner3Binding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner3Binding.inflate(inflater,container,false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt
new file mode 100644
index 0000000..879e2d7
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/TwoBannerFragment.kt
@@ -0,0 +1,21 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.example.mission3.databinding.FragmentBanner2Binding
+
+class TwoBannerFragment : Fragment() {
+ lateinit var binding : FragmentBanner2Binding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentBanner2Binding.inflate(inflater,container,false)
+
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt b/Work7/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt
new file mode 100644
index 0000000..cb0b9b0
--- /dev/null
+++ b/Work7/Mission3/app/src/main/java/com/example/mission3/ViedoFragment.kt
@@ -0,0 +1,22 @@
+package com.example.mission3
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+
+import com.example.mission3.databinding.FragmentVideoBinding
+
+class ViedoFragment : Fragment() {
+ lateinit var binding: FragmentVideoBinding
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ binding = FragmentVideoBinding.inflate(inflater,container,false)
+ return binding.root
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/drawable/banner1.jpg b/Work7/Mission3/app/src/main/res/drawable/banner1.jpg
new file mode 100644
index 0000000..81524e1
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/drawable/banner1.jpg differ
diff --git a/Work7/Mission3/app/src/main/res/drawable/banner2.jpg b/Work7/Mission3/app/src/main/res/drawable/banner2.jpg
new file mode 100644
index 0000000..bc20bf4
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/drawable/banner2.jpg differ
diff --git a/Work7/Mission3/app/src/main/res/drawable/banner3.jpg b/Work7/Mission3/app/src/main/res/drawable/banner3.jpg
new file mode 100644
index 0000000..8b55d5f
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/drawable/banner3.jpg differ
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml
new file mode 100644
index 0000000..99f85de
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_arrow_back_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml
new file mode 100644
index 0000000..1a69b23
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_arrow_down_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml
new file mode 100644
index 0000000..6e3d747
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_arrow_right_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_audio_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_audio_24.xml
new file mode 100644
index 0000000..82ea4d3
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_audio_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_check_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_check_24.xml
new file mode 100644
index 0000000..356e998
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_check_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml
new file mode 100644
index 0000000..badf5ea
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_favorite_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml
new file mode 100644
index 0000000..2acceab
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_favorite_border_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_home_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_home_24.xml
new file mode 100644
index 0000000..20cb4d6
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_home_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml
new file mode 100644
index 0000000..0e5587b
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_horizontal_line_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml
new file mode 100644
index 0000000..1146d4c
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_insert_link_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml
new file mode 100644
index 0000000..a7912d8
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_instagram_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_menu_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_menu_24.xml
new file mode 100644
index 0000000..75c361f
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_menu_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml
new file mode 100644
index 0000000..52ede6a
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_music_list_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml
new file mode 100644
index 0000000..c9c2ad9
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_mymusic_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_next_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_next_24.xml
new file mode 100644
index 0000000..4904368
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_next_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_pause_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_pause_24.xml
new file mode 100644
index 0000000..ae853f2
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_pause_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml
new file mode 100644
index 0000000..1e24cf3
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_person_circle_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_play_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_play_24.xml
new file mode 100644
index 0000000..b176182
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_play_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_play_more24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_play_more24.xml
new file mode 100644
index 0000000..5ffb98a
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_play_more24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml
new file mode 100644
index 0000000..c7d89f1
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_random_music_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml
new file mode 100644
index 0000000..151a3e1
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_repeat_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_search_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_search_24.xml
new file mode 100644
index 0000000..d29c6ea
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_search_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml
new file mode 100644
index 0000000..5a79f5e
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_skip_next_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml
new file mode 100644
index 0000000..7951d71
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_skip_previous_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_star_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_star_24.xml
new file mode 100644
index 0000000..925b973
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_star_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml
new file mode 100644
index 0000000..f775f11
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_toggle_off_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/baseline_volume_24.xml b/Work7/Mission3/app/src/main/res/drawable/baseline_volume_24.xml
new file mode 100644
index 0000000..a53186e
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/baseline_volume_24.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/drowning.jpg b/Work7/Mission3/app/src/main/res/drawable/drowning.jpg
new file mode 100644
index 0000000..97fa652
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/drawable/drowning.jpg differ
diff --git a/Work7/Mission3/app/src/main/res/drawable/happy.jpg b/Work7/Mission3/app/src/main/res/drawable/happy.jpg
new file mode 100644
index 0000000..6b24b63
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/drawable/happy.jpg differ
diff --git a/Work7/Mission3/app/src/main/res/drawable/ic_launcher_background.xml b/Work7/Mission3/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml b/Work7/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/drawable/idome.jpg b/Work7/Mission3/app/src/main/res/drawable/idome.jpg
new file mode 100644
index 0000000..b40b38f
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/drawable/idome.jpg differ
diff --git a/Work7/Mission3/app/src/main/res/layout/activity_main.xml b/Work7/Mission3/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..dded351
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/layout/activity_song.xml b/Work7/Mission3/app/src/main/res/layout/activity_song.xml
new file mode 100644
index 0000000..6be6395
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/activity_song.xml
@@ -0,0 +1,283 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/frag_audio.xml b/Work7/Mission3/app/src/main/res/layout/frag_audio.xml
new file mode 100644
index 0000000..ae66603
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/frag_audio.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/frag_menu.xml b/Work7/Mission3/app/src/main/res/layout/frag_menu.xml
new file mode 100644
index 0000000..d6811d0
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/frag_menu.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/frag_mymusic.xml b/Work7/Mission3/app/src/main/res/layout/frag_mymusic.xml
new file mode 100644
index 0000000..6b3bd08
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/frag_mymusic.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/frag_search.xml b/Work7/Mission3/app/src/main/res/layout/frag_search.xml
new file mode 100644
index 0000000..d523e6e
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/frag_search.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_album.xml b/Work7/Mission3/app/src/main/res/layout/fragment_album.xml
new file mode 100644
index 0000000..825ab0d
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_album.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_album_drowning.xml b/Work7/Mission3/app/src/main/res/layout/fragment_album_drowning.xml
new file mode 100644
index 0000000..e341853
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_album_drowning.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_album_idome.xml b/Work7/Mission3/app/src/main/res/layout/fragment_album_idome.xml
new file mode 100644
index 0000000..6792827
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_album_idome.xml
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_banner_1.xml b/Work7/Mission3/app/src/main/res/layout/fragment_banner_1.xml
new file mode 100644
index 0000000..142a6b8
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_banner_1.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_banner_2.xml b/Work7/Mission3/app/src/main/res/layout/fragment_banner_2.xml
new file mode 100644
index 0000000..f194ac2
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_banner_2.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_banner_3.xml b/Work7/Mission3/app/src/main/res/layout/fragment_banner_3.xml
new file mode 100644
index 0000000..5923f27
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_banner_3.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_detail.xml b/Work7/Mission3/app/src/main/res/layout/fragment_detail.xml
new file mode 100644
index 0000000..413125c
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_detail.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_home.xml b/Work7/Mission3/app/src/main/res/layout/fragment_home.xml
new file mode 100644
index 0000000..859952e
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_home.xml
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_like.xml b/Work7/Mission3/app/src/main/res/layout/fragment_like.xml
new file mode 100644
index 0000000..814e6de
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_like.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_music_file.xml b/Work7/Mission3/app/src/main/res/layout/fragment_music_file.xml
new file mode 100644
index 0000000..77d9ef6
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_music_file.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_saved_song.xml b/Work7/Mission3/app/src/main/res/layout/fragment_saved_song.xml
new file mode 100644
index 0000000..6130fb1
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_saved_song.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_saved_songs.xml b/Work7/Mission3/app/src/main/res/layout/fragment_saved_songs.xml
new file mode 100644
index 0000000..8fb800d
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_saved_songs.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_song.xml b/Work7/Mission3/app/src/main/res/layout/fragment_song.xml
new file mode 100644
index 0000000..7da782e
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_song.xml
@@ -0,0 +1,422 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_song_drowning.xml b/Work7/Mission3/app/src/main/res/layout/fragment_song_drowning.xml
new file mode 100644
index 0000000..6566743
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_song_drowning.xml
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_song_idome.xml b/Work7/Mission3/app/src/main/res/layout/fragment_song_idome.xml
new file mode 100644
index 0000000..e92ec6f
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_song_idome.xml
@@ -0,0 +1,421 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/fragment_video.xml b/Work7/Mission3/app/src/main/res/layout/fragment_video.xml
new file mode 100644
index 0000000..e86dad1
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/fragment_video.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/item_liked_song.xml b/Work7/Mission3/app/src/main/res/layout/item_liked_song.xml
new file mode 100644
index 0000000..bbb8fe1
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/item_liked_song.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work7/Mission3/app/src/main/res/layout/item_mymusic_album.xml b/Work7/Mission3/app/src/main/res/layout/item_mymusic_album.xml
new file mode 100644
index 0000000..2e9489b
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/item_mymusic_album.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/layout/recyclerview_item.xml b/Work7/Mission3/app/src/main/res/layout/recyclerview_item.xml
new file mode 100644
index 0000000..30c304a
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/layout/recyclerview_item.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/menu/menu.xml b/Work7/Mission3/app/src/main/res/menu/menu.xml
new file mode 100644
index 0000000..4472d4b
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/menu/menu.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Work7/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Work7/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Work7/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Work7/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Work7/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Work7/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Work7/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Work7/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Work7/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Work7/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Work7/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Work7/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Work7/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Work7/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Work7/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Work7/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Work7/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Work7/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Work7/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Work7/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Work7/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/Work7/Mission3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Work7/Mission3/app/src/main/res/values-night/themes.xml b/Work7/Mission3/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..ebeb9cd
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/values/colors.xml b/Work7/Mission3/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..aacedae
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/values/strings.xml b/Work7/Mission3/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..90c25e1
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/values/strings.xml
@@ -0,0 +1,12 @@
+
+ Mission3
+ NewJeans 이미지
+ 배너 이미지
+ Home
+ Album
+ Audio
+ Search
+ My Music
+ Menu
+ Play/Pause
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/values/themes.xml b/Work7/Mission3/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..66e5370
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/values/themes.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/xml/backup_rules.xml b/Work7/Mission3/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/main/res/xml/data_extraction_rules.xml b/Work7/Mission3/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/Work7/Mission3/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt b/Work7/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt
new file mode 100644
index 0000000..6c8895e
--- /dev/null
+++ b/Work7/Mission3/app/src/test/java/com/example/mission3/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.mission3
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt b/Work7/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt
new file mode 100644
index 0000000..49f80b4
--- /dev/null
+++ b/Work7/Mission3/app/src/test/java/com/example/missionn3/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.missionn3
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt b/Work7/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt
new file mode 100644
index 0000000..e500fb8
--- /dev/null
+++ b/Work7/Mission3/app/src/test/java/com/example/myapplication/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.myapplication
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work7/Mission3/build.gradle.kts b/Work7/Mission3/build.gradle.kts
new file mode 100644
index 0000000..922f551
--- /dev/null
+++ b/Work7/Mission3/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+}
\ No newline at end of file
diff --git a/Work7/Mission3/gradle.properties b/Work7/Mission3/gradle.properties
new file mode 100644
index 0000000..20e2a01
--- /dev/null
+++ b/Work7/Mission3/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Work7/Mission3/gradle/libs.versions.toml b/Work7/Mission3/gradle/libs.versions.toml
new file mode 100644
index 0000000..0b1b772
--- /dev/null
+++ b/Work7/Mission3/gradle/libs.versions.toml
@@ -0,0 +1,32 @@
+[versions]
+agp = "8.6.0"
+kotlin = "1.9.0"
+coreKtx = "1.13.1"
+junit = "4.13.2"
+junitVersion = "1.2.1"
+espressoCore = "3.6.1"
+appcompat = "1.7.0"
+material = "1.12.0"
+activity = "1.9.2"
+constraintlayout = "2.1.4"
+roomCommon = "2.6.1"
+roomKtx = "2.6.1"
+supportAnnotations = "28.0.0"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+androidx-room-common = { group = "androidx.room", name = "room-common", version.ref = "roomCommon" }
+androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "roomKtx" }
+support-annotations = { group = "com.android.support", name = "support-annotations", version.ref = "supportAnnotations" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+
diff --git a/Work7/Mission3/gradle/wrapper/gradle-wrapper.jar b/Work7/Mission3/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/Work7/Mission3/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Work7/Mission3/gradle/wrapper/gradle-wrapper.properties b/Work7/Mission3/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..e9384f5
--- /dev/null
+++ b/Work7/Mission3/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Oct 11 15:46:02 KST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Work7/Mission3/gradlew b/Work7/Mission3/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/Work7/Mission3/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Work7/Mission3/gradlew.bat b/Work7/Mission3/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/Work7/Mission3/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Work7/Mission3/settings.gradle.kts b/Work7/Mission3/settings.gradle.kts
new file mode 100644
index 0000000..f1d91db
--- /dev/null
+++ b/Work7/Mission3/settings.gradle.kts
@@ -0,0 +1,26 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "Mission3"
+include(":app")
+include(":app")
+include(":app")
+
\ No newline at end of file
diff --git a/Work8/Mission83/.gitignore b/Work8/Mission83/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/Work8/Mission83/.gitignore
@@ -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
diff --git a/Work8/Mission83/.idea/.gitignore b/Work8/Mission83/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Work8/Mission83/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Work8/Mission83/.idea/.name b/Work8/Mission83/.idea/.name
new file mode 100644
index 0000000..68b78bc
--- /dev/null
+++ b/Work8/Mission83/.idea/.name
@@ -0,0 +1 @@
+Mission8
\ No newline at end of file
diff --git a/Work8/Mission83/.idea/compiler.xml b/Work8/Mission83/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/Work8/Mission83/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/.idea/deploymentTargetSelector.xml b/Work8/Mission83/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/Work8/Mission83/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/.idea/gradle.xml b/Work8/Mission83/.idea/gradle.xml
new file mode 100644
index 0000000..7b3006b
--- /dev/null
+++ b/Work8/Mission83/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/.idea/kotlinc.xml b/Work8/Mission83/.idea/kotlinc.xml
new file mode 100644
index 0000000..148fdd2
--- /dev/null
+++ b/Work8/Mission83/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/.idea/migrations.xml b/Work8/Mission83/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/Work8/Mission83/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/.idea/misc.xml b/Work8/Mission83/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/Work8/Mission83/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/.idea/runConfigurations.xml b/Work8/Mission83/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/Work8/Mission83/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/.gitignore b/Work8/Mission83/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Work8/Mission83/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Work8/Mission83/app/build.gradle.kts b/Work8/Mission83/app/build.gradle.kts
new file mode 100644
index 0000000..2dbaf5e
--- /dev/null
+++ b/Work8/Mission83/app/build.gradle.kts
@@ -0,0 +1,49 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.mission8"
+ compileSdk = 35
+
+ defaultConfig {
+ applicationId = "com.example.mission8"
+ minSdk = 24
+ targetSdk = 35
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+}
+
+dependencies {
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.activity)
+ implementation(libs.androidx.constraintlayout)
+ implementation(libs.androidx.room.runtime.android)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
\ No newline at end of file
diff --git a/Work8/Mission83/app/proguard-rules.pro b/Work8/Mission83/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Work8/Mission83/app/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/androidTest/java/com/example/mission8/ExampleInstrumentedTest.kt b/Work8/Mission83/app/src/androidTest/java/com/example/mission8/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..08ec283
--- /dev/null
+++ b/Work8/Mission83/app/src/androidTest/java/com/example/mission8/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.mission8
+
+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.mission8", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/AndroidManifest.xml b/Work8/Mission83/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..90edc3f
--- /dev/null
+++ b/Work8/Mission83/app/src/main/AndroidManifest.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/java/com/example/mission8/AppDatabase.kt b/Work8/Mission83/app/src/main/java/com/example/mission8/AppDatabase.kt
new file mode 100644
index 0000000..465d341
--- /dev/null
+++ b/Work8/Mission83/app/src/main/java/com/example/mission8/AppDatabase.kt
@@ -0,0 +1,29 @@
+package com.example.mission8
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+
+@Database(entities = [User::class], version = 1)
+abstract class AppDatabase : RoomDatabase() {
+ abstract fun userDao(): UserDao
+
+ companion object {
+ @Volatile
+ private var INSTANCE: AppDatabase? = null
+
+ fun getDatabase(context: Context): AppDatabase {
+ return INSTANCE ?: synchronized(this) {
+ val instance = Room.databaseBuilder(
+ context.applicationContext,
+ AppDatabase::class.java,
+ "user_database"
+ ).build()
+ INSTANCE = instance
+ instance
+ }
+ }
+ }
+}
+
diff --git a/Work8/Mission83/app/src/main/java/com/example/mission8/LoginActivity.kt b/Work8/Mission83/app/src/main/java/com/example/mission8/LoginActivity.kt
new file mode 100644
index 0000000..93f706a
--- /dev/null
+++ b/Work8/Mission83/app/src/main/java/com/example/mission8/LoginActivity.kt
@@ -0,0 +1,61 @@
+package com.example.mission8
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.widget.Button
+import android.widget.EditText
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.lifecycleScope
+import kotlinx.coroutines.launch
+
+class LoginActivity : AppCompatActivity() {
+
+ private lateinit var db: AppDatabase
+ private lateinit var userDao: UserDao
+
+ private fun saveUserId(context: Context, id: Int) {
+ val pref = context.getSharedPreferences("user_pref", Context.MODE_PRIVATE)
+ pref.edit().putInt("id", id).apply()
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_login)
+
+ db = AppDatabase.getDatabase(this)
+ userDao = db.userDao()
+
+ val emailEditText = findViewById(R.id.etEmail)
+ val passwordEditText = findViewById(R.id.etPassword)
+ val loginButton = findViewById(R.id.btnLogin)
+
+ loginButton.setOnClickListener {
+ val email = emailEditText.text.toString()
+ val password = passwordEditText.text.toString()
+
+ if (email.isBlank() || password.isBlank()) {
+ Toast.makeText(this, "이메일과 비밀번호를 입력해주세요.", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ lifecycleScope.launch {
+ val user = userDao.getUserByEmailAndPassword(email, password)
+ runOnUiThread {
+ if (user != null) {
+ Toast.makeText(this@LoginActivity, "로그인 성공!", Toast.LENGTH_SHORT).show()
+ saveUserId(this@LoginActivity, user.id)
+ // 로그인 성공 후 다음 화면 이동 예: MainActivity
+ startActivity(Intent(this@LoginActivity, MainActivity::class.java))
+ finish()
+ } else {
+ Toast.makeText(this@LoginActivity, "로그인 실패: 회원정보가 없습니다.", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+ }
+ }
+}
+
+
diff --git a/Work8/Mission83/app/src/main/java/com/example/mission8/MainActivity.kt b/Work8/Mission83/app/src/main/java/com/example/mission8/MainActivity.kt
new file mode 100644
index 0000000..32d452f
--- /dev/null
+++ b/Work8/Mission83/app/src/main/java/com/example/mission8/MainActivity.kt
@@ -0,0 +1,20 @@
+package com.example.mission8
+
+import android.os.Bundle
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.ViewCompat
+import androidx.core.view.WindowInsetsCompat
+
+class MainActivity : AppCompatActivity() {
+ 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
+ }
+ }
+}
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/java/com/example/mission8/SignUpActivity.kt b/Work8/Mission83/app/src/main/java/com/example/mission8/SignUpActivity.kt
new file mode 100644
index 0000000..4fbb010
--- /dev/null
+++ b/Work8/Mission83/app/src/main/java/com/example/mission8/SignUpActivity.kt
@@ -0,0 +1,59 @@
+package com.example.mission8
+
+import android.os.Bundle
+import android.widget.Button
+import android.widget.EditText
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.lifecycleScope
+import kotlinx.coroutines.launch
+
+class SignUpActivity : AppCompatActivity() {
+
+ private lateinit var db: AppDatabase
+ private lateinit var userDao: UserDao
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_sign_up)
+
+ db = AppDatabase.getDatabase(this)
+ userDao = db.userDao()
+
+ val emailEditText = findViewById(R.id.etEmail)
+ val passwordEditText = findViewById(R.id.etPassword)
+ val nameEditText = findViewById(R.id.etName)
+ val signUpButton = findViewById(R.id.btnSignUp)
+
+ signUpButton.setOnClickListener {
+ val email = emailEditText.text.toString()
+ val password = passwordEditText.text.toString()
+ val name = nameEditText.text.toString()
+
+ if (email.isBlank() || password.isBlank() || name.isBlank()) {
+ Toast.makeText(this, "모든 필드를 입력해주세요.", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
+ }
+
+ lifecycleScope.launch {
+ val newUser = User(email, password, name)
+ val id = userDao.insert(newUser)
+
+ runOnUiThread {
+ if (id > 0) {
+ Toast.makeText(this@SignUpActivity, "회원가입 성공!", Toast.LENGTH_SHORT).show()
+ finish() // 가입 후 이전 화면으로 돌아가기
+ } else {
+ Toast.makeText(this@SignUpActivity, "회원가입 실패!", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+
+
+
diff --git a/Work8/Mission83/app/src/main/java/com/example/mission8/User.kt b/Work8/Mission83/app/src/main/java/com/example/mission8/User.kt
new file mode 100644
index 0000000..e288c73
--- /dev/null
+++ b/Work8/Mission83/app/src/main/java/com/example/mission8/User.kt
@@ -0,0 +1,15 @@
+package com.example.mission8
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity(tableName = "UserTable")
+data class User(
+ val email: String,
+ val password: String,
+ val name: String
+) {
+ @PrimaryKey(autoGenerate = true)
+ var id: Int = 0
+}
+
diff --git a/Work8/Mission83/app/src/main/java/com/example/mission8/UserDao.kt b/Work8/Mission83/app/src/main/java/com/example/mission8/UserDao.kt
new file mode 100644
index 0000000..da2f7d1
--- /dev/null
+++ b/Work8/Mission83/app/src/main/java/com/example/mission8/UserDao.kt
@@ -0,0 +1,15 @@
+package com.example.mission8
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.Query
+
+@Dao
+interface UserDao {
+ @Insert
+ suspend fun insert(user: User): Long
+
+ @Query("SELECT * FROM UserTable WHERE email = :email AND password = :password LIMIT 1")
+ suspend fun getUserByEmailAndPassword(email: String, password: String): User?
+}
+
diff --git a/Work8/Mission83/app/src/main/res/drawable/ic_launcher_background.xml b/Work8/Mission83/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work8/Mission83/app/src/main/res/drawable/ic_launcher_foreground.xml b/Work8/Mission83/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/res/layout/activity_login.xml b/Work8/Mission83/app/src/main/res/layout/activity_login.xml
new file mode 100644
index 0000000..5466ee6
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/layout/activity_login.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work8/Mission83/app/src/main/res/layout/activity_main.xml b/Work8/Mission83/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..86a5d97
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/res/layout/activity_sign_up.xml b/Work8/Mission83/app/src/main/res/layout/activity_sign_up.xml
new file mode 100644
index 0000000..00d8e50
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/layout/activity_sign_up.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work8/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Work8/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Work8/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Work8/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/Work8/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Work8/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Work8/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/Work8/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Work8/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Work8/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/Work8/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Work8/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Work8/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/Work8/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Work8/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Work8/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/Work8/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Work8/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Work8/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/Work8/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Work8/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Work8/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/Work8/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Work8/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Work8/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/Work8/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Work8/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Work8/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/Work8/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Work8/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Work8/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/Work8/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Work8/Mission83/app/src/main/res/values-night/themes.xml b/Work8/Mission83/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..90c96a3
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/res/values/colors.xml b/Work8/Mission83/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..c8524cd
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/res/values/strings.xml b/Work8/Mission83/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..0b8871f
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Mission8
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/res/values/themes.xml b/Work8/Mission83/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..7037a92
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/res/xml/backup_rules.xml b/Work8/Mission83/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/main/res/xml/data_extraction_rules.xml b/Work8/Mission83/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/Work8/Mission83/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work8/Mission83/app/src/test/java/com/example/mission8/ExampleUnitTest.kt b/Work8/Mission83/app/src/test/java/com/example/mission8/ExampleUnitTest.kt
new file mode 100644
index 0000000..71878f6
--- /dev/null
+++ b/Work8/Mission83/app/src/test/java/com/example/mission8/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.mission8
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work8/Mission83/build.gradle.kts b/Work8/Mission83/build.gradle.kts
new file mode 100644
index 0000000..922f551
--- /dev/null
+++ b/Work8/Mission83/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+}
\ No newline at end of file
diff --git a/Work8/Mission83/gradle.properties b/Work8/Mission83/gradle.properties
new file mode 100644
index 0000000..20e2a01
--- /dev/null
+++ b/Work8/Mission83/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Work8/Mission83/gradle/libs.versions.toml b/Work8/Mission83/gradle/libs.versions.toml
new file mode 100644
index 0000000..a16c2b0
--- /dev/null
+++ b/Work8/Mission83/gradle/libs.versions.toml
@@ -0,0 +1,28 @@
+[versions]
+agp = "8.8.0"
+kotlin = "1.9.24"
+coreKtx = "1.16.0"
+junit = "4.13.2"
+junitVersion = "1.2.1"
+espressoCore = "3.6.1"
+appcompat = "1.7.0"
+material = "1.12.0"
+activity = "1.10.1"
+constraintlayout = "2.2.1"
+roomRuntimeAndroid = "2.7.1"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+androidx-room-runtime-android = { group = "androidx.room", name = "room-runtime-android", version.ref = "roomRuntimeAndroid" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+
diff --git a/Work8/Mission83/gradle/wrapper/gradle-wrapper.jar b/Work8/Mission83/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/Work8/Mission83/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Work8/Mission83/gradle/wrapper/gradle-wrapper.properties b/Work8/Mission83/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..40cd2e8
--- /dev/null
+++ b/Work8/Mission83/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri May 23 23:28:55 KST 2025
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Work8/Mission83/gradlew b/Work8/Mission83/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/Work8/Mission83/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Work8/Mission83/gradlew.bat b/Work8/Mission83/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/Work8/Mission83/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Work8/Mission83/settings.gradle.kts b/Work8/Mission83/settings.gradle.kts
new file mode 100644
index 0000000..d31a381
--- /dev/null
+++ b/Work8/Mission83/settings.gradle.kts
@@ -0,0 +1,24 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "Mission8"
+include(":app")
+
\ No newline at end of file
diff --git a/Work9/Mission83/.gitignore b/Work9/Mission83/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/Work9/Mission83/.gitignore
@@ -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
diff --git a/Work9/Mission83/.idea/.gitignore b/Work9/Mission83/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/Work9/Mission83/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/Work9/Mission83/.idea/.name b/Work9/Mission83/.idea/.name
new file mode 100644
index 0000000..68b78bc
--- /dev/null
+++ b/Work9/Mission83/.idea/.name
@@ -0,0 +1 @@
+Mission8
\ No newline at end of file
diff --git a/Work9/Mission83/.idea/compiler.xml b/Work9/Mission83/.idea/compiler.xml
new file mode 100644
index 0000000..b86273d
--- /dev/null
+++ b/Work9/Mission83/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/.idea/deploymentTargetSelector.xml b/Work9/Mission83/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..b268ef3
--- /dev/null
+++ b/Work9/Mission83/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/.idea/gradle.xml b/Work9/Mission83/.idea/gradle.xml
new file mode 100644
index 0000000..7b3006b
--- /dev/null
+++ b/Work9/Mission83/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/.idea/kotlinc.xml b/Work9/Mission83/.idea/kotlinc.xml
new file mode 100644
index 0000000..148fdd2
--- /dev/null
+++ b/Work9/Mission83/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/.idea/migrations.xml b/Work9/Mission83/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/Work9/Mission83/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/.idea/misc.xml b/Work9/Mission83/.idea/misc.xml
new file mode 100644
index 0000000..74dd639
--- /dev/null
+++ b/Work9/Mission83/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/.idea/runConfigurations.xml b/Work9/Mission83/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/Work9/Mission83/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/.gitignore b/Work9/Mission83/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Work9/Mission83/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Work9/Mission83/app/build.gradle.kts b/Work9/Mission83/app/build.gradle.kts
new file mode 100644
index 0000000..d8f115c
--- /dev/null
+++ b/Work9/Mission83/app/build.gradle.kts
@@ -0,0 +1,58 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.mission8"
+ compileSdk = 35
+
+ defaultConfig {
+ applicationId = "com.example.mission8"
+ minSdk = 24
+ targetSdk = 35
+ versionCode = 1
+ versionName = "1.0"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+}
+
+dependencies {
+ implementation("org.jetbrains.kotlin:kotlin-stdlib:2.1.10")
+
+ implementation("com.squareup.retrofit2:retrofit:2.9.0")
+ implementation("com.squareup.retrofit2:converter-gson:2.9.0")
+
+ implementation("com.squareup.okhttp3:okhttp:4.10.0")
+ implementation("com.squareup.okhttp3:logging-interceptor:4.10.0")
+
+ //implementation ("com.squareup.okhttp3:logging-interceptor:4.9.0")
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.activity)
+ implementation(libs.androidx.constraintlayout)
+ implementation(libs.androidx.room.runtime.android)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
\ No newline at end of file
diff --git a/Work9/Mission83/app/proguard-rules.pro b/Work9/Mission83/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Work9/Mission83/app/proguard-rules.pro
@@ -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
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/androidTest/java/com/example/mission8/ExampleInstrumentedTest.kt b/Work9/Mission83/app/src/androidTest/java/com/example/mission8/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..08ec283
--- /dev/null
+++ b/Work9/Mission83/app/src/androidTest/java/com/example/mission8/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.mission8
+
+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.mission8", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/AndroidManifest.xml b/Work9/Mission83/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a5646f6
--- /dev/null
+++ b/Work9/Mission83/app/src/main/AndroidManifest.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/login/LoginActivity.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/login/LoginActivity.kt
new file mode 100644
index 0000000..f5cba60
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/login/LoginActivity.kt
@@ -0,0 +1,103 @@
+package com.example.mission8.login
+
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import android.widget.Button
+import android.widget.EditText
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.example.mission8.R
+import com.example.mission8.model.LoginRequest
+import com.example.mission8.model.LoginResult
+import com.example.mission8.network.NetworkService
+
+/**
+ * LoginActivity: 로그인 화면
+ * - 사용자로부터 email/password 입력을 받아서
+ * NetworkService.login()을 호출 → 결과를 콜백으로 받아 화면에 토스트와 로그로 표시
+ */
+class LoginActivity : AppCompatActivity(), LoginContract.View {
+
+ companion object {
+ private const val TAG = "LoginActivity"
+ }
+
+ // View 바인딩
+ private lateinit var emailEditText: EditText
+ private lateinit var passwordEditText: EditText
+ private lateinit var loginButton: Button
+
+ // NetworkService 객체 (API 호출 담당)
+ private val networkService = NetworkService()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_login)
+
+ // 1) UI 컴포넌트 바인딩
+ emailEditText = findViewById(R.id.etEmail)
+ passwordEditText = findViewById(R.id.etPassword)
+ loginButton = findViewById(R.id.btnLogin)
+
+ // 2) “로그인” 버튼 클릭
+ loginButton.setOnClickListener {
+ val email = emailEditText.text.toString().trim()
+ val password = passwordEditText.text.toString().trim()
+
+ // 필수 입력값 체크
+ if (email.isEmpty() || password.isEmpty()) {
+ Toast.makeText(this, "이메일과 비밀번호를 입력해주세요.", Toast.LENGTH_SHORT).show()
+ Log.d(TAG, "입력값 부족: email='$email', password='$password'")
+ return@setOnClickListener
+ }
+
+ // 3) LoginRequest 객체 생성
+ val request = LoginRequest(
+ email = email,
+ password = password
+ )
+ Log.d(TAG, "로그인 요청: email='$email'")
+
+ // 4) NetworkService.login() 호출 → 콜백 결과: onLoginSuccess / onLoginFailure
+ networkService.login(request, this)
+ }
+ }
+
+ /**
+ * 로그인 성공 시 호출
+ */
+ override fun onLoginSuccess(result: LoginResult) {
+ runOnUiThread {
+ Toast.makeText(
+ this,
+ "로그인 성공! 회원 ID: ${result.memberId}",
+ Toast.LENGTH_LONG
+ ).show()
+ Log.d(TAG, "로그인 성공: memberId=${result.memberId}, accessToken=${result.accessToken}")
+
+ // 예시: accessToken을 SharedPreferences에 저장
+ // val pref = getSharedPreferences("user_pref", MODE_PRIVATE)
+ // pref.edit().putString("accessToken", result.accessToken).apply()
+
+ // 다음 화면(예: MainActivity)으로 이동
+ // val intent = Intent(this, MainActivity::class.java)
+ // startActivity(intent)
+ // finish()
+ }
+ }
+
+ /**
+ * 로그인 실패 시 호출
+ */
+ override fun onLoginFailure(code: String, message: String) {
+ runOnUiThread {
+ Toast.makeText(
+ this,
+ "로그인 실패: [$code] $message",
+ Toast.LENGTH_LONG
+ ).show()
+ Log.d(TAG, "로그인 실패: code=$code, message=$message")
+ }
+ }
+}
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/login/LoginContract.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/login/LoginContract.kt
new file mode 100644
index 0000000..847bb82
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/login/LoginContract.kt
@@ -0,0 +1,23 @@
+package com.example.mission8.login
+
+import com.example.mission8.model.LoginResult
+
+/**
+ * LoginContract: Activity(View)와 Service 사이의 인터페이스 정의
+ */
+interface LoginContract {
+ interface View {
+ /**
+ * 로그인 성공 시 호출
+ * @param result : LoginResult (userId, jwt, nickname 등)
+ */
+ fun onLoginSuccess(result: LoginResult)
+
+ /**
+ * 로그인 실패 시 호출
+ * @param code : 서버 에러 코드 또는 통신 실패 시 키값
+ * @param message : 사용자에게 보여줄 메시지
+ */
+ fun onLoginFailure(code: String, message: String)
+ }
+}
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/model/LoginRequest.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/model/LoginRequest.kt
new file mode 100644
index 0000000..4023b82
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/model/LoginRequest.kt
@@ -0,0 +1,6 @@
+package com.example.mission8.model
+
+data class LoginRequest(
+ val email : String,
+ val password : String
+)
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/model/LoginResponse.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/model/LoginResponse.kt
new file mode 100644
index 0000000..d83e88e
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/model/LoginResponse.kt
@@ -0,0 +1,14 @@
+package com.example.mission8.model
+
+data class LoginResponse(
+ val isSuccess: Boolean,
+ val code: String,
+ val message: String,
+ val result: LoginResult?
+)
+
+data class LoginResult(
+ val memberId: Int,
+ val accessToken: String
+)
+
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/model/SignUpRequest.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/model/SignUpRequest.kt
new file mode 100644
index 0000000..56ef26e
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/model/SignUpRequest.kt
@@ -0,0 +1,7 @@
+package com.example.mission8.model
+
+data class SignUpRequest(
+ var name: String,
+ var email: String,
+ var password: String
+)
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/model/SignupResponse.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/model/SignupResponse.kt
new file mode 100644
index 0000000..293be83
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/model/SignupResponse.kt
@@ -0,0 +1,14 @@
+package com.example.mission8.model
+
+data class SignupResponse (
+ val isSuccess: Boolean,
+ val code : String,
+ val message : String,
+ val result : SuccessResponse?
+)
+
+data class SuccessResponse(
+ val memberId : Int,
+ val createdAt : String,
+ val updateAt : String
+)
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/network/LoginService.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/network/LoginService.kt
new file mode 100644
index 0000000..0555082
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/network/LoginService.kt
@@ -0,0 +1,14 @@
+package com.example.mission8.network
+
+import com.example.mission8.model.LoginRequest
+import com.example.mission8.model.LoginResponse
+import retrofit2.Call
+import retrofit2.http.Body
+import retrofit2.http.POST
+
+interface LoginService {
+ @POST("/login")
+ fun login(
+ @Body request: LoginRequest
+ ): Call
+}
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/network/NetworkManager.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/network/NetworkManager.kt
new file mode 100644
index 0000000..62b2358
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/network/NetworkManager.kt
@@ -0,0 +1,49 @@
+package com.example.mission8.network
+
+import okhttp3.OkHttpClient
+import okhttp3.logging.HttpLoggingInterceptor
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+import java.util.concurrent.TimeUnit
+
+object NetworkManager {
+
+ // 서버의 Base URL을 실제 주소로 변경하세요. 예: "https://api.myserver.com/"
+ private const val BASE_URL = "http://3.35.121.185"
+
+ // (선택) 상세 로그 확인을 위한 로깅 인터셉터
+ private val loggingInterceptor: HttpLoggingInterceptor by lazy {
+ HttpLoggingInterceptor().apply {
+ level = HttpLoggingInterceptor.Level.BODY
+ }
+ }
+
+ // OkHttpClient 설정 (타임아웃, 로깅 등)
+ private val okHttpClient: OkHttpClient by lazy {
+ OkHttpClient.Builder()
+ .addInterceptor(loggingInterceptor)
+ .connectTimeout(15, TimeUnit.SECONDS)
+ .readTimeout(15, TimeUnit.SECONDS)
+ .writeTimeout(15, TimeUnit.SECONDS)
+ .build()
+ }
+
+ // Retrofit 인스턴스
+ private val retrofit: Retrofit by lazy {
+ Retrofit.Builder()
+ .baseUrl(BASE_URL)
+ .client(okHttpClient)
+ .addConverterFactory(GsonConverterFactory.create())
+ .build()
+ }
+
+ // 회원가입 서비스 구현체
+ val signUpService: SignUpService by lazy {
+ retrofit.create(SignUpService::class.java)
+ }
+
+ // 로그인 서비스 구현체
+ val loginService: LoginService by lazy {
+ retrofit.create(LoginService::class.java)
+ }
+}
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/network/NetworkService.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/network/NetworkService.kt
new file mode 100644
index 0000000..bfe6c7b
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/network/NetworkService.kt
@@ -0,0 +1,101 @@
+package com.example.mission8.network
+
+import com.example.mission8.login.LoginContract
+import com.example.mission8.model.LoginRequest
+import com.example.mission8.model.LoginResponse
+import com.example.mission8.model.SignUpRequest
+import com.example.mission8.model.SignUpResponse
+import com.example.mission8.signup.SignUpContract
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+
+/**
+ * NetworkService 클래스:
+ * - Activity(또는 Presenter)에서 호출하여 API 요청을 바로 보낼 수 있도록 래핑한 클래스
+ * - 회원가입(signUp)과 로그인(login)을 각각 처리
+ */
+class NetworkService {
+
+ /**
+ * 회원가입 API 호출
+ * @param request : SignUpRequest (name, email, password)
+ * @param view : SignUpContract.View (결과 콜백을 받을 인터페이스)
+ */
+ fun signUp(request: SignUpRequest, view: SignUpContract.View) {
+ NetworkManager.signUpService.signup(request)
+ .enqueue(object : Callback {
+ override fun onResponse(
+ call: Call,
+ response: Response
+ ) {
+ if (response.isSuccessful) {
+ val body = response.body()
+ if (body != null) {
+ if (body.isSuccess) {
+ // 회원가입 성공
+ view.onSignUpSuccess(body.result!!)
+ } else {
+ // 서버 로직 상 실패 (isSuccess == false)
+ view.onSignUpFailure(body.code, body.message)
+ }
+ } else {
+ // body가 null인 경우
+ view.onSignUpFailure("NULL_BODY", "서버 응답이 비었습니다.")
+ }
+ } else {
+ // HTTP 상태 코드 2xx가 아닌 경우
+ val codeStr = response.code().toString()
+ val msg = response.errorBody()?.string() ?: "알 수 없는 서버 오류"
+ view.onSignUpFailure(codeStr, msg)
+ }
+ }
+
+ override fun onFailure(call: Call, t: Throwable) {
+ // 네트워크 통신 자체가 실패한 경우
+ view.onSignUpFailure("NETWORK_ERROR", t.message ?: "네트워크 오류")
+ }
+ })
+ }
+
+ /**
+ * 로그인 API 호출
+ * @param request : LoginRequest (email, password)
+ * @param view : LoginContract.View (결과 콜백을 받을 인터페이스)
+ */
+ fun login(request: LoginRequest, view: LoginContract.View) {
+ NetworkManager.loginService.login(request)
+ .enqueue(object : Callback {
+ override fun onResponse(
+ call: Call,
+ response: Response
+ ) {
+ if (response.isSuccessful) {
+ val body = response.body()
+ if (body != null) {
+ if (body.isSuccess) {
+ // 로그인 성공
+ view.onLoginSuccess(body.result!!)
+ } else {
+ // 서버 로직 상 실패 (isSuccess == false)
+ view.onLoginFailure(body.code, body.message)
+ }
+ } else {
+ // body가 null인 경우
+ view.onLoginFailure("NULL_BODY", "서버 응답이 비었습니다.")
+ }
+ } else {
+ // HTTP 상태 코드 2xx가 아닌 경우
+ val codeStr = response.code().toString()
+ val msg = response.errorBody()?.string() ?: "알 수 없는 서버 오류"
+ view.onLoginFailure(codeStr, msg)
+ }
+ }
+
+ override fun onFailure(call: Call, t: Throwable) {
+ // 네트워크 통신 자체가 실패한 경우
+ view.onLoginFailure("NETWORK_ERROR", t.message ?: "네트워크 오류")
+ }
+ })
+ }
+}
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/network/SignUpService.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/network/SignUpService.kt
new file mode 100644
index 0000000..3ffd17b
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/network/SignUpService.kt
@@ -0,0 +1,14 @@
+package com.example.mission8.network
+
+import com.example.mission8.model.SignUpRequest
+import com.example.mission8.model.SignupResponse
+import retrofit2.Call
+import retrofit2.http.Body
+import retrofit2.http.POST
+
+interface SignUpService {
+ @POST("/join")
+ fun signup(
+ @Body request: SignUpRequest
+ ): Call
+}
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/signup/SignUpActivity.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/signup/SignUpActivity.kt
new file mode 100644
index 0000000..ea38130
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/signup/SignUpActivity.kt
@@ -0,0 +1,99 @@
+package com.example.mission8.signup
+
+import android.os.Bundle
+import android.util.Log
+import android.widget.Button
+import android.widget.EditText
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.example.mission8.R
+import com.example.mission8.model.SignUpRequest
+import com.example.mission8.model.SuccessResponse
+import com.example.mission8.network.NetworkService
+
+/**
+ * SignUpActivity: 회원가입 화면
+ * - 사용자로부터 name/email/password 입력을 받아서
+ * NetworkService.signUp()을 호출 → 결과를 콜백으로 받아 화면에 토스트와 로그로 표시
+ */
+class SignUpActivity : AppCompatActivity(), SignUpContract.View {
+
+ companion object {
+ private const val TAG = "SignUpActivity"
+ }
+
+ // View 바인딩
+ private lateinit var nameEditText: EditText
+ private lateinit var emailEditText: EditText
+ private lateinit var passwordEditText: EditText
+ private lateinit var signUpButton: Button
+
+ // NetworkService 객체 (API 호출 담당)
+ private val networkService = NetworkService()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_sign_up)
+
+ // 1) UI 컴포넌트 바인딩
+ nameEditText = findViewById(R.id.etName)
+ emailEditText = findViewById(R.id.etEmail)
+ passwordEditText = findViewById(R.id.etPassword)
+ signUpButton = findViewById(R.id.btnSignUp)
+
+ // 2) “회원가입” 버튼 클릭
+ signUpButton.setOnClickListener {
+ val name = nameEditText.text.toString().trim()
+ val email = emailEditText.text.toString().trim()
+ val password = passwordEditText.text.toString().trim()
+
+ // 필수 입력값 체크
+ if (name.isEmpty() || email.isEmpty() || password.isEmpty()) {
+ Toast.makeText(this, "모든 필드를 입력해주세요.", Toast.LENGTH_SHORT).show()
+ Log.d(TAG, "입력값 부족: name='$name', email='$email', password='$password'")
+ return@setOnClickListener
+ }
+
+ // 3) SignUpRequest 객체 생성
+ val request = SignUpRequest(
+ name = name,
+ email = email,
+ password = password
+ )
+ Log.d(TAG, "회원가입 요청: name='$name', email='$email'")
+
+ // 4) NetworkService.signUp() 호출 → 콜백 결과: onSignUpSuccess / onSignUpFailure
+ networkService.signUp(request, this)
+ }
+ }
+
+ /**
+ * 회원가입 성공 시 호출
+ */
+ override fun onSignUpSuccess(result: SuccessResponse) {
+ runOnUiThread {
+ Toast.makeText(
+ this,
+ "회원가입 성공! 회원 ID: ${result.memberId}",
+ Toast.LENGTH_LONG
+ ).show()
+ Log.d(TAG, "회원가입 성공: memberId=${result.memberId}, createdAt=${result.createdAt}, updateAt=${result.updateAt}")
+ // 가입 후 다른 화면으로 이동하거나 finish()를 호출하여 이전 화면으로 돌아갑니다.
+ finish()
+ }
+ }
+
+ /**
+ * 회원가입 실패 시 호출
+ */
+ override fun onSignUpFailure(code: String, message: String) {
+ runOnUiThread {
+ Toast.makeText(
+ this,
+ "회원가입 실패: [$code] $message",
+ Toast.LENGTH_LONG
+ ).show()
+ Log.d(TAG, "회원가입 실패: code=$code, message=$message")
+ }
+ }
+}
diff --git a/Work9/Mission83/app/src/main/java/com/example/mission8/signup/SignUpContract.kt b/Work9/Mission83/app/src/main/java/com/example/mission8/signup/SignUpContract.kt
new file mode 100644
index 0000000..307de52
--- /dev/null
+++ b/Work9/Mission83/app/src/main/java/com/example/mission8/signup/SignUpContract.kt
@@ -0,0 +1,23 @@
+package com.example.mission8.signup
+
+import com.example.mission8.model.SuccessResponse
+
+/**
+ * SignUpContract: Activity(View)와 Service 사이의 인터페이스 정의
+ */
+interface SignUpContract {
+ interface View {
+ /**
+ * 회원가입 성공 시 호출
+ * @param result : SuccessResponse (memberId, createdAt, updateAt)
+ */
+ fun onSignUpSuccess(result: SuccessResponse)
+
+ /**
+ * 회원가입 실패 시 호출
+ * @param code : 서버 에러 코드 또는 통신 실패 시 키값 (ex. "NETWORK_ERROR")
+ * @param message : 사용자에게 보여줄 메시지 (서버에서 내려온 메시지 또는 예외 메시지)
+ */
+ fun onSignUpFailure(code: String, message: String)
+ }
+}
diff --git a/Work9/Mission83/app/src/main/res/drawable/ic_launcher_background.xml b/Work9/Mission83/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work9/Mission83/app/src/main/res/drawable/ic_launcher_foreground.xml b/Work9/Mission83/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/res/layout/activity_login.xml b/Work9/Mission83/app/src/main/res/layout/activity_login.xml
new file mode 100644
index 0000000..af4110b
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/layout/activity_login.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work9/Mission83/app/src/main/res/layout/activity_sign_up.xml b/Work9/Mission83/app/src/main/res/layout/activity_sign_up.xml
new file mode 100644
index 0000000..1392a25
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/layout/activity_sign_up.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Work9/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Work9/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Work9/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Work9/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/Work9/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Work9/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Work9/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/Work9/Mission83/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Work9/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Work9/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/Work9/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Work9/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Work9/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/Work9/Mission83/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Work9/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Work9/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/Work9/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Work9/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Work9/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/Work9/Mission83/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Work9/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Work9/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/Work9/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Work9/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Work9/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/Work9/Mission83/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Work9/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Work9/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/Work9/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Work9/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Work9/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/Work9/Mission83/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Work9/Mission83/app/src/main/res/values-night/themes.xml b/Work9/Mission83/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..90c96a3
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/res/values/colors.xml b/Work9/Mission83/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..c8524cd
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/res/values/strings.xml b/Work9/Mission83/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..d0d6b57
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/values/strings.xml
@@ -0,0 +1,5 @@
+
+ Mission8
+ 회원가입
+ 로그인
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/res/values/themes.xml b/Work9/Mission83/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..7037a92
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/res/xml/backup_rules.xml b/Work9/Mission83/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/main/res/xml/data_extraction_rules.xml b/Work9/Mission83/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/Work9/Mission83/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Work9/Mission83/app/src/test/java/com/example/mission8/ExampleUnitTest.kt b/Work9/Mission83/app/src/test/java/com/example/mission8/ExampleUnitTest.kt
new file mode 100644
index 0000000..71878f6
--- /dev/null
+++ b/Work9/Mission83/app/src/test/java/com/example/mission8/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.mission8
+
+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)
+ }
+}
\ No newline at end of file
diff --git a/Work9/Mission83/build.gradle.kts b/Work9/Mission83/build.gradle.kts
new file mode 100644
index 0000000..922f551
--- /dev/null
+++ b/Work9/Mission83/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+}
\ No newline at end of file
diff --git a/Work9/Mission83/gradle.properties b/Work9/Mission83/gradle.properties
new file mode 100644
index 0000000..20e2a01
--- /dev/null
+++ b/Work9/Mission83/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. For more details, visit
+# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Work9/Mission83/gradle/libs.versions.toml b/Work9/Mission83/gradle/libs.versions.toml
new file mode 100644
index 0000000..a16c2b0
--- /dev/null
+++ b/Work9/Mission83/gradle/libs.versions.toml
@@ -0,0 +1,28 @@
+[versions]
+agp = "8.8.0"
+kotlin = "1.9.24"
+coreKtx = "1.16.0"
+junit = "4.13.2"
+junitVersion = "1.2.1"
+espressoCore = "3.6.1"
+appcompat = "1.7.0"
+material = "1.12.0"
+activity = "1.10.1"
+constraintlayout = "2.2.1"
+roomRuntimeAndroid = "2.7.1"
+
+[libraries]
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+androidx-room-runtime-android = { group = "androidx.room", name = "room-runtime-android", version.ref = "roomRuntimeAndroid" }
+
+[plugins]
+android-application = { id = "com.android.application", version.ref = "agp" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+
diff --git a/Work9/Mission83/gradle/wrapper/gradle-wrapper.jar b/Work9/Mission83/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/Work9/Mission83/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Work9/Mission83/gradle/wrapper/gradle-wrapper.properties b/Work9/Mission83/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..40cd2e8
--- /dev/null
+++ b/Work9/Mission83/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri May 23 23:28:55 KST 2025
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/Work9/Mission83/gradlew b/Work9/Mission83/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/Work9/Mission83/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Work9/Mission83/gradlew.bat b/Work9/Mission83/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/Work9/Mission83/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Work9/Mission83/settings.gradle.kts b/Work9/Mission83/settings.gradle.kts
new file mode 100644
index 0000000..d31a381
--- /dev/null
+++ b/Work9/Mission83/settings.gradle.kts
@@ -0,0 +1,24 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = "Mission8"
+include(":app")
+
\ No newline at end of file