Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

부산대 Android_김현민 6주차 과제 Step1 #17

Merged
merged 92 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
04c907f
Initial commit
MyStoryG Jun 15, 2024
8b097b3
Initial commit
MyStoryG Jun 15, 2024
6b8ac02
Docs: Update README.md
khyeonm Jul 1, 2024
cacee4b
Feat: Complete search screen layout
khyeonm Jul 1, 2024
cb73f1e
Feat: Add data to the database
khyeonm Jul 1, 2024
6bd8cf7
Docs: Update README.md
khyeonm Jul 3, 2024
0fc0da3
Feat: Create item_view
khyeonm Jul 4, 2024
f94b9b8
Feat: Modify main view
khyeonm Jul 4, 2024
a400cbd
Feat: Implement search list
khyeonm Jul 4, 2024
60e50ab
Feat: Complete saved element view
khyeonm Jul 4, 2024
36ad032
Feat: Complete save action
khyeonm Jul 4, 2024
0644db3
Feat: Add persistent save function
khyeonm Jul 4, 2024
de2036d
부산대 Android_김현민_2주차_과제_Step1 (#2)
khyeonm Jul 5, 2024
8dcc8a7
Design: Modify save element design
khyeonm Jul 5, 2024
3959c94
Update README.md
khyeonm Jul 5, 2024
c03af09
Merge branch 'khyeonm' into step2
khyeonm Jul 6, 2024
bbf77e9
Initial commit
MyStoryG Jul 7, 2024
e708df9
Fix: Fix error
khyeonm Jul 8, 2024
39de52b
Merge branch 'step2-from-keyword' into step0
khyeonm Jul 8, 2024
1c5d9c2
Fix: Fix Week2 error
khyeonm Jul 9, 2024
a68d784
Docs: Update README.md
khyeonm Jul 9, 2024
2f45b6c
Feat: Add initial settings
khyeonm Jul 9, 2024
e3818d0
Feat: Add Document data class
khyeonm Jul 9, 2024
3521161
Feat: Add RetrofitService interface
khyeonm Jul 9, 2024
ab8d218
Refactor: Delete DB code
khyeonm Jul 9, 2024
7b38ee9
Feat: Add search function using API
khyeonm Jul 9, 2024
10c77c6
Feat: Separate CategoryGroupCode
khyeonm Jul 9, 2024
8d65dd3
Docs: Update step2 README.md
khyeonm Jul 11, 2024
9e07bf4
Feat: complete initial project setup
khyeonm Jul 11, 2024
8702f3b
Feat: Add mapview and map function
khyeonm Jul 11, 2024
b3231a9
Fix: resolve errors
khyeonm Jul 11, 2024
113daff
Chore: Update network security configuration
khyeonm Jul 11, 2024
b954413
Fix: Resolve windows emulator issue
khyeonm Jul 11, 2024
0f3c880
Style: Update mapview design
khyeonm Jul 11, 2024
9652c65
부산대 Android_김현민 3주차 과제 Step0 (#19)
khyeonm Jul 14, 2024
9238189
Fix: Reflect feedback
khyeonm Jul 15, 2024
918d3fd
Fix: Resolve error
khyeonm Jul 15, 2024
f87982e
Merge branch 'khyeonm' into step2-1
khyeonm Jul 15, 2024
ce0ab32
Merge branch 'step2-1-from-search' into step0
khyeonm Jul 15, 2024
f6cb344
부산대 Android_김현민 4주차 과제 Step0 (#16)
khyeonm Jul 15, 2024
767bc4a
Docs: Update README.md
khyeonm Jul 16, 2024
dac7bca
Feat: Add location marker
khyeonm Jul 16, 2024
afa34b0
Feat: Add camera movement function
khyeonm Jul 16, 2024
d88c1a5
Feat: Add bottom sheet dialog
khyeonm Jul 16, 2024
13d7133
Feat: Add initial camera location function
khyeonm Jul 16, 2024
97ee6d1
Refactor: Resolve initial camera issue and search issue
khyeonm Jul 16, 2024
dd9b3a1
Feat: Add map error event
khyeonm Jul 16, 2024
b44783b
Design: Modify UI design
khyeonm Jul 16, 2024
f14be70
Refactor: Separate function and write annotations
khyeonm Jul 16, 2024
1d481b2
Docs: Update README.md
khyeonm Jul 16, 2024
cec88cf
Feat: Add save item click function
khyeonm Jul 16, 2024
02b9df4
Feat: Add keyword search function
khyeonm Jul 16, 2024
08879d8
Refactor: Reflect step1 feedback
khyeonm Jul 17, 2024
305453d
Initial commit
MyStoryG Jul 18, 2024
53769af
Feat: Add dependencies
khyeonm Jul 19, 2024
bf7f411
Test: Add map activity ui test
khyeonm Jul 19, 2024
4aceb24
Test: Add main activity ui test
khyeonm Jul 19, 2024
634700d
Test: Add main activity unit test
khyeonm Jul 19, 2024
eea98eb
Test: Add map activity unit test
khyeonm Jul 19, 2024
202da6c
부산대 Android_김현민 4주차 과제 Step1 (#33)
khyeonm Jul 21, 2024
ec78710
Fix: Fix conflict error
khyeonm Jul 22, 2024
cac1aaa
Merge branch 'khyeonm' into step2-1
khyeonm Jul 22, 2024
3b8c2ca
Merge branch 'step2-from-location' into step0
khyeonm Jul 22, 2024
3ca355a
Chore: Add dependency and grouping
khyeonm Jul 22, 2024
05d33a7
부산대 Android_김현민 5주차 과제 Step0 (#6)
khyeonm Jul 22, 2024
bd0c9ba
Chore: Edit grouping
khyeonm Jul 22, 2024
fff84fb
Refactor: Change database to Room
khyeonm Jul 22, 2024
ba997ca
Fix: Resolve data integrity error
khyeonm Jul 22, 2024
55d7ed5
Refactor: Apply dependency injection
khyeonm Jul 22, 2024
9cf280f
Refactor: Apply dependency injection
khyeonm Jul 22, 2024
5b541c7
Refactor: Apply dependency injection
khyeonm Jul 23, 2024
712d413
Chore: Edit grouping
khyeonm Jul 23, 2024
8e28f65
Refactor: Apply dependency injection
khyeonm Jul 23, 2024
f79cab4
Refactor: Apply dependency injection
khyeonm Jul 23, 2024
59c928d
Fix: Remove test code error
khyeonm Jul 23, 2024
5aaa878
Refactor: Reflect step1 feedback
khyeonm Jul 23, 2024
348dcb9
Chore: Add initial settings
khyeonm Jul 23, 2024
dc1329a
Refactor: Apply databinding in MainActivity
khyeonm Jul 24, 2024
da573e2
Refactor: Apply MVVM in error activity
khyeonm Jul 24, 2024
5d71bef
부산대 Android_김현민 5주차 과제 Step1 (#25)
khyeonm Jul 24, 2024
9bdaa2f
Refactor: Change asynchronous to coroutine
khyeonm Jul 24, 2024
6ce455d
Refactor: Apply MVVM in map activity
khyeonm Jul 25, 2024
592cdc5
Chore: Modify error activity code
khyeonm Jul 25, 2024
9141ee4
Refactor: Apply MVVM in main activity
khyeonm Jul 26, 2024
261f6a3
Merge branch 'khyeonm' into step2
khyeonm Jul 26, 2024
a8910a9
Merge branch 'step2-from-refactoring' into step0
khyeonm Jul 29, 2024
c2115ed
Chore: Prepare step0
khyeonm Jul 29, 2024
2b423ce
Docs: Update README.md
khyeonm Jul 29, 2024
0f87216
Feat: Add splash screen
khyeonm Jul 29, 2024
618db5c
Refactor: Apply MVVM in splash activity
khyeonm Jul 29, 2024
de13d90
Refactor: Reflect week5 feedback
khyeonm Jul 29, 2024
890bf2b
Merge branch 'khyeonm' into step1
khyeonm Jul 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,20 @@
# android-map-notification
# 맵 위치 검색 안드로이드 앱
- 카테캠 Step2 Week6
- 장소 검색 및 장소 저장이 가능한 안드로이드 앱

## 기능
**1. 초기 진입 화면 추가**
- firebase의 Remote Config 설정
- serviceState 값이 ON_SERVICE 일 때
- 지도 화면으로 진입
- serviceState 값이 ON_SERVICE가 아닐 때
- serviceMessage를 초기 진입 화면 하단에 표시
- 지도 화면으로 진입하지 않음


## 실행
- SplashActivity.kt 에서 시작

## 환경
- Kotlin
- Android Studio
3 changes: 2 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,11 @@ dependencies {
implementation("com.squareup.retrofit2:converter-gson:2.11.0")
implementation("com.kakao.maps.open:android:2.9.5")
implementation("androidx.activity:activity:1.8.0")
implementation("com.kakao.sdk:v2-all:2.20.3")
// implementation("com.kakao.sdk:v2-all:2.20.3")
implementation("com.google.dagger:hilt-android:2.48.1")
implementation(platform("com.google.firebase:firebase-bom:33.1.2"))
implementation("com.google.firebase:firebase-analytics-ktx")
implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-config-ktx:22.0.0")
implementation("com.google.firebase:firebase-messaging-ktx:24.0.0")
kapt("com.google.dagger:hilt-compiler:2.48.1")
Expand Down
21 changes: 12 additions & 9 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:name=".utility.MapApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
Expand All @@ -19,31 +19,34 @@
android:theme="@style/Theme.Map"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".ui.MapActivity"
android:exported="false" />

<meta-data
android:name="com.kakao.vectormap.APP_KEY"
android:value="${KAKAO_API_KEY}"/>
android:value="${KAKAO_API_KEY}" />

<activity
android:name=".ui.ErrorActivity"
android:exported="false" />

<meta-data
android:name="com.kakao.vectormap.APP_KEY"
android:value="${KAKAO_API_KEY}"/>
android:value="${KAKAO_API_KEY}" />

<activity
android:name=".ui.MapActivity"
android:exported="true" >
android:name=".ui.SplashActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".ui.MainActivity"
android:exported="false">
</activity>
android:exported="false"></activity>
</application>

</manifest>
</manifest>
11 changes: 0 additions & 11 deletions app/src/main/java/campus/tech/kakao/map/MainActivity.kt

This file was deleted.

22 changes: 0 additions & 22 deletions app/src/main/java/campus/tech/kakao/map/data/KakaoResponse.kt

This file was deleted.

9 changes: 0 additions & 9 deletions app/src/main/java/campus/tech/kakao/map/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ import javax.inject.Inject
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

@Inject
lateinit var db: AppDatabase

@Inject
lateinit var searchSave: SaveHelper

Expand All @@ -49,12 +46,6 @@ class MainActivity : AppCompatActivity() {
} else {
adapter.updateProfiles(profiles)
mainBinding.tvNoResult.visibility = View.GONE

lifecycleScope.launch {
withContext(Dispatchers.IO) {
db.profileDao().insertAll(*profiles.toTypedArray())
}
}
}
})

Expand Down
12 changes: 11 additions & 1 deletion app/src/main/java/campus/tech/kakao/map/ui/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package campus.tech.kakao.map.ui

import android.widget.Toast
import androidx.lifecycle.*
import campus.tech.kakao.map.data.AppDatabase
import campus.tech.kakao.map.data.Profile
import campus.tech.kakao.map.network.Document
import campus.tech.kakao.map.network.KakaoResponse
Expand All @@ -14,7 +15,10 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

@HiltViewModel
class MainViewModel @Inject constructor(private val searchService: SearchService) : ViewModel() {
class MainViewModel @Inject constructor(
private val searchService: SearchService,
private val db: AppDatabase // Inject the database here
) : ViewModel() {

private val _profiles = MutableLiveData<List<Profile>>()
val profiles: LiveData<List<Profile>> get() = _profiles
Expand Down Expand Up @@ -52,6 +56,12 @@ class MainViewModel @Inject constructor(private val searchService: SearchService
} else {
val profilesList = documents.map { it.toProfile() }
_profiles.value = profilesList

viewModelScope.launch {
withContext(Dispatchers.IO) {
db.profileDao().insertAll(*profilesList.toTypedArray())
}
}
Comment on lines +60 to +64

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

profileDao의 insertAll도 suspend function으로 선언되어 있죠?
그렇다면, withContext로 Dispatcher를 전환해주지 않아도 괜찮습니다. Room 내부에서 비동기로 처리되게 해주기 때문이죠. 혹여나 필요하다면 viewModelScope.launch(Dispatchers.IO) 이렇게 넣어주면 withContext 단계를 생략할 수 있을듯 합니다

}
} ?: run {
_noResult.value = true
Expand Down
38 changes: 38 additions & 0 deletions app/src/main/java/campus/tech/kakao/map/ui/SplashActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package campus.tech.kakao.map.ui

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import campus.tech.kakao.map.R
import campus.tech.kakao.map.databinding.ActivitySplashBinding

class SplashActivity : AppCompatActivity() {

private val splashViewModel: SplashViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivitySplashBinding = DataBindingUtil.setContentView(this, R.layout.activity_splash)
binding.lifecycleOwner = this
binding.viewModel = splashViewModel

splashViewModel.serviceState.observe(this, Observer { state ->
if (state == "ON_SERVICE") {
startActivity(Intent(this, MapActivity::class.java))
finish()
} else {
binding.tvServiceMessage.visibility = TextView.VISIBLE
}
})

splashViewModel.serviceMessage.observe(this, Observer { message ->
Log.d("SplashActivity", "serviceMessage: $message")
})
}
}
38 changes: 38 additions & 0 deletions app/src/main/java/campus/tech/kakao/map/ui/SplashViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package campus.tech.kakao.map.ui

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.remoteConfigSettings

class SplashViewModel(application: Application) : AndroidViewModel(application) {

Comment on lines +9 to +11

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hilt를 통해 의존성 주입을 받고자 한다면, @HiltViewModel 어노테이션을 붙여줘야 할것 같습니다.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SplashActivity 에도 @AndroidEntryPoint 어노테이션을 붙여줘야 할것 같네요

private val _serviceState = MutableLiveData<String>()
val serviceState: LiveData<String> = _serviceState

private val _serviceMessage = MutableLiveData<String>()
val serviceMessage: LiveData<String> = _serviceMessage

init {
remoteConfigValues()
}

private fun remoteConfigValues() {
val remoteConfig: FirebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
val configSettings = remoteConfigSettings {
minimumFetchIntervalInSeconds = 0
}
remoteConfig.setConfigSettingsAsync(configSettings)

remoteConfig.fetchAndActivate().addOnCompleteListener { task ->
if (task.isSuccessful) {
_serviceState.value = remoteConfig.getString("serviceState")
_serviceMessage.value = remoteConfig.getString("serviceMessage")
} else {
_serviceMessage.value = "Failed to fetch remote config values"
}
}
}
Comment on lines +18 to +37

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RemoteConfig로 데이터를 조회하고, LiveData를 통해 Activity에 전달해주는 코드는 훌륭하게 작성하셨습니다.

조금 개선하면 좋을 부분이요. RemoteConfig 또한 원격 저장소에서 데이터를 조회하는 동작이라 network 및 data layer (model) 쪽에 속한다고 볼 수 있습니다. 따라서 repository혹은 remote 와 관련된 클래스를 만들고, 그 클래스에서 리모트컨피그 값을 조회하도록 하는것이 조금더 좋을것 같습니다! 그 클래스는 hilt module에 선언한 후 SplashViewModel의 생성자를 통해 주입받는거죠

}
Binary file added app/src/main/res/drawable/map.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions app/src/main/res/layout/activity_splash.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>
<variable
name="viewModel"
type="campus.tech.kakao.map.ui.SplashViewModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.SplashActivity">

<ImageView
android:id="@+id/ivInitialIcon"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/map"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

<TextView
android:id="@+id/tvServiceMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.serviceMessage}"
app:layout_constraintTop_toBottomOf="@+id/ivInitialIcon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:visibility="gone"/>

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>