diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c00d3bd..7a99082 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,3 +1,5 @@ +import java.util.Properties + //plugins { // alias(libs.plugins.android.application) // alias(libs.plugins.jetbrains.kotlin.android) @@ -148,11 +150,16 @@ android { targetSdk = 34 versionCode = 1 versionName = "1.0" - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } + val properties = Properties() + properties.load(project.rootProject.file("local.properties").inputStream()) + buildConfigField("String", "KAKAO_NATIVE_API", "\"${properties.getProperty("KAKAO_NATIVE_API")}\"") + buildConfigField("String", "KAKAO_REST_API", "\"${properties.getProperty("KAKAO_REST_API")}\"") + buildConfigField("String", "KAKAO_ADMIN_API", "\"${properties.getProperty("KAKAO_ADMIN_API")}\"") + manifestPlaceholders.put("KAKAO_NATIVE_API", properties.getProperty("KAKAO_NATIVE_API")) } buildTypes { @@ -174,6 +181,7 @@ android { buildFeatures { compose = true viewBinding = true + buildConfig = true } composeOptions { kotlinCompilerExtensionVersion = "1.5.1" @@ -260,4 +268,9 @@ dependencies { implementation("androidx.room:room-ktx:2.6.1") implementation("me.relex:circleindicator:2.1.6") + + implementation("com.kakao.sdk:v2-user:2.23.0") + implementation("com.kakao.sdk:v2-share:2.23.0") + implementation("com.kakao.sdk:v2-cert:2.23.0") + implementation("com.kakao.sdk:v2-auth:2.13.0") } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 00b2774..cb10857 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,7 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/umc_9th/GlobalApplication.kt b/app/src/main/java/com/example/umc_9th/GlobalApplication.kt new file mode 100644 index 0000000..bc43596 --- /dev/null +++ b/app/src/main/java/com/example/umc_9th/GlobalApplication.kt @@ -0,0 +1,13 @@ +package com.example.umc_9th + +import android.app.Application +import com.kakao.sdk.common.KakaoSdk +import umc.study.umc_9th.BuildConfig + +class GlobalApplication : Application() { + override fun onCreate() { + super.onCreate() + + KakaoSdk.init(this, BuildConfig.KAKAO_NATIVE_API) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/umc_9th/LoginActivity.kt b/app/src/main/java/com/example/umc_9th/LoginActivity.kt index 4e2b10f..5ada8a9 100644 --- a/app/src/main/java/com/example/umc_9th/LoginActivity.kt +++ b/app/src/main/java/com/example/umc_9th/LoginActivity.kt @@ -1,6 +1,7 @@ package com.example.umc_9th import android.content.Intent +import android.graphics.BitmapFactory import android.os.Bundle import android.text.InputType import android.util.Log @@ -15,9 +16,14 @@ import com.google.firebase.database.DatabaseError import com.google.firebase.database.FirebaseDatabase import com.google.firebase.database.ValueEventListener import com.google.firebase.database.getValue +import com.kakao.sdk.auth.model.OAuthToken +import com.kakao.sdk.common.model.ClientError +import com.kakao.sdk.common.model.ClientErrorCause +import com.kakao.sdk.user.UserApiClient import umc.study.umc_9th.R import umc.study.umc_9th.databinding.ActivityLoginBinding import umc.study.umc_9th.databinding.ActivitySignUpBinding +import java.net.URL import kotlin.getValue class LoginActivity : AppCompatActivity() { @@ -33,6 +39,8 @@ class LoginActivity : AppCompatActivity() { super.onCreate(savedInstanceState) binding = ActivityLoginBinding.inflate(layoutInflater) setContentView(binding.root) + val keyHash = com.kakao.sdk.common.util.Utility.getKeyHash(this) + Log.d("KeyHash", keyHash) observeLogin() observeJWT() binding.loginButton.setOnClickListener { @@ -54,6 +62,53 @@ class LoginActivity : AppCompatActivity() { binding.gotoSignup.setOnClickListener { startActivity(Intent(this, SignUpActivity::class.java)) } + binding.kakaoLogin.setOnClickListener { + // 로그인 조합 예제 + +// 카카오계정으로 로그인 공통 callback 구성 +// 카카오톡으로 로그인 할 수 없어 카카오계정으로 로그인할 경우 사용됨 + val callback: (OAuthToken?, Throwable?) -> Unit = { token, error -> + if (error != null) { + Log.e("TAG", "카카오계정으로 로그인 실패", error) + } else if (token != null) { + Log.i("TAG", "카카오계정으로 로그인 성공 ${token.accessToken}") + } + } + +// 카카오톡이 설치되어 있으면 카카오톡으로 로그인, 아니면 카카오계정으로 로그인 + if (UserApiClient.instance.isKakaoTalkLoginAvailable(this)) { + UserApiClient.instance.loginWithKakaoTalk(this) { token, error -> + if (error != null) { + Log.e("TAG", "카카오톡으로 로그인 실패", error) + + // 사용자가 카카오톡 설치 후 디바이스 권한 요청 화면에서 로그인을 취소한 경우, + // 의도적인 로그인 취소로 보고 카카오계정으로 로그인 시도 없이 로그인 취소로 처리 (예: 뒤로 가기) + if (error is ClientError && error.reason == ClientErrorCause.Cancelled) { + return@loginWithKakaoTalk + } + + // 카카오톡에 연결된 카카오계정이 없는 경우, 카카오계정으로 로그인 시도 + UserApiClient.instance.loginWithKakaoAccount(this, callback = callback) + } else if (token != null) { + Log.i("TAG", "카카오톡으로 로그인 성공 ${token.accessToken}") + updateKakaoData() + + } + } + } else { + UserApiClient.instance.loginWithKakaoAccount(this, callback = callback) + } + } + binding.naverLogin.setOnClickListener { + UserApiClient.instance.logout { error -> + if (error != null) { + Log.e("TAG", "로그아웃 실패. SDK에서 토큰 폐기됨", error) + } + else { + Log.i("TAG", "로그아웃 성공. SDK에서 토큰 폐기됨") + } + } + } } private fun observeLogin() { authViewModel.loginResult.observe(this) { result -> @@ -83,6 +138,29 @@ class LoginActivity : AppCompatActivity() { } } } + private fun updateKakaoData() { + // 사용자 정보 요청 (기본) + UserApiClient.instance.me { user, error -> + if (error != null) { + Log.e("TAG", "사용자 정보 요청 실패", error) + } + else if (user != null) { + Log.i("TAG", "사용자 정보 요청 성공" + + "\n회원번호: ${user.id}" + + "\n닉네임: ${user.kakaoAccount?.profile?.nickname}" + + "\n프로필사진: ${user.kakaoAccount?.profile?.thumbnailImageUrl}") + Thread { + val url = URL(user.kakaoAccount?.profile?.thumbnailImageUrl) + val bitmap = BitmapFactory.decodeStream(url.openStream()) + + runOnUiThread { + binding.kakaoImg.setImageBitmap(bitmap) + } + }.start() + binding.nickname.text = user.kakaoAccount?.profile?.nickname + " " + user.id + } + } + } fun Login(id : String, pw : String) { diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 3a3ea7a..805c2b3 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -136,12 +136,12 @@ android:layout_height="50dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" - app:layout_constraintStart_toEndOf="@+id/imageView16" + app:layout_constraintStart_toEndOf="@+id/kakaoLogin" app:layout_constraintTop_toBottomOf="@+id/button3" app:srcCompat="@drawable/apple_44" /> + + + + \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 7736c99..47358fb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,6 +16,7 @@ dependencyResolutionManagement { repositories { google() mavenCentral() + maven { url = java.net.URI("https://devrepo.kakao.com/nexus/content/groups/public/") } } }