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_오진우_3주차 과제_Step2 #97

Open
wants to merge 22 commits into
base: fivejinw
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
# android-map-search
# 3주차 - android-map-search
## step1 구현할 기능 목록

- [x] 앱 키를 외부에 노출하지 않도록 만드는 기능
- [x] 카카오 API를 통해 데이터를 요청하는 기능
- [x] 받은 데이터를 가공하는 기능
- [x] 데이터를 RecyclerView 형태로 띄워주는 기능

---------------------------
## step2 구현할 기능 목록

- [ ] 카카오 맵 sdk를 통해 카카오 맵을 띄우는 기능
- [ ] 검색창을 선택하면 검색 화면으로 넘어가는 기능
14 changes: 13 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties


plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
Expand All @@ -7,14 +10,20 @@ android {
namespace = "campus.tech.kakao.map"
compileSdk = 34


defaultConfig {
applicationId = "campus.tech.kakao.map"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "1.0"


testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
buildConfigField("String", "KAKAO_LOCAL_API_KEY", gradleLocalProperties(rootDir, providers).getProperty("KAKAO_LOCAL_API_KEY"))
buildConfigField("String", "KAKAO_BASE_URL", gradleLocalProperties(rootDir, providers).getProperty("KAKAO_BASE_URL"))
buildConfigField("String", "KAKAO_NATIVE_APP_KEY", gradleLocalProperties(rootDir, providers).getProperty("KAKAO_NATIVE_APP_KEY"))

}

buildTypes {
Expand All @@ -36,7 +45,9 @@ android {

buildFeatures {
viewBinding = true
buildConfig = true
}

}

dependencies {
Expand All @@ -49,8 +60,9 @@ dependencies {
implementation("androidx.datastore:datastore-preferences:1.0.0")
implementation("com.squareup.retrofit2:retrofit:2.11.0")
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")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}
}
8 changes: 6 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Map"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:name=".view.SearchActivity"
android:exported="false" />
<activity
android:name=".view.MapActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand All @@ -25,4 +29,4 @@
</activity>
</application>

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

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ class PlaceViewAdapter(

class PlaceDiffCallBack : DiffUtil.ItemCallback<Place>() {
override fun areItemsTheSame(oldItem: Place, newItem: Place): Boolean {
Log.d("testt", "areItemsTheSame: ${oldItem === newItem}")
return oldItem === newItem
}

Expand All @@ -60,7 +59,8 @@ class PlaceViewHolder(itemView: View, val listener: OnClickPlaceListener) :
fun bind(place : Place){
currentPlace = place
name.text = place.name
location.text = place.location
category.text = place.category
location.text = place.location ?: ""
Log.d("testt", "입력값 : " + location.text.toString())
category.text = place.category ?: ""
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,10 @@ class SavedPlaceViewAdapter(
}

class SavedPlaceDiffCallBack : DiffUtil.ItemCallback<SavedPlace>() {
// 같은 Item인지
override fun areItemsTheSame(oldItem: SavedPlace, newItem: SavedPlace): Boolean {
return oldItem === newItem
}

// 같은 내용물을 가지고 있는지. 여기서는 name
override fun areContentsTheSame(oldItem: SavedPlace, newItem: SavedPlace): Boolean {
return oldItem.name == newItem.name
}
Expand Down
14 changes: 10 additions & 4 deletions app/src/main/java/campus/tech/kakao/map/model/Place.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package campus.tech.kakao.map.model

import com.google.gson.annotations.SerializedName

data class ResultSearch(
val documents: List<Place>
)

data class Place(
val name : String,
val location : String,
val category : String
)
@SerializedName("place_name") val name : String,
@SerializedName("road_address_name") val location : String?,
@SerializedName("category_group_name") val category : String?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package campus.tech.kakao.map.repository

import android.util.Log
import campus.tech.kakao.map.BuildConfig
import campus.tech.kakao.map.model.Place
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.create

class KakaoApiDataSource {
object KakaoRetrofitInstance {

val kakaoLocalApi : KakaoLocalApi = getApiClient().create()

private fun getApiClient(): Retrofit {
return Retrofit.Builder()
.baseUrl(BuildConfig.KAKAO_BASE_URL)
.client(provideOkHttpClient(AppInterceptor()))
.addConverterFactory(GsonConverterFactory.create())
.build()
}

private fun provideOkHttpClient(interceptor: AppInterceptor): OkHttpClient
= OkHttpClient.Builder().run {
addInterceptor(interceptor)
build()
}

class AppInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain) : okhttp3.Response = with(chain) {
val newRequest = request().newBuilder()
.addHeader("Authorization", BuildConfig.KAKAO_LOCAL_API_KEY)
.build()
proceed(newRequest)
}
}
}

suspend fun getPlaceData(text: String) : List<Place> {
val emptyList = listOf<Place>()
val kakaoApi = KakaoRetrofitInstance.kakaoLocalApi
return try{
val placeList = kakaoApi.getPlaceData(text)
Log.d("coroutineTest", "return")
placeList.documents ?: emptyList
} catch (e : Exception){
Log.d("coroutineTest", e.toString())
emptyList
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package campus.tech.kakao.map.repository

import campus.tech.kakao.map.model.ResultSearch
import retrofit2.Call
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Query

interface KakaoLocalApi {
@GET("v2/local/search/keyword.json")
suspend fun getPlaceData(
@Query("query") query: String
): ResultSearch

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import campus.tech.kakao.map.db.PlaceDBHelper
import campus.tech.kakao.map.model.Place

class PlaceRepository (val dbHelper: PlaceDBHelper){
val kakaoApiDataSource = KakaoApiDataSource()
fun getAllPlace() : List<Place>{
val cursor = dbHelper.readPlaceData()
val placeList = mutableListOf<Place>()
Expand All @@ -31,7 +32,10 @@ class PlaceRepository (val dbHelper: PlaceDBHelper){
}

fun writePlace(place: Place){
dbHelper.insertPlaceData(place.name, place.location, place.category)
val name = place.name
val location = place.location ?: ""
val category = place.category ?: ""
dbHelper.insertPlaceData(name, location, category)
}

fun getPlaceWithCategory(category : String): List<Place>{
Expand All @@ -58,4 +62,9 @@ class PlaceRepository (val dbHelper: PlaceDBHelper){
cursor.close()
return placeList
}

suspend fun getKakaoLocalPlaceData(text : String) : List<Place>{
val placeList = kakaoApiDataSource.getPlaceData(text)
return placeList
}
}
82 changes: 82 additions & 0 deletions app/src/main/java/campus/tech/kakao/map/view/MapActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package campus.tech.kakao.map.view

import android.app.ActivityOptions
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import campus.tech.kakao.map.BuildConfig
import campus.tech.kakao.map.R
import com.kakao.vectormap.KakaoMap
import com.kakao.vectormap.KakaoMapReadyCallback
import com.kakao.vectormap.KakaoMapSdk
import com.kakao.vectormap.MapLifeCycleCallback
import com.kakao.vectormap.MapView


class MapActivity : AppCompatActivity() {

lateinit var map : MapView
lateinit var inputField : EditText
lateinit var searchIcon : ImageView

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_map)

initVar()
initSDK()
initMapView()
initClickListener()
}

private fun initVar(){
inputField = findViewById<EditText>(R.id.input_search_field)
searchIcon = findViewById<ImageView>(R.id.search_icon)
bringFrontSearchField()
}

private fun initSDK(){
KakaoMapSdk.init(this, BuildConfig.KAKAO_NATIVE_APP_KEY)
}

private fun initMapView(){
map = findViewById<MapView>(R.id.map_view)
map.start(object : MapLifeCycleCallback() {
override fun onMapDestroy() {
Log.d("testt", "MapDestroy")
}

override fun onMapError(error: Exception) {
Log.d("testt", error.toString())
}
}, object : KakaoMapReadyCallback() {
override fun onMapReady(kakaoMap: KakaoMap) {
Log.d("testt", "MapReady")
}
})

}

private fun bringFrontSearchField(){
inputField.bringToFront()
searchIcon.bringToFront()
}

private fun initClickListener(){
inputField.setOnClickListener{
moveSearchPage(it)
}
}

private fun moveSearchPage(view : View){
val intent = Intent(this, SearchActivity::class.java)
val options = ActivityOptions.makeSceneTransitionAnimation(
this, view, "inputFieldTransition")
startActivity(intent, options.toBundle())
}
}
Loading