From d4796257b3f7ceff7043835444bd9b14ceb8b112 Mon Sep 17 00:00:00 2001 From: klaus Date: Mon, 7 Apr 2025 19:20:57 +0900 Subject: [PATCH] =?UTF-8?q?=EC=B9=B4=EC=B9=B4=EC=98=A4=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 13 +++- app/proguard-rules.pro | 8 +++ app/src/main/AndroidManifest.xml | 14 +++++ .../co/vividnext/sodalive/app/SodaLiveApp.kt | 3 + .../kr/co/vividnext/sodalive/user/UserApi.kt | 7 +++ .../vividnext/sodalive/user/UserRepository.kt | 8 +++ .../sodalive/user/login/LoginActivity.kt | 61 +++++++++++++++++++ .../sodalive/user/login/LoginViewModel.kt | 39 ++++++++++++ app/src/main/res/layout/activity_login.xml | 8 +++ settings.gradle | 1 + 10 files changed, 160 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 14c687c..9125f2c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -52,12 +52,14 @@ android { buildConfigField 'String', 'NOTIFLY_PROJECT_ID', '"765102ec85855aa680da35f1b0f55712"' buildConfigField 'String', 'NOTIFLY_USERNAME', '"voiceon"' buildConfigField 'String', 'NOTIFLY_PASSWORD', '"c6c585db0aaa4189be44d0467c7d66b6@A"' + buildConfigField 'String', 'KAKAO_APP_KEY', '"231cf78acfa8252fca38b9eedf87c5cb"' buildConfigField 'String', 'GOOGLE_CLIENT_ID', '"983594297130-5hrmkh6vpskeq6v34350kmilf74574h2.apps.googleusercontent.com"' manifestPlaceholders = [ URISCHEME : "voiceon", APPLINK_HOST : "voiceon.onelink.me", FACEBOOK_APP_ID : "612448298237287", - FACEBOOK_CLIENT_TOKEN: "32af760f4a7b7cb7e3b1e7ffd0b0da70" + FACEBOOK_CLIENT_TOKEN: "32af760f4a7b7cb7e3b1e7ffd0b0da70", + KAKAO_APP_KEY: "231cf78acfa8252fca38b9eedf87c5cb" ] } @@ -75,12 +77,14 @@ android { buildConfigField 'String', 'NOTIFLY_PROJECT_ID', '"5f7ebe90d1ce5f0392164b8a53a662bc"' buildConfigField 'String', 'NOTIFLY_USERNAME', '"voiceon"' buildConfigField 'String', 'NOTIFLY_PASSWORD', '"c6c585db0aaa4189be44d0467c7d66b6@A"' + buildConfigField 'String', 'KAKAO_APP_KEY', '"20cf19413d63bfdfd30e8e6dff933d33"' buildConfigField 'String', 'GOOGLE_CLIENT_ID', '"758414412471-mosodbj2chno7l1j0iihldh6edmk0gk9.apps.googleusercontent.com"' manifestPlaceholders = [ URISCHEME : "voiceon-test", APPLINK_HOST : "voiceon-test.onelink.me", FACEBOOK_APP_ID : "608674328645232", - FACEBOOK_CLIENT_TOKEN: "3775e6ea83236a685d264b6c5a1bbb4d" + FACEBOOK_CLIENT_TOKEN: "3775e6ea83236a685d264b6c5a1bbb4d", + KAKAO_APP_KEY: "20cf19413d63bfdfd30e8e6dff933d33" ] } } @@ -197,4 +201,9 @@ dependencies { // 노티플라이 implementation 'com.github.team-michael:notifly-android-sdk:1.12.0' + + // Kakao + implementation "com.kakao.sdk:v2-common:2.21.0" + implementation "com.kakao.sdk:v2-auth:2.21.0" + implementation "com.kakao.sdk:v2-user:2.21.0" } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index ad1db1a..ea3a468 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -229,3 +229,11 @@ # @Keep 애노테이션이 붙은 클래스, 메서드, 필드를 보호 -keep @androidx.annotation.Keep class * { *; } + +-keep class com.kakao.sdk.**.model.* { ; } +-keep class * extends com.google.gson.TypeAdapter + +# https://github.com/square/okhttp/pull/6792 +-dontwarn org.bouncycastle.jsse.** +-dontwarn org.conscrypt.* +-dontwarn org.openjsse.** diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6720e17..daad0b6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -198,6 +198,20 @@ android:name="com.google.android.gms.oss.licenses.OssLicensesActivity" android:theme="@style/Theme.AppCompat.DayNight" /> + + + + + + + + + + + > + + @POST("/member/login/kakao") + fun loginKakao( + @Body request: SocialLoginRequest, + @Header("Authorization") authHeader: String + ): Single> + } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/user/UserRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/user/UserRepository.kt index b0caa46..2ae20ee 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/user/UserRepository.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/user/UserRepository.kt @@ -133,4 +133,12 @@ class UserRepository(private val userApi: UserApi) { request = request, authHeader = token ) + + fun kakaoLogin( + request: SocialLoginRequest, + token: String + ) = userApi.loginKakao( + request = request, + authHeader = token + ) } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/user/login/LoginActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/user/login/LoginActivity.kt index a9ce6e3..52de3d7 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/user/login/LoginActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/user/login/LoginActivity.kt @@ -25,6 +25,10 @@ import com.google.android.libraries.identity.googleid.GetGoogleIdOption import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential.Companion.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL import com.jakewharton.rxbinding4.widget.textChanges +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 com.orhanobut.logger.Logger import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.schedulers.Schedulers @@ -147,6 +151,8 @@ class LoginActivity : BaseActivity(ActivityLoginBinding::i } } } + + binding.ivLoginKakao.setOnClickListener { loginKakao() } } private fun handleSignIn(credential: Credential) { @@ -255,4 +261,59 @@ class LoginActivity : BaseActivity(ActivityLoginBinding::i ) }, 100) } + + private val kakaoLoginCallback: (OAuthToken?, Throwable?) -> Unit = { token, error -> + loadingDialog.dismiss() + if (error != null) { + showToast("카카오 계정으로 로그인 하지 못했습니다. 다시 시도해 주세요") + } else if (token != null) { + handleKakaoLogin(token) + } + } + + private fun loginKakao() { + loadingDialog.show(screenWidth) + if (UserApiClient.instance.isKakaoTalkLoginAvailable(this@LoginActivity)) { + UserApiClient.instance.loginWithKakaoTalk(this@LoginActivity) { token, error -> + if (error != null) { + Logger.e("error: ${error.message}, ${error.cause}") + if (error is ClientError && error.reason == ClientErrorCause.Cancelled) { + loadingDialog.dismiss() + return@loginWithKakaoTalk + } else { + UserApiClient.instance.loginWithKakaoAccount( + this@LoginActivity, + callback = kakaoLoginCallback + ) + } + } else if (token != null) { + handleKakaoLogin(token) + } + } + } else { + UserApiClient.instance.loginWithKakaoAccount( + this@LoginActivity, + callback = kakaoLoginCallback + ) + } + } + + private fun handleKakaoLogin(token: OAuthToken) { + viewModel.kakaoLogin(accessToken = token.accessToken) { + finishAffinity() + val nextIntent = Intent(applicationContext, MainActivity::class.java) + val extras = intent.getBundleExtra(Constants.EXTRA_DATA) + ?: if (intent.extras != null) { + intent.extras + } else { + null + } + if (extras != null) { + nextIntent.putExtra(Constants.EXTRA_DATA, extras) + } + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) + startActivity(nextIntent) + } + } } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/user/login/LoginViewModel.kt b/app/src/main/java/kr/co/vividnext/sodalive/user/login/LoginViewModel.kt index 26cc1cb..834bb61 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/user/login/LoginViewModel.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/user/login/LoginViewModel.kt @@ -22,6 +22,45 @@ class LoginViewModel(private val repository: UserRepository) : BaseViewModel() { val isLoading: LiveData get() = _isLoading + fun kakaoLogin(accessToken: String, onSuccess: () -> Unit) { + _isLoading.value = true + + compositeDisposable.add( + repository.kakaoLogin( + request = SocialLoginRequest(marketingPid = SharedPreferenceManager.marketingPid), + token = "Bearer $accessToken" + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { + _isLoading.value = false + if (it.success && it.data != null) { + SharedPreferenceManager.token = it.data.token + SharedPreferenceManager.email = it.data.email + SharedPreferenceManager.userId = it.data.userId + SharedPreferenceManager.nickname = it.data.nickname + SharedPreferenceManager.profileImage = it.data.profileImage + onSuccess() + } else { + if (it.message != null) { + _toastLiveData.postValue(it.message) + } else { + _toastLiveData.postValue( + "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요." + ) + } + } + }, + { + _isLoading.value = false + it.message?.let { message -> Logger.e(message) } + _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.") + } + ) + ) + } + fun googleLogin(idToken: String, onSuccess: () -> Unit) { _isLoading.value = true diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 7bf6871..7b2ec9a 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -103,6 +103,14 @@ android:layout_marginTop="20dp" android:gravity="center"> + +